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(const char* str, size_t n) 00065 { 00066 p = static_cast<char*>(malloc(n + 1)); 00067 00068 allocated_ = n + 1; 00069 size_ = n; 00070 memcpy(p, str, n); 00071 p[n] = 0; 00072 } 00073 00074 String& String::operator=(const char* s) 00075 { 00076 if ( p != s ) { 00077 // s could point into our own string, so we have to allocate a new string 00078 const size_t len = strlen(s); 00079 char* copy = (char*) malloc( len + 1); 00080 memmove(copy, s, len+1); // trailing 0 00081 free( p ); 00082 p = copy; 00083 size_ = len; 00084 allocated_ = len+1; 00085 } 00086 return *this; 00087 } 00088 00089 String& String::operator=(const String& s) 00090 { 00091 return operator=(s.p); 00092 } 00093 00094 String& String::operator+=(const String& s) 00095 { 00096 if (s.size_ > 0) { 00097 this->reserve(size_ + s.size_); 00098 memmove(p+size_, s.p, s.size_+1); // trailing 0 00099 size_ += s.size_; 00100 } 00101 return *this; 00102 } 00103 00104 // since p and s may overlap, we have to copy our own string first 00105 String& String::operator+=(const char* s) 00106 { 00107 const size_type lens = strlen(s); 00108 if (lens > 0) { 00109 if (size_ + lens + 1 <= allocated_) { 00110 memmove(p+size_, s, lens+1); // trailing 0 00111 size_ += lens; 00112 } else { 00113 String s2( *this ); // copy own data 00114 s2.reserve(size_ + lens); 00115 memmove(s2.p+size_, s, lens+1); // trailing 0 00116 s2.size_ = size_ + lens; 00117 this->swap( s2 ); 00118 } 00119 } 00120 return *this; 00121 } 00122 00123 String& String::operator+=(const char c) 00124 { 00125 push_back(c); 00126 return *this; 00127 } 00128 00129 void String::push_back(const char c) { 00130 00131 if (size_ == allocated_ - 1) { 00132 size_t more = (allocated_* 3) / 2; // factor 1.5 00133 if ( more < 4 ) more = 4; 00134 reserve( size_ + more ); 00135 } 00136 00137 p[size_] = c; 00138 size_++; 00139 p[size_] = 0; 00140 } 00141 00142 bool String::operator==(const char* s) const 00143 { 00144 if( s == NULL ) { 00145 if( p == NULL ) { 00146 return true; 00147 } 00148 return false; 00149 } 00150 bool ret = strcmp(p, s); 00151 return !ret; 00152 } 00153 00154 bool String::operator==(const String& s) const 00155 { 00156 bool ret = strcmp(p, s.p); 00157 return !ret; 00158 } 00159 00160 void String::clear() 00161 { 00162 size_ = 0; 00163 p[0] = 0; 00164 } 00165 00166 String String::substr(const size_type pos, size_type length) const 00167 { 00168 String s; 00169 const size_type len = size_; 00170 00171 if ( pos <= len ) { 00172 00173 size_type remain = len - pos; 00174 00175 if ( length > remain ) 00176 length = remain; 00177 00178 s.reserve( length ); 00179 00180 memcpy(s.p, p + pos, length); 00181 s.p[length] = '\0'; 00182 s.size_ = length; 00183 } 00184 return s; 00185 } 00186 00187 00188 // checked access, accessing the NUL at end is allowed 00189 char String::at(const size_type i) const 00190 { 00191 if ( i <= strlen(p) ) { 00192 return p[i]; 00193 } else { 00194 return '\0'; 00195 } 00196 } 00197 00198 String& String::erase(size_type pos, size_type len) 00199 { 00200 if (len > 0) { 00201 00202 if ( pos < size_ ) { // user must not remove trailing 0 00203 00204 size_type s2 = size_; 00205 size_type remain = s2 - pos - len; 00206 00207 if (remain > 0) { 00208 // erase by overwriting 00209 memmove(p + pos, p + pos + len, remain); 00210 } 00211 00212 //if ( remain < 0 ) remain = 0; 00213 00214 // remove unused space 00215 this->resize( pos+remain ); 00216 00217 } 00218 } 00219 return *this; 00220 } 00221 00222 String& String::append( const char* str, size_type n) { 00223 if (str && n > 0) { 00224 size_t lens = strlen(str); 00225 if (n > lens) 00226 n = lens; 00227 size_t newlen = size_ + n; 00228 this->reserve( newlen ); 00229 memmove(p+size_, str, n); // p and s.p MAY overlap 00230 p[newlen] = 0; // add NUL termination 00231 size_ = newlen; 00232 } 00233 return *this; 00234 } 00235 00236 String& String::append_raw( const char* str, size_type n) { 00237 if (str && n > 0) { 00238 size_t newlen = size_ + n; 00239 this->reserve( newlen ); 00240 memmove(p+size_, str, n); // p and s.p MAY overlap 00241 p[newlen] = 0; // add NUL termination 00242 size_ = newlen; 00243 } 00244 return *this; 00245 } 00246 00247 void String::append_int(int param) { 00248 00249 // max len of "-9223372036854775808" plus zero termination 00250 char conv_buff[20+1]; 00251 00252 int len = itoa_c(param, conv_buff); 00253 append_raw(conv_buff, len); 00254 } 00255 00256 int String::compare( size_type pos, size_type len, const String& str ) const { 00257 int r = -1; 00258 if (pos <= size_) { 00259 if ( len > size_ - pos) 00260 len = size_ - pos; // limit len to available length 00261 00262 const size_type osize = str.size(); 00263 const size_type len2 = std::min(len, osize); 00264 r = strncmp( p + pos, str.p, len2); 00265 if (r==0) // equal so far, now compare sizes 00266 r = len < osize ? -1 : ( len == osize ? 0 : +1 ); 00267 } 00268 return r; 00269 } 00270 00271 int String::compare( size_type pos, size_type len, const char* str ) const { 00272 int r = -1; 00273 if (pos <= size_) { 00274 00275 if ( len > size_ - pos) 00276 len = size_ - pos; // limit len to available length 00277 00278 const size_type osize = strlen(str); 00279 const size_type len2 = std::min(len, osize); 00280 r = strncmp( p + pos, str, len2); 00281 if (r==0) // equal so far, now compare sizes 00282 r = len < osize ? -1 : ( len == osize ? 0 : +1 ); 00283 } 00284 return r; 00285 } 00286 00287 int String::find_last_of(char c) const { 00288 int r = -1; 00289 char *v; 00290 v = strrchr(p,c); 00291 if (v != NULL) { 00292 r = 0; 00293 char* i = p; 00294 while (v != i) { 00295 i++; 00296 r++; 00297 } 00298 } 00299 return r; 00300 } 00301 00302 void String::new_realloc( size_type n) { 00303 if (n > 0 ) { 00304 char* pnew = static_cast<char*>(realloc(p, n)); // could return NULL 00305 if (pnew) 00306 p = pnew; 00307 } 00308 } 00309 00310 void String::reserve( const size_type n) { 00311 if (n >= allocated_ ) { 00312 this->new_realloc(n + 1); 00313 allocated_ = n + 1; 00314 } 00315 } 00316 00317 void String::resize( const size_type n) { 00318 this->resize( n, 0 ); 00319 } 00320 00321 void String::resize( const size_type n, const char c) { 00322 if (n < size_ ) { 00323 p[n] = 0; 00324 size_ = n; 00325 } 00326 else if (n > size_ ) { 00327 this->reserve( n ); 00328 for (size_type i=size_; i < n; ++i ) 00329 p[i] = c; 00330 p[n] = 0; 00331 size_ = n; 00332 } 00333 } 00334 00335 void String::swap( String& s ) { 00336 std::swap( allocated_, s.allocated_ ); 00337 std::swap( size_, s.size_ ); 00338 std::swap( p, s.p ); 00339 } 00340 00341 00342 // Comparison 00343 bool operator<( const String& s1, const String& s2 ) { 00344 return strcmp( s1.c_str(), s2.c_str() ) < 0; 00345 } 00346 00347 void reverse(char s[], uint32_t length) 00348 { 00349 uint32_t i, j; 00350 char c; 00351 00352 for (i = 0, j = length-1; i<j; i++, j--) { 00353 c = s[i]; 00354 s[i] = s[j]; 00355 s[j] = c; 00356 } 00357 } 00358 00359 uint32_t itoa_c (int64_t n, char s[]) 00360 { 00361 int64_t sign; 00362 uint32_t i; 00363 00364 if ((sign = n) < 0) 00365 n = -n; 00366 00367 i = 0; 00368 00369 do { 00370 s[i++] = n % 10 + '0'; 00371 } 00372 while ((n /= 10) > 0); 00373 00374 if (sign < 0) 00375 s[i++] = '-'; 00376 00377 s[i] = '\0'; 00378 00379 m2m::reverse(s, i); 00380 return i; 00381 } 00382 00383 uint8_t* String::convert_integer_to_array(int64_t value, uint8_t &size, uint8_t *array, uint32_t array_size) 00384 { 00385 uint8_t* buffer = NULL; 00386 size = 0; 00387 if (array) { 00388 value = String::convert_array_to_integer(array, array_size); 00389 } 00390 00391 if(value < 0xFF) { 00392 size = 1; 00393 } else if(value < 0xFFFF) { 00394 size = 2; 00395 } else if(value < 0xFFFFFF) { 00396 size = 3; 00397 } else if(value < 0xFFFFFFFF) { 00398 size = 4; 00399 } else if(value < 0xFFFFFFFFFF) { 00400 size = 5; 00401 } else if(value < 0xFFFFFFFFFFFF) { 00402 size = 6; 00403 } else if(value < 0xFFFFFFFFFFFFFF) { 00404 size = 7; 00405 } else { 00406 size = 8; 00407 } 00408 00409 buffer = (uint8_t*)malloc(size); 00410 if (buffer) { 00411 for (int i = 0; i < size; i++) { 00412 buffer[i] = (value >> ((size - i - 1) * 8)); 00413 } 00414 } else { 00415 size = 0; 00416 } 00417 return buffer; 00418 } 00419 00420 int64_t String::convert_array_to_integer(uint8_t *value, uint32_t size) 00421 { 00422 int64_t temp_64 = 0; 00423 for (int i = size - 1; i >= 0; i--) { 00424 temp_64 += (uint64_t)(*value++) << i * 8; 00425 } 00426 return temp_64; 00427 } 00428 00429 } // namespace
Generated on Tue Jul 12 2022 21:20:28 by
1.7.2