Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
m2mstring.cpp
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #include "mbed-client/m2mstring.h" 00017 #include <string.h> // strlen 00018 #include <stdlib.h> // malloc, realloc 00019 #include <assert.h> 00020 #include <algorithm> // min 00021 00022 namespace m2m { 00023 00024 const String::size_type String::npos = static_cast<size_t>(-1); 00025 00026 char* String::strdup(const char* s) 00027 { 00028 const size_t len = strlen(s)+1; 00029 char *p2 = static_cast<char*>(malloc(len)); 00030 memcpy(p2, s, len); 00031 allocated_ = len; 00032 size_ = len-1; 00033 return p2; 00034 } 00035 00036 String::String() 00037 : p( strdup("") ) 00038 { 00039 } 00040 00041 String::~String() 00042 { 00043 free(p); 00044 p = 0; 00045 } 00046 00047 String::String(const String& s) 00048 : p(0) 00049 { 00050 if( &s != NULL ) { 00051 p = static_cast<char*>(malloc(s.size_ + 1)); 00052 00053 allocated_ = s.size_ + 1; 00054 size_ = s.size_; 00055 memcpy(p, s.p, size_ + 1); 00056 } 00057 } 00058 00059 String::String(const char* s) 00060 : p(strdup(s)) 00061 { 00062 } 00063 00064 String& String::operator=(const char* s) 00065 { 00066 if ( p != s ) { 00067 // s could point into our own string, so we have to allocate a new string 00068 const size_t len = strlen(s); 00069 char* copy = (char*) malloc( len + 1); 00070 memmove(copy, s, len+1); // trailing 0 00071 free( p ); 00072 p = copy; 00073 size_ = len; 00074 allocated_ = len+1; 00075 } 00076 return *this; 00077 } 00078 00079 String& String::operator=(const String& s) 00080 { 00081 return operator=(s.p); 00082 } 00083 00084 String& String::operator+=(const String& s) 00085 { 00086 if (s.size_ > 0) { 00087 this->reserve(size_ + s.size_); 00088 memmove(p+size_, s.p, s.size_+1); // trailing 0 00089 size_ += s.size_; 00090 } 00091 return *this; 00092 } 00093 00094 // since p and s may overlap, we have to copy our own string first 00095 String& String::operator+=(const char* s) 00096 { 00097 const size_type lens = strlen(s); 00098 if (lens > 0) { 00099 if (size_ + lens + 1 <= allocated_) { 00100 memmove(p+size_, s, lens+1); // trailing 0 00101 size_ += lens; 00102 } else { 00103 String s2( *this ); // copy own data 00104 s2.reserve(size_ + lens); 00105 memmove(s2.p+size_, s, lens+1); // trailing 0 00106 s2.size_ = size_ + lens; 00107 this->swap( s2 ); 00108 } 00109 } 00110 return *this; 00111 } 00112 00113 String& String::operator+=(const char c) 00114 { 00115 push_back(c); 00116 return *this; 00117 } 00118 00119 void String::push_back(const char c) { 00120 00121 if (size_ == allocated_ - 1) { 00122 size_t more = (allocated_* 3) / 2; // factor 1.5 00123 if ( more < 4 ) more = 4; 00124 reserve( size_ + more ); 00125 } 00126 00127 p[size_] = c; 00128 size_++; 00129 p[size_] = 0; 00130 } 00131 00132 bool String::operator==(const char* s) const 00133 { 00134 if( s == NULL ) { 00135 if( p == NULL ) { 00136 return true; 00137 } 00138 return false; 00139 } 00140 bool ret = strcmp(p, s); 00141 return !ret; 00142 } 00143 00144 bool String::operator==(const String& s) const 00145 { 00146 bool ret = strcmp(p, s.p); 00147 return !ret; 00148 } 00149 00150 void String::clear() 00151 { 00152 size_ = 0; 00153 p[0] = 0; 00154 } 00155 00156 String String::substr(const size_type pos, size_type length) const 00157 { 00158 String s; 00159 const size_type len = size_; 00160 00161 if ( pos <= len ) { 00162 00163 size_type remain = len - pos; 00164 00165 if ( length > remain ) 00166 length = remain; 00167 00168 s.reserve( length ); 00169 00170 memcpy(s.p, p + pos, length); 00171 s.p[length] = '\0'; 00172 s.size_ = length; 00173 } 00174 return s; 00175 } 00176 00177 00178 // checked access, accessing the NUL at end is allowed 00179 char String::at(const size_type i) const 00180 { 00181 if ( i <= strlen(p) ) { 00182 return p[i]; 00183 } else { 00184 return '\0'; 00185 } 00186 } 00187 00188 String& String::erase(size_type pos, size_type len) 00189 { 00190 if (len > 0) { 00191 00192 if ( pos < size_ ) { // user must not remove trailing 0 00193 00194 size_type s2 = size_; 00195 size_type remain = s2 - pos - len; 00196 00197 if (remain > 0) { 00198 // erase by overwriting 00199 memmove(p + pos, p + pos + len, remain); 00200 } 00201 00202 //if ( remain < 0 ) remain = 0; 00203 00204 // remove unused space 00205 this->resize( pos+remain ); 00206 00207 } 00208 } 00209 return *this; 00210 } 00211 00212 String& String::append( const char* str, size_type n) { 00213 if (str && n > 0) { 00214 size_t lens = strlen(str); 00215 if (n > lens) 00216 n = lens; 00217 size_t newlen = size_ + n; 00218 this->reserve( newlen ); 00219 memmove(p+size_, str, n); // p and s.p MAY overlap 00220 p[newlen] = 0; // add NUL termination 00221 size_ = newlen; 00222 } 00223 return *this; 00224 } 00225 00226 String& String::append_raw( const char* str, size_type n) { 00227 if (str && n > 0) { 00228 size_t newlen = size_ + n; 00229 this->reserve( newlen ); 00230 memmove(p+size_, str, n); // p and s.p MAY overlap 00231 p[newlen] = 0; // add NUL termination 00232 size_ = newlen; 00233 } 00234 return *this; 00235 } 00236 00237 void String::append_int(int param) { 00238 00239 // max len of "-9223372036854775808" plus zero termination 00240 char conv_buff[20+1]; 00241 00242 int len = itoa_c(param, conv_buff); 00243 append_raw(conv_buff, len); 00244 } 00245 00246 int String::compare( size_type pos, size_type len, const String& str ) const { 00247 int r = -1; 00248 if (pos <= size_) { 00249 if ( len > size_ - pos) 00250 len = size_ - pos; // limit len to available length 00251 00252 const size_type osize = str.size(); 00253 const size_type len2 = std::min(len, osize); 00254 r = strncmp( p + pos, str.p, len2); 00255 if (r==0) // equal so far, now compare sizes 00256 r = len < osize ? -1 : ( len == osize ? 0 : +1 ); 00257 } 00258 return r; 00259 } 00260 00261 int String::compare( size_type pos, size_type len, const char* str ) const { 00262 int r = -1; 00263 if (pos <= size_) { 00264 00265 if ( len > size_ - pos) 00266 len = size_ - pos; // limit len to available length 00267 00268 const size_type osize = strlen(str); 00269 const size_type len2 = std::min(len, osize); 00270 r = strncmp( p + pos, str, len2); 00271 if (r==0) // equal so far, now compare sizes 00272 r = len < osize ? -1 : ( len == osize ? 0 : +1 ); 00273 } 00274 return r; 00275 } 00276 00277 int String::find_last_of(char c) const { 00278 int r = -1; 00279 char *v; 00280 v = strrchr(p,c); 00281 if (v != NULL) { 00282 r = 0; 00283 char* i = p; 00284 while (v != i) { 00285 i++; 00286 r++; 00287 } 00288 } 00289 return r; 00290 } 00291 00292 void String::new_realloc( size_type n) { 00293 if (n > 0 ) { 00294 char* pnew = static_cast<char*>(realloc(p, n)); // could return NULL 00295 if (pnew) 00296 p = pnew; 00297 } 00298 } 00299 00300 void String::reserve( const size_type n) { 00301 if (n >= allocated_ ) { 00302 this->new_realloc(n + 1); 00303 allocated_ = n + 1; 00304 } 00305 } 00306 00307 void String::resize( const size_type n) { 00308 this->resize( n, 0 ); 00309 } 00310 00311 void String::resize( const size_type n, const char c) { 00312 if (n < size_ ) { 00313 p[n] = 0; 00314 size_ = n; 00315 } 00316 else if (n > size_ ) { 00317 this->reserve( n ); 00318 for (size_type i=size_; i < n; ++i ) 00319 p[i] = c; 00320 p[n] = 0; 00321 size_ = n; 00322 } 00323 } 00324 00325 void String::swap( String& s ) { 00326 std::swap( allocated_, s.allocated_ ); 00327 std::swap( size_, s.size_ ); 00328 std::swap( p, s.p ); 00329 } 00330 00331 00332 // Comparison 00333 bool operator<( const String& s1, const String& s2 ) { 00334 return strcmp( s1.c_str(), s2.c_str() ) < 0; 00335 } 00336 00337 void reverse(char s[], uint32_t length) 00338 { 00339 uint32_t i, j; 00340 char c; 00341 00342 for (i = 0, j = length-1; i<j; i++, j--) { 00343 c = s[i]; 00344 s[i] = s[j]; 00345 s[j] = c; 00346 } 00347 } 00348 00349 uint32_t itoa_c (int64_t n, char s[]) 00350 { 00351 int64_t sign; 00352 uint32_t i; 00353 00354 if ((sign = n) < 0) 00355 n = -n; 00356 00357 i = 0; 00358 00359 do { 00360 s[i++] = n % 10 + '0'; 00361 } 00362 while ((n /= 10) > 0); 00363 00364 if (sign < 0) 00365 s[i++] = '-'; 00366 00367 s[i] = '\0'; 00368 00369 m2m::reverse(s, i); 00370 return i; 00371 } 00372 00373 uint8_t* String::convert_integer_to_array(int64_t value, uint8_t &size, uint8_t *array, uint32_t array_size) 00374 { 00375 uint8_t* buffer = NULL; 00376 size = 0; 00377 if (array) { 00378 value = String::convert_array_to_integer(array, array_size); 00379 } 00380 00381 if(value < 0xFF) { 00382 size = 1; 00383 } else if(value < 0xFFFF) { 00384 size = 2; 00385 } else if(value < 0xFFFFFF) { 00386 size = 3; 00387 } else if(value < 0xFFFFFFFF) { 00388 size = 4; 00389 } else if(value < 0xFFFFFFFFFF) { 00390 size = 5; 00391 } else if(value < 0xFFFFFFFFFFFF) { 00392 size = 6; 00393 } else if(value < 0xFFFFFFFFFFFFFF) { 00394 size = 7; 00395 } else { 00396 size = 8; 00397 } 00398 00399 buffer = (uint8_t*)malloc(size); 00400 if (buffer) { 00401 for (int i = 0; i < size; i++) { 00402 buffer[i] = (value >> ((size - i - 1) * 8)); 00403 } 00404 } else { 00405 size = 0; 00406 } 00407 return buffer; 00408 } 00409 00410 int64_t String::convert_array_to_integer(uint8_t *value, uint32_t size) 00411 { 00412 int64_t temp_64 = 0; 00413 for (int i = size - 1; i >= 0; i--) { 00414 temp_64 += (uint64_t)(*value++) << i * 8; 00415 } 00416 return temp_64; 00417 } 00418 00419 } // namespace
Generated on Tue Jul 12 2022 13:05:13 by
1.7.2