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.
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo 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 } 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 12:28:39 by
