Toyomasa Watarai
/
Mbed-example-WS-W27
Mbed Cloud example program for workshop in W27 2018.
Embed:
(wiki syntax)
Show/hide line numbers
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 if (p2) { 00031 memcpy(p2, s, len); 00032 allocated_ = len; 00033 size_ = len-1; 00034 } 00035 return p2; 00036 } 00037 00038 String::String() 00039 : p( strdup("") ) 00040 { 00041 } 00042 00043 String::~String() 00044 { 00045 free(p); 00046 p = 0; 00047 } 00048 00049 String::String(const String& s) 00050 : p(0) 00051 { 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 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, const uint8_t *array, const 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(const uint8_t *value, const 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 16:22:07 by 1.7.2