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: mbed Socket lwip-eth lwip-sys lwip
Fork of 6_songs-from-the-cloud 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 /* 00027 * Like the 'new' operator, we want to guarantee that we NEVER 00028 * return NULL. Loop until there is free memory. 00029 * 00030 */ 00031 static char* malloc_never_null(const size_t b) 00032 { 00033 char *p; 00034 00035 do { 00036 p = static_cast<char*>(malloc(b)); 00037 } while ( p == NULL ); 00038 00039 return p; 00040 } 00041 00042 /** 00043 * Allocates memory for the copy the string at the same time sets "this->allocated". 00044 * @param s 00045 * @return 00046 */ 00047 char* 00048 String::strdup_never_null(const char* s) 00049 { 00050 const size_t len = strlen(s)+1; 00051 char *p2 = malloc_never_null(len); 00052 memcpy(p2, s, len); 00053 allocated_=len; 00054 size_=len-1; 00055 return p2; 00056 } 00057 00058 String::String() 00059 : p( strdup_never_null("") ) 00060 { 00061 _return_value = '\0'; 00062 } 00063 00064 String::~String() 00065 { 00066 free(p); 00067 p = 0; 00068 } 00069 00070 String::String(const String& s) 00071 : p(0) 00072 { 00073 if( &s != NULL ){ 00074 p = malloc_never_null( s.size_ + 1 ); // copy only used part 00075 allocated_ = s.size_ + 1; 00076 size_ = s.size_; 00077 memcpy(p, s.p, size_ + 1); 00078 } 00079 _return_value = '\0'; 00080 } 00081 00082 String::String(const char* s) 00083 : p(strdup_never_null(s)) 00084 { 00085 _return_value = '\0'; 00086 } 00087 00088 String& String::operator=(const char* s) 00089 { 00090 if ( p != s ) { 00091 // s could point into our own string, so we have to allocate a new string 00092 const size_t len = strlen(s); 00093 char* copy = (char*) malloc( len + 1); 00094 memmove(copy, s, len+1); // trailing 0 00095 free( p ); 00096 p = copy; 00097 size_ = len; 00098 allocated_ = len+1; 00099 } 00100 00101 return *this; 00102 } 00103 00104 String& String::operator=(const String& s) 00105 { 00106 return operator=(s.p); 00107 } 00108 00109 String& String::operator+=(const String& s) 00110 { 00111 if (s.size_ > 0){ 00112 this->reserve(size_ + s.size_); 00113 memmove(p+size_, s.p, s.size_+1); // trailing 0 00114 size_ += s.size_; 00115 } 00116 return *this; 00117 } 00118 00119 // since p and s may overlap, we have to copy our own string first 00120 String& String::operator+=(const char* s) 00121 { 00122 const size_type lens = strlen(s); 00123 if (lens > 0){ 00124 if (size_ + lens + 1 <= allocated_) { 00125 memmove(p+size_, s, lens+1); // trailing 0 00126 size_ += lens; 00127 } else { 00128 String s2( *this ); // copy own data 00129 s2.reserve(size_ + lens); 00130 memmove(s2.p+size_, s, lens+1); // trailing 0 00131 s2.size_ = size_ + lens; 00132 this->swap( s2 ); 00133 } 00134 } 00135 return *this; 00136 } 00137 00138 String& String::operator+=(const char c) 00139 { 00140 push_back(c); 00141 return *this; 00142 } 00143 00144 00145 void String::push_back(const char c) { 00146 00147 if (size_ == allocated_ - 1) { 00148 size_t more = (allocated_* 3) / 2; // factor 1.5 00149 if ( more < 4 ) more = 4; 00150 reserve( size_ + more ); 00151 } 00152 00153 p[size_] = c; 00154 size_++; 00155 p[size_] = 0; 00156 } 00157 00158 bool String::operator==(const char* s) const 00159 { 00160 if( s == NULL ){ 00161 if( p == NULL ){ 00162 return true; 00163 } 00164 return false; 00165 } 00166 bool ret = strcmp(p, s); 00167 return !ret; 00168 } 00169 00170 bool String::operator==(const String& s) const 00171 { 00172 bool ret = strcmp(p, s.p); 00173 return !ret; 00174 } 00175 00176 void String::clear() 00177 { 00178 size_ = 0; 00179 p[0] = 0; 00180 } 00181 00182 // String operator+(const String& lhs, const String& rhs) 00183 // { 00184 // return String(lhs) += rhs; 00185 // } 00186 00187 String String::substr(const size_type pos, size_type length) const 00188 { 00189 String s; 00190 const size_type len = size_; 00191 00192 if ( pos <= len ) { 00193 00194 size_type remain = len - pos; 00195 00196 if ( length > remain ) 00197 length = remain; 00198 00199 s.reserve( length ); 00200 00201 memcpy(s.p, p + pos, length); 00202 s.p[length] = '\0'; 00203 s.size_ = length; 00204 } 00205 return s; 00206 } 00207 00208 00209 // checked access, accessing the NUL at end is allowed 00210 char& String::at(const size_type i) 00211 { 00212 if ( i <= strlen(p) ) { 00213 _return_value = p[i]; 00214 } else { 00215 _return_value = '\0'; 00216 } 00217 return _return_value; 00218 } 00219 00220 char String::at(const size_type i) const 00221 { 00222 if ( i <= strlen(p) ) { 00223 return p[i]; 00224 } else { 00225 return '\0'; 00226 } 00227 } 00228 00229 String& String::erase(size_type pos, size_type len) 00230 { 00231 if (len > 0) { 00232 00233 if ( pos < size_ ) { // user must not remove trailing 0 00234 00235 size_type s2 = size_; 00236 size_type remain = s2 - pos - len; 00237 00238 if (remain > 0) { 00239 // erase by overwriting 00240 memmove(p + pos, p + pos + len, remain); 00241 } 00242 00243 //if ( remain < 0 ) remain = 0; 00244 00245 // remove unused space 00246 this->resize( pos+remain ); 00247 00248 } 00249 } 00250 return *this; 00251 } 00252 00253 String& String::append( const char* str, size_type n) { 00254 if (str && n > 0) { 00255 size_t lens = strlen(str); 00256 if (n > lens) 00257 n = lens; 00258 size_t newlen = size_ + n; 00259 this->reserve( newlen ); 00260 memmove(p+size_, str, n); // p and s.p MAY overlap 00261 p[newlen] = 0; // add NUL termination 00262 size_ = newlen; 00263 } 00264 return *this; 00265 } 00266 00267 int 00268 String::compare( size_type pos, size_type len, const String& str ) const { 00269 int r = -1; 00270 if (pos <= size_) { 00271 if ( len > size_ - pos) 00272 len = size_ - pos; // limit len to available length 00273 00274 const size_type osize = str.size(); 00275 const size_type len2 = std::min(len, osize); 00276 r = strncmp( p + pos, str.p, len2); 00277 if (r==0) // equal so far, now compare sizes 00278 r = len < osize ? -1 : ( len == osize ? 0 : +1 ); 00279 } 00280 return r; 00281 } 00282 00283 int 00284 String::compare( size_type pos, size_type len, const char* str ) const { 00285 int r = -1; 00286 if (pos <= size_) { 00287 00288 if ( len > size_ - pos) 00289 len = size_ - pos; // limit len to available length 00290 00291 const size_type osize = strlen(str); 00292 const size_type len2 = std::min(len, osize); 00293 r = strncmp( p + pos, str, len2); 00294 if (r==0) // equal so far, now compare sizes 00295 r = len < osize ? -1 : ( len == osize ? 0 : +1 ); 00296 } 00297 return r; 00298 } 00299 00300 int 00301 String::find_last_of(char c) const { 00302 int r = -1; 00303 char *v; 00304 v = strrchr(p,c); 00305 if (v != NULL){ 00306 r = 0; 00307 char* i = p; 00308 while (v != i){ 00309 i++; 00310 r++; 00311 } 00312 } 00313 return r; 00314 } 00315 00316 void 00317 String::new_realloc( size_type n) { 00318 if (n > 0 ) { 00319 char* pnew = static_cast<char*>(realloc(p, n)); // could return NULL 00320 if (pnew) 00321 p = pnew; 00322 } 00323 } 00324 00325 00326 void 00327 String::reserve( const size_type n) { 00328 if (n >= allocated_ ) { 00329 this->new_realloc(n + 1); 00330 allocated_ = n + 1; 00331 } 00332 } 00333 00334 void 00335 String::resize( const size_type n) { 00336 this->resize( n, 0 ); 00337 } 00338 00339 void 00340 String::resize( const size_type n, const char c) { 00341 if (n < size_ ) { 00342 p[n] = 0; 00343 size_ = n; 00344 } 00345 else if (n > size_ ) { 00346 this->reserve( n ); 00347 for (size_type i=size_; i < n; ++i ) 00348 p[i] = c; 00349 p[n] = 0; 00350 size_ = n; 00351 } 00352 } 00353 00354 void String::swap( String& s ) { 00355 std::swap( allocated_, s.allocated_ ); 00356 std::swap( size_, s.size_ ); 00357 std::swap( p, s.p ); 00358 } 00359 00360 00361 // Comparison 00362 bool operator<( const String& s1, const String& s2 ) { 00363 return strcmp( s1.c_str(), s2.c_str() ) < 0; 00364 } 00365 00366 } // namespace
Generated on Tue Jul 12 2022 12:47:48 by
