joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers m2mstring.cpp Source File

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