Sierra Toolkit  Version of the Day
String.cpp
1 
10 #include <iostream>
11 #include <iomanip>
12 #include <sstream>
13 #include <stdexcept>
14 
15 #include <stk_util/diag/String.hpp>
16 
17 #include <cstddef>
18 #include <cctype>
19 #include <stdexcept>
20 #include <iostream>
21 
22 //----------------------------------------------------------------------
23 
24 namespace sierra {
25 
26 namespace {
27 
28 static const char arraylower_t[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
29  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
30  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
31  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
32  0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
33  'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
34  0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
35  'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
36 };
37 
38 inline int arraylower(int c) {
39  return arraylower_t[c];
40 }
41 
42 } // namespace <unnamed>
43 
44 int to_label( int c )
45 {
46  return isspace(c) ? '_' : c;
47 }
48 
49 size_t char_simple_traits::length( const char * c1 )
50 {
51  const char * c = c1 ;
52  if ( c ) while ( *c ) ++c ;
53  return c - c1 ;
54 }
55 
56 int char_simple_traits::compare( const char * c1 , const char * c2 )
57 {
58  for ( ; *c1 && arraylower(*c1) == arraylower(*c2); c1++, c2++)
59  ;
60 
61  return arraylower(*c1) - arraylower(*c2);
62 }
63 
64 size_t char_label_traits::length( const char * c1 )
65 {
66  const char * c = c1 ;
67  if ( c ) while ( *c ) ++c ;
68  return c - c1 ;
69 }
70 
71 void char_label_traits::convert( char * c , size_t n )
72 {
73  for ( char * const e = c + n ; c != e ; ++c )
74  *c = to_label(*c);
75 }
76 
77 int char_label_traits::compare( const char * c1 , const char * c2 )
78 {
79  for ( ; *c1 && arraylower(to_label(*c1)) == arraylower(to_label(*c2)); c1++, c2++)
80  ;
81 
82  return arraylower(to_label(*c1)) - arraylower(to_label(*c2));
83 }
84 
85 } // namespace sierra
86 
87 //----------------------------------------------------------------------
88 
89 namespace sierra {
90 
91 namespace implementation {
92 
116 // Manage memory but do not invalidate current memory
117 // until operation is complete.
118 
119 char * StringData::mem( const char * cs , size_t n )
120 {
121  enum { inc = 4 * sizeof(long) };
122  static std::string::allocator_type a ;
123 
124  const bool is_allocated = small[ max_len ] == 1;
125  const bool to_allocated = max_len < n ;
126 
127  size_t new_alloc = 0 ;
128 
129  if ( to_allocated && ( ! is_allocated || large.siz <= n ) ) {
130  const size_t n_total = n + 1 ;
131  new_alloc = n_total % inc ? n_total + inc - n_total % inc : n_total ;
132  if ( new_alloc == 0 || new_alloc - 1 < n ) {
133  throw std::runtime_error("FAILED MEMORY ALLOCATION SIZING in sierra::String");
134  }
135  }
136 
137  char * dst = NULL ;
138  char * del_ptr = NULL ;
139  size_t del_size = 0 ;
140 
141  if ( is_allocated && ( new_alloc || ! to_allocated ) ) {
142  // Deallocate currently allocated memory after copying input,
143  // input might be a subset of currently allocated memory.
144  del_ptr = large.ptr ;
145  del_size = large.siz ;
146  }
147 
148  if ( to_allocated ) {
149  // Needs to be allocated to hold input
150 
151  if ( new_alloc ) {
152  // New allocation or reallocation to increase size
153 
154  { //----------------------------------------
155  // Verify memory layout
156  static bool first_pass = true ;
157 
158  if ( first_pass ) {
159  first_pass = false ;
160 
161  if ( buf_len % sizeof(long) ||
162  sizeof(StringData) != buf_len ||
163  small + max_len < (char*)(&(large)) + sizeof(Large) ) {
164  throw std::logic_error("StringData memory layout error");
165  }
166  }
167  } //----------------------------------------
168 
169  try {
170  large.siz = new_alloc ;
171  large.ptr = (char *) a.allocate( new_alloc );
172 // std::cout << "String allocated at " << (void *)large.ptr << " for " << new_alloc << std::endl;
173  }
174  catch (...) {
175  throw std::runtime_error("FAILED MEMORY ALLOCATION in sierra::String");
176  }
177  }
178 
179  small[max_len] = 1 ;
180  large.len = n ;
181  dst = large.ptr ;
182  }
183  else {
184  small[max_len] = 0 ;
185  small[off_len] = n ;
186  dst = small ;
187  }
188 
189  {
190  const char * const cs_e = cs + n ;
191  char * d = dst ;
192  while ( cs != cs_e ) *d++ = *cs++ ;
193  *d = 0 ;
194  }
195 
196  if ( del_ptr != NULL ) {
197  try {
198 // std::cout << "String deallocated at " << (void *)del_ptr << " for " << del_size << std::endl;
199  a.deallocate( del_ptr , del_size );
200  }
201  catch (...) {
202  throw std::runtime_error("FAILED MEMORY DEALLOCATION in sierra::String");
203  }
204  }
205 
206  return dst ;
207 }
208 
209 StringData::~StringData()
210 { mem(NULL, 0); }
211 
212 StringData::StringData()
213 { small[ max_len ] = small[ off_len ] = small[ 0 ] = 0 ; }
214 
215 size_t StringData::len() const
216 { return small[ max_len ] ? large.len : small[ off_len ] ; }
217 
218 char * StringData::c_str()
219 { return small[ max_len ] ? large.ptr : small ; }
220 
221 const char * StringData::c_str() const
222 { return small[ max_len ] ? large.ptr : small ; }
223 
224 } // namespace internal
225 
226 std::ostream &
227 operator<<( std::ostream & os, const sierra::String & s)
228 { return os << s.c_str(); }
229 
230 std::istream &
231 operator>>( std::istream & is, sierra::String & s )
232 { std::string tmp; is >> tmp; s.assign(tmp); return is; }
233 
234 std::ostream &
235 operator<<( std::ostream & os, const sierra::Identifier &s)
236 { return os << s.c_str(); }
237 
238 std::istream &
239 operator>>( std::istream & is, sierra::Identifier &s )
240 { std::string tmp; is >> tmp; s.assign(tmp); return is; }
241 
242 } // namespace sierra
static size_t length(const char *c1)
Definition: String.cpp:64
Definition: Env.cpp:53
static int compare(const char *c1, const char *c2)
Definition: String.cpp:77
std::ostream & operator<<(std::ostream &s, const Bucket &k)
Print the part names for which this bucket is a subset.
Definition: Bucket.cpp:239
static int compare(const char *c1, const char *c2)
Definition: String.cpp:56
char * mem(const char *, size_t n)
Definition: String.cpp:119
static size_t length(const char *c1)
Definition: String.cpp:49
static void convert(char *c, size_t n)
Definition: String.cpp:71