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