Committer:
leothedragon
Date:
Sun Apr 18 15:20:23 2021 +0000
Revision:
0:25fa8795676b
DS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
leothedragon 0:25fa8795676b 1 /*
leothedragon 0:25fa8795676b 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
leothedragon 0:25fa8795676b 3 * SPDX-License-Identifier: Apache-2.0
leothedragon 0:25fa8795676b 4 * Licensed under the Apache License, Version 2.0 (the License); you may
leothedragon 0:25fa8795676b 5 * not use this file except in compliance with the License.
leothedragon 0:25fa8795676b 6 * You may obtain a copy of the License at
leothedragon 0:25fa8795676b 7 *
leothedragon 0:25fa8795676b 8 * http://www.apache.org/licenses/LICENSE-2.0
leothedragon 0:25fa8795676b 9 *
leothedragon 0:25fa8795676b 10 * Unless required by applicable law or agreed to in writing, software
leothedragon 0:25fa8795676b 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
leothedragon 0:25fa8795676b 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
leothedragon 0:25fa8795676b 13 * See the License for the specific language governing permissions and
leothedragon 0:25fa8795676b 14 * limitations under the License.
leothedragon 0:25fa8795676b 15 */
leothedragon 0:25fa8795676b 16 #include "mbed-client/m2mstring.h"
leothedragon 0:25fa8795676b 17 #include <string.h> // strlen
leothedragon 0:25fa8795676b 18 #include <stdlib.h> // malloc, realloc
leothedragon 0:25fa8795676b 19 #include <assert.h>
leothedragon 0:25fa8795676b 20
leothedragon 0:25fa8795676b 21 namespace m2m {
leothedragon 0:25fa8795676b 22
leothedragon 0:25fa8795676b 23
leothedragon 0:25fa8795676b 24 // can't use std::min as it is not universally available
leothedragon 0:25fa8795676b 25 #ifndef MIN
leothedragon 0:25fa8795676b 26 #define MIN(A,B) ((A) < (B) ? (A) : (B))
leothedragon 0:25fa8795676b 27 #endif
leothedragon 0:25fa8795676b 28
leothedragon 0:25fa8795676b 29 const String::size_type String::npos = static_cast<size_t>(-1);
leothedragon 0:25fa8795676b 30
leothedragon 0:25fa8795676b 31 char* String::strdup(const char* s)
leothedragon 0:25fa8795676b 32 {
leothedragon 0:25fa8795676b 33 const size_t len = strlen(s)+1;
leothedragon 0:25fa8795676b 34 char *p2 = static_cast<char*>(malloc(len));
leothedragon 0:25fa8795676b 35 if (p2) {
leothedragon 0:25fa8795676b 36 memcpy(p2, s, len);
leothedragon 0:25fa8795676b 37 allocated_ = len;
leothedragon 0:25fa8795676b 38 size_ = len-1;
leothedragon 0:25fa8795676b 39 }
leothedragon 0:25fa8795676b 40 return p2;
leothedragon 0:25fa8795676b 41 }
leothedragon 0:25fa8795676b 42
leothedragon 0:25fa8795676b 43 String::String()
leothedragon 0:25fa8795676b 44 : p( strdup("") )
leothedragon 0:25fa8795676b 45 {
leothedragon 0:25fa8795676b 46 }
leothedragon 0:25fa8795676b 47
leothedragon 0:25fa8795676b 48 String::~String()
leothedragon 0:25fa8795676b 49 {
leothedragon 0:25fa8795676b 50 free(p);
leothedragon 0:25fa8795676b 51 p = 0;
leothedragon 0:25fa8795676b 52 }
leothedragon 0:25fa8795676b 53
leothedragon 0:25fa8795676b 54 String::String(const String& s)
leothedragon 0:25fa8795676b 55 : p(0)
leothedragon 0:25fa8795676b 56 {
leothedragon 0:25fa8795676b 57 p = static_cast<char*>(malloc(s.size_ + 1));
leothedragon 0:25fa8795676b 58
leothedragon 0:25fa8795676b 59 allocated_ = s.size_ + 1;
leothedragon 0:25fa8795676b 60 size_ = s.size_;
leothedragon 0:25fa8795676b 61 memcpy(p, s.p, size_ + 1);
leothedragon 0:25fa8795676b 62 }
leothedragon 0:25fa8795676b 63
leothedragon 0:25fa8795676b 64 String::String(const char* s)
leothedragon 0:25fa8795676b 65 : p(strdup(s))
leothedragon 0:25fa8795676b 66 {
leothedragon 0:25fa8795676b 67 }
leothedragon 0:25fa8795676b 68
leothedragon 0:25fa8795676b 69 String::String(const char* str, size_t n)
leothedragon 0:25fa8795676b 70 {
leothedragon 0:25fa8795676b 71 p = static_cast<char*>(malloc(n + 1));
leothedragon 0:25fa8795676b 72
leothedragon 0:25fa8795676b 73 allocated_ = n + 1;
leothedragon 0:25fa8795676b 74 size_ = n;
leothedragon 0:25fa8795676b 75 memcpy(p, str, n);
leothedragon 0:25fa8795676b 76 p[n] = 0;
leothedragon 0:25fa8795676b 77 }
leothedragon 0:25fa8795676b 78
leothedragon 0:25fa8795676b 79 String& String::operator=(const char* s)
leothedragon 0:25fa8795676b 80 {
leothedragon 0:25fa8795676b 81 if ( p != s ) {
leothedragon 0:25fa8795676b 82 // s could point into our own string, so we have to allocate a new string
leothedragon 0:25fa8795676b 83 const size_t len = strlen(s);
leothedragon 0:25fa8795676b 84 char* copy = (char*) malloc( len + 1);
leothedragon 0:25fa8795676b 85 memmove(copy, s, len+1); // trailing 0
leothedragon 0:25fa8795676b 86 free( p );
leothedragon 0:25fa8795676b 87 p = copy;
leothedragon 0:25fa8795676b 88 size_ = len;
leothedragon 0:25fa8795676b 89 allocated_ = len+1;
leothedragon 0:25fa8795676b 90 }
leothedragon 0:25fa8795676b 91 return *this;
leothedragon 0:25fa8795676b 92 }
leothedragon 0:25fa8795676b 93
leothedragon 0:25fa8795676b 94 String& String::operator=(const String& s)
leothedragon 0:25fa8795676b 95 {
leothedragon 0:25fa8795676b 96 return operator=(s.p);
leothedragon 0:25fa8795676b 97 }
leothedragon 0:25fa8795676b 98
leothedragon 0:25fa8795676b 99 String& String::operator+=(const String& s)
leothedragon 0:25fa8795676b 100 {
leothedragon 0:25fa8795676b 101 if (s.size_ > 0) {
leothedragon 0:25fa8795676b 102 this->reserve(size_ + s.size_);
leothedragon 0:25fa8795676b 103 memmove(p+size_, s.p, s.size_+1); // trailing 0
leothedragon 0:25fa8795676b 104 size_ += s.size_;
leothedragon 0:25fa8795676b 105 }
leothedragon 0:25fa8795676b 106 return *this;
leothedragon 0:25fa8795676b 107 }
leothedragon 0:25fa8795676b 108
leothedragon 0:25fa8795676b 109 // since p and s may overlap, we have to copy our own string first
leothedragon 0:25fa8795676b 110 String& String::operator+=(const char* s)
leothedragon 0:25fa8795676b 111 {
leothedragon 0:25fa8795676b 112 const size_type lens = strlen(s);
leothedragon 0:25fa8795676b 113 if (lens > 0) {
leothedragon 0:25fa8795676b 114 if (size_ + lens + 1 <= allocated_) {
leothedragon 0:25fa8795676b 115 memmove(p+size_, s, lens+1); // trailing 0
leothedragon 0:25fa8795676b 116 size_ += lens;
leothedragon 0:25fa8795676b 117 } else {
leothedragon 0:25fa8795676b 118 String s2( *this ); // copy own data
leothedragon 0:25fa8795676b 119 s2.reserve(size_ + lens);
leothedragon 0:25fa8795676b 120 memmove(s2.p+size_, s, lens+1); // trailing 0
leothedragon 0:25fa8795676b 121 s2.size_ = size_ + lens;
leothedragon 0:25fa8795676b 122 this->swap( s2 );
leothedragon 0:25fa8795676b 123 }
leothedragon 0:25fa8795676b 124 }
leothedragon 0:25fa8795676b 125 return *this;
leothedragon 0:25fa8795676b 126 }
leothedragon 0:25fa8795676b 127
leothedragon 0:25fa8795676b 128 String& String::operator+=(const char c)
leothedragon 0:25fa8795676b 129 {
leothedragon 0:25fa8795676b 130 push_back(c);
leothedragon 0:25fa8795676b 131 return *this;
leothedragon 0:25fa8795676b 132 }
leothedragon 0:25fa8795676b 133
leothedragon 0:25fa8795676b 134 void String::push_back(const char c) {
leothedragon 0:25fa8795676b 135
leothedragon 0:25fa8795676b 136 if (size_ == allocated_ - 1) {
leothedragon 0:25fa8795676b 137 size_t more = (allocated_* 3) / 2; // factor 1.5
leothedragon 0:25fa8795676b 138 if ( more < 4 ) more = 4;
leothedragon 0:25fa8795676b 139 reserve( size_ + more );
leothedragon 0:25fa8795676b 140 }
leothedragon 0:25fa8795676b 141
leothedragon 0:25fa8795676b 142 p[size_] = c;
leothedragon 0:25fa8795676b 143 size_++;
leothedragon 0:25fa8795676b 144 p[size_] = 0;
leothedragon 0:25fa8795676b 145 }
leothedragon 0:25fa8795676b 146
leothedragon 0:25fa8795676b 147 bool String::operator==(const char* s) const
leothedragon 0:25fa8795676b 148 {
leothedragon 0:25fa8795676b 149 if( s == NULL ) {
leothedragon 0:25fa8795676b 150 if( p == NULL ) {
leothedragon 0:25fa8795676b 151 return true;
leothedragon 0:25fa8795676b 152 }
leothedragon 0:25fa8795676b 153 return false;
leothedragon 0:25fa8795676b 154 }
leothedragon 0:25fa8795676b 155 bool ret = strcmp(p, s);
leothedragon 0:25fa8795676b 156 return !ret;
leothedragon 0:25fa8795676b 157 }
leothedragon 0:25fa8795676b 158
leothedragon 0:25fa8795676b 159 bool String::operator==(const String& s) const
leothedragon 0:25fa8795676b 160 {
leothedragon 0:25fa8795676b 161 bool ret = strcmp(p, s.p);
leothedragon 0:25fa8795676b 162 return !ret;
leothedragon 0:25fa8795676b 163 }
leothedragon 0:25fa8795676b 164
leothedragon 0:25fa8795676b 165 void String::clear()
leothedragon 0:25fa8795676b 166 {
leothedragon 0:25fa8795676b 167 size_ = 0;
leothedragon 0:25fa8795676b 168 p[0] = 0;
leothedragon 0:25fa8795676b 169 }
leothedragon 0:25fa8795676b 170
leothedragon 0:25fa8795676b 171 String String::substr(const size_type pos, size_type length) const
leothedragon 0:25fa8795676b 172 {
leothedragon 0:25fa8795676b 173 String s;
leothedragon 0:25fa8795676b 174 const size_type len = size_;
leothedragon 0:25fa8795676b 175
leothedragon 0:25fa8795676b 176 if ( pos <= len ) {
leothedragon 0:25fa8795676b 177
leothedragon 0:25fa8795676b 178 size_type remain = len - pos;
leothedragon 0:25fa8795676b 179
leothedragon 0:25fa8795676b 180 if ( length > remain )
leothedragon 0:25fa8795676b 181 length = remain;
leothedragon 0:25fa8795676b 182
leothedragon 0:25fa8795676b 183 s.reserve( length );
leothedragon 0:25fa8795676b 184
leothedragon 0:25fa8795676b 185 memcpy(s.p, p + pos, length);
leothedragon 0:25fa8795676b 186 s.p[length] = '\0';
leothedragon 0:25fa8795676b 187 s.size_ = length;
leothedragon 0:25fa8795676b 188 }
leothedragon 0:25fa8795676b 189 return s;
leothedragon 0:25fa8795676b 190 }
leothedragon 0:25fa8795676b 191
leothedragon 0:25fa8795676b 192
leothedragon 0:25fa8795676b 193 // checked access, accessing the NUL at end is allowed
leothedragon 0:25fa8795676b 194 char String::at(const size_type i) const
leothedragon 0:25fa8795676b 195 {
leothedragon 0:25fa8795676b 196 if ( i <= strlen(p) ) {
leothedragon 0:25fa8795676b 197 return p[i];
leothedragon 0:25fa8795676b 198 } else {
leothedragon 0:25fa8795676b 199 return '\0';
leothedragon 0:25fa8795676b 200 }
leothedragon 0:25fa8795676b 201 }
leothedragon 0:25fa8795676b 202
leothedragon 0:25fa8795676b 203 String& String::erase(size_type pos, size_type len)
leothedragon 0:25fa8795676b 204 {
leothedragon 0:25fa8795676b 205 if (len > 0) {
leothedragon 0:25fa8795676b 206
leothedragon 0:25fa8795676b 207 if ( pos < size_ ) { // user must not remove trailing 0
leothedragon 0:25fa8795676b 208
leothedragon 0:25fa8795676b 209 size_type s2 = size_;
leothedragon 0:25fa8795676b 210 size_type remain = s2 - pos - len;
leothedragon 0:25fa8795676b 211
leothedragon 0:25fa8795676b 212 if (remain > 0) {
leothedragon 0:25fa8795676b 213 // erase by overwriting
leothedragon 0:25fa8795676b 214 memmove(p + pos, p + pos + len, remain);
leothedragon 0:25fa8795676b 215 }
leothedragon 0:25fa8795676b 216
leothedragon 0:25fa8795676b 217 //if ( remain < 0 ) remain = 0;
leothedragon 0:25fa8795676b 218
leothedragon 0:25fa8795676b 219 // remove unused space
leothedragon 0:25fa8795676b 220 this->resize( pos+remain );
leothedragon 0:25fa8795676b 221
leothedragon 0:25fa8795676b 222 }
leothedragon 0:25fa8795676b 223 }
leothedragon 0:25fa8795676b 224 return *this;
leothedragon 0:25fa8795676b 225 }
leothedragon 0:25fa8795676b 226
leothedragon 0:25fa8795676b 227 String& String::append( const char* str, size_type n) {
leothedragon 0:25fa8795676b 228 if (str && n > 0) {
leothedragon 0:25fa8795676b 229 size_t lens = strlen(str);
leothedragon 0:25fa8795676b 230 if (n > lens)
leothedragon 0:25fa8795676b 231 n = lens;
leothedragon 0:25fa8795676b 232 size_t newlen = size_ + n;
leothedragon 0:25fa8795676b 233 this->reserve( newlen );
leothedragon 0:25fa8795676b 234 memmove(p+size_, str, n); // p and s.p MAY overlap
leothedragon 0:25fa8795676b 235 p[newlen] = 0; // add NUL termination
leothedragon 0:25fa8795676b 236 size_ = newlen;
leothedragon 0:25fa8795676b 237 }
leothedragon 0:25fa8795676b 238 return *this;
leothedragon 0:25fa8795676b 239 }
leothedragon 0:25fa8795676b 240
leothedragon 0:25fa8795676b 241 String& String::append_raw( const char* str, size_type n) {
leothedragon 0:25fa8795676b 242 if (str && n > 0) {
leothedragon 0:25fa8795676b 243 size_t newlen = size_ + n;
leothedragon 0:25fa8795676b 244 this->reserve( newlen );
leothedragon 0:25fa8795676b 245 memmove(p+size_, str, n); // p and s.p MAY overlap
leothedragon 0:25fa8795676b 246 p[newlen] = 0; // add NUL termination
leothedragon 0:25fa8795676b 247 size_ = newlen;
leothedragon 0:25fa8795676b 248 }
leothedragon 0:25fa8795676b 249 return *this;
leothedragon 0:25fa8795676b 250 }
leothedragon 0:25fa8795676b 251
leothedragon 0:25fa8795676b 252 void String::append_int(int param) {
leothedragon 0:25fa8795676b 253
leothedragon 0:25fa8795676b 254 // max len of "-9223372036854775808" plus zero termination
leothedragon 0:25fa8795676b 255 char conv_buff[20+1];
leothedragon 0:25fa8795676b 256
leothedragon 0:25fa8795676b 257 int len = itoa_c(param, conv_buff);
leothedragon 0:25fa8795676b 258 append_raw(conv_buff, len);
leothedragon 0:25fa8795676b 259 }
leothedragon 0:25fa8795676b 260
leothedragon 0:25fa8795676b 261 int String::compare( size_type pos, size_type len, const String& str ) const {
leothedragon 0:25fa8795676b 262 int r = -1;
leothedragon 0:25fa8795676b 263 if (pos <= size_) {
leothedragon 0:25fa8795676b 264 if ( len > size_ - pos)
leothedragon 0:25fa8795676b 265 len = size_ - pos; // limit len to available length
leothedragon 0:25fa8795676b 266
leothedragon 0:25fa8795676b 267 const size_type osize = str.size();
leothedragon 0:25fa8795676b 268 const size_type len2 = MIN(len, osize);
leothedragon 0:25fa8795676b 269 r = strncmp( p + pos, str.p, len2);
leothedragon 0:25fa8795676b 270 if (r==0) // equal so far, now compare sizes
leothedragon 0:25fa8795676b 271 r = len < osize ? -1 : ( len == osize ? 0 : +1 );
leothedragon 0:25fa8795676b 272 }
leothedragon 0:25fa8795676b 273 return r;
leothedragon 0:25fa8795676b 274 }
leothedragon 0:25fa8795676b 275
leothedragon 0:25fa8795676b 276 int String::compare( size_type pos, size_type len, const char* str ) const {
leothedragon 0:25fa8795676b 277 int r = -1;
leothedragon 0:25fa8795676b 278 if (pos <= size_) {
leothedragon 0:25fa8795676b 279
leothedragon 0:25fa8795676b 280 if ( len > size_ - pos)
leothedragon 0:25fa8795676b 281 len = size_ - pos; // limit len to available length
leothedragon 0:25fa8795676b 282
leothedragon 0:25fa8795676b 283 const size_type osize = strlen(str);
leothedragon 0:25fa8795676b 284 const size_type len2 = MIN(len, osize);
leothedragon 0:25fa8795676b 285 r = strncmp( p + pos, str, len2);
leothedragon 0:25fa8795676b 286 if (r==0) // equal so far, now compare sizes
leothedragon 0:25fa8795676b 287 r = len < osize ? -1 : ( len == osize ? 0 : +1 );
leothedragon 0:25fa8795676b 288 }
leothedragon 0:25fa8795676b 289 return r;
leothedragon 0:25fa8795676b 290 }
leothedragon 0:25fa8795676b 291
leothedragon 0:25fa8795676b 292 int String::find_last_of(char c) const {
leothedragon 0:25fa8795676b 293 int r = -1;
leothedragon 0:25fa8795676b 294 char *v;
leothedragon 0:25fa8795676b 295 v = strrchr(p,c);
leothedragon 0:25fa8795676b 296 if (v != NULL) {
leothedragon 0:25fa8795676b 297 r = 0;
leothedragon 0:25fa8795676b 298 char* i = p;
leothedragon 0:25fa8795676b 299 while (v != i) {
leothedragon 0:25fa8795676b 300 i++;
leothedragon 0:25fa8795676b 301 r++;
leothedragon 0:25fa8795676b 302 }
leothedragon 0:25fa8795676b 303 }
leothedragon 0:25fa8795676b 304 return r;
leothedragon 0:25fa8795676b 305 }
leothedragon 0:25fa8795676b 306
leothedragon 0:25fa8795676b 307 void String::new_realloc( size_type n) {
leothedragon 0:25fa8795676b 308 if (n > 0 ) {
leothedragon 0:25fa8795676b 309 char* pnew = static_cast<char*>(realloc(p, n)); // could return NULL
leothedragon 0:25fa8795676b 310 if (pnew)
leothedragon 0:25fa8795676b 311 p = pnew;
leothedragon 0:25fa8795676b 312 }
leothedragon 0:25fa8795676b 313 }
leothedragon 0:25fa8795676b 314
leothedragon 0:25fa8795676b 315 void String::reserve( const size_type n) {
leothedragon 0:25fa8795676b 316 if (n >= allocated_ ) {
leothedragon 0:25fa8795676b 317 this->new_realloc(n + 1);
leothedragon 0:25fa8795676b 318 allocated_ = n + 1;
leothedragon 0:25fa8795676b 319 }
leothedragon 0:25fa8795676b 320 }
leothedragon 0:25fa8795676b 321
leothedragon 0:25fa8795676b 322 void String::resize( const size_type n) {
leothedragon 0:25fa8795676b 323 this->resize( n, 0 );
leothedragon 0:25fa8795676b 324 }
leothedragon 0:25fa8795676b 325
leothedragon 0:25fa8795676b 326 void String::resize( const size_type n, const char c) {
leothedragon 0:25fa8795676b 327 if (n < size_ ) {
leothedragon 0:25fa8795676b 328 p[n] = 0;
leothedragon 0:25fa8795676b 329 size_ = n;
leothedragon 0:25fa8795676b 330 }
leothedragon 0:25fa8795676b 331 else if (n > size_ ) {
leothedragon 0:25fa8795676b 332 this->reserve( n );
leothedragon 0:25fa8795676b 333 for (size_type i=size_; i < n; ++i )
leothedragon 0:25fa8795676b 334 p[i] = c;
leothedragon 0:25fa8795676b 335 p[n] = 0;
leothedragon 0:25fa8795676b 336 size_ = n;
leothedragon 0:25fa8795676b 337 }
leothedragon 0:25fa8795676b 338 }
leothedragon 0:25fa8795676b 339
leothedragon 0:25fa8795676b 340 void String::swap(String& s) {
leothedragon 0:25fa8795676b 341
leothedragon 0:25fa8795676b 342 // do the swap manually, without relience on std::swap() as that is not always available
leothedragon 0:25fa8795676b 343 size_t temp;
leothedragon 0:25fa8795676b 344 char* tempPtr;
leothedragon 0:25fa8795676b 345
leothedragon 0:25fa8795676b 346 temp = allocated_;
leothedragon 0:25fa8795676b 347 allocated_ = s.allocated_;
leothedragon 0:25fa8795676b 348 s.allocated_ = temp;
leothedragon 0:25fa8795676b 349
leothedragon 0:25fa8795676b 350 temp = size_;
leothedragon 0:25fa8795676b 351 size_ = s.size_;
leothedragon 0:25fa8795676b 352 s.size_ = temp;
leothedragon 0:25fa8795676b 353
leothedragon 0:25fa8795676b 354 tempPtr = p;
leothedragon 0:25fa8795676b 355 p = s.p;
leothedragon 0:25fa8795676b 356 s.p = tempPtr;
leothedragon 0:25fa8795676b 357 }
leothedragon 0:25fa8795676b 358
leothedragon 0:25fa8795676b 359
leothedragon 0:25fa8795676b 360 // Comparison
leothedragon 0:25fa8795676b 361 bool operator<( const String& s1, const String& s2 ) {
leothedragon 0:25fa8795676b 362 return strcmp( s1.c_str(), s2.c_str() ) < 0;
leothedragon 0:25fa8795676b 363 }
leothedragon 0:25fa8795676b 364
leothedragon 0:25fa8795676b 365 void reverse(char s[], uint32_t length)
leothedragon 0:25fa8795676b 366 {
leothedragon 0:25fa8795676b 367 uint32_t i, j;
leothedragon 0:25fa8795676b 368 char c;
leothedragon 0:25fa8795676b 369
leothedragon 0:25fa8795676b 370 for (i = 0, j = length-1; i<j; i++, j--) {
leothedragon 0:25fa8795676b 371 c = s[i];
leothedragon 0:25fa8795676b 372 s[i] = s[j];
leothedragon 0:25fa8795676b 373 s[j] = c;
leothedragon 0:25fa8795676b 374 }
leothedragon 0:25fa8795676b 375 }
leothedragon 0:25fa8795676b 376
leothedragon 0:25fa8795676b 377 uint32_t itoa_c (int64_t n, char s[])
leothedragon 0:25fa8795676b 378 {
leothedragon 0:25fa8795676b 379 int64_t sign;
leothedragon 0:25fa8795676b 380 uint32_t i;
leothedragon 0:25fa8795676b 381
leothedragon 0:25fa8795676b 382 if ((sign = n) < 0)
leothedragon 0:25fa8795676b 383 n = -n;
leothedragon 0:25fa8795676b 384
leothedragon 0:25fa8795676b 385 i = 0;
leothedragon 0:25fa8795676b 386
leothedragon 0:25fa8795676b 387 do {
leothedragon 0:25fa8795676b 388 s[i++] = n % 10 + '0';
leothedragon 0:25fa8795676b 389 }
leothedragon 0:25fa8795676b 390 while ((n /= 10) > 0);
leothedragon 0:25fa8795676b 391
leothedragon 0:25fa8795676b 392 if (sign < 0)
leothedragon 0:25fa8795676b 393 s[i++] = '-';
leothedragon 0:25fa8795676b 394
leothedragon 0:25fa8795676b 395 s[i] = '\0';
leothedragon 0:25fa8795676b 396
leothedragon 0:25fa8795676b 397 m2m::reverse(s, i);
leothedragon 0:25fa8795676b 398 return i;
leothedragon 0:25fa8795676b 399 }
leothedragon 0:25fa8795676b 400
leothedragon 0:25fa8795676b 401 uint8_t* String::convert_integer_to_array(int64_t value, uint8_t &size, const uint8_t *array, const uint32_t array_size)
leothedragon 0:25fa8795676b 402 {
leothedragon 0:25fa8795676b 403 uint8_t* buffer = NULL;
leothedragon 0:25fa8795676b 404 size = 0;
leothedragon 0:25fa8795676b 405 if (array) {
leothedragon 0:25fa8795676b 406 value = String::convert_array_to_integer(array, array_size);
leothedragon 0:25fa8795676b 407 }
leothedragon 0:25fa8795676b 408
leothedragon 0:25fa8795676b 409 if(value < 0xFF) {
leothedragon 0:25fa8795676b 410 size = 1;
leothedragon 0:25fa8795676b 411 } else if(value < 0xFFFF) {
leothedragon 0:25fa8795676b 412 size = 2;
leothedragon 0:25fa8795676b 413 } else if(value < 0xFFFFFF) {
leothedragon 0:25fa8795676b 414 size = 3;
leothedragon 0:25fa8795676b 415 } else if(value < 0xFFFFFFFF) {
leothedragon 0:25fa8795676b 416 size = 4;
leothedragon 0:25fa8795676b 417 } else if(value < 0xFFFFFFFFFF) {
leothedragon 0:25fa8795676b 418 size = 5;
leothedragon 0:25fa8795676b 419 } else if(value < 0xFFFFFFFFFFFF) {
leothedragon 0:25fa8795676b 420 size = 6;
leothedragon 0:25fa8795676b 421 } else if(value < 0xFFFFFFFFFFFFFF) {
leothedragon 0:25fa8795676b 422 size = 7;
leothedragon 0:25fa8795676b 423 } else {
leothedragon 0:25fa8795676b 424 size = 8;
leothedragon 0:25fa8795676b 425 }
leothedragon 0:25fa8795676b 426
leothedragon 0:25fa8795676b 427 buffer = (uint8_t*)malloc(size);
leothedragon 0:25fa8795676b 428 if (buffer) {
leothedragon 0:25fa8795676b 429 for (int i = 0; i < size; i++) {
leothedragon 0:25fa8795676b 430 buffer[i] = (value >> ((size - i - 1) * 8));
leothedragon 0:25fa8795676b 431 }
leothedragon 0:25fa8795676b 432 } else {
leothedragon 0:25fa8795676b 433 size = 0;
leothedragon 0:25fa8795676b 434 }
leothedragon 0:25fa8795676b 435 return buffer;
leothedragon 0:25fa8795676b 436 }
leothedragon 0:25fa8795676b 437
leothedragon 0:25fa8795676b 438 int64_t String::convert_array_to_integer(const uint8_t *value, const uint32_t size)
leothedragon 0:25fa8795676b 439 {
leothedragon 0:25fa8795676b 440 int64_t temp_64 = 0;
leothedragon 0:25fa8795676b 441 for (int i = size - 1; i >= 0; i--) {
leothedragon 0:25fa8795676b 442 temp_64 += (uint64_t)(*value++) << i * 8;
leothedragon 0:25fa8795676b 443 }
leothedragon 0:25fa8795676b 444 return temp_64;
leothedragon 0:25fa8795676b 445 }
leothedragon 0:25fa8795676b 446
leothedragon 0:25fa8795676b 447 bool String::convert_ascii_to_int(const char *value, size_t length, int64_t &conversion_result)
leothedragon 0:25fa8795676b 448 {
leothedragon 0:25fa8795676b 449 unsigned int index = 0;
leothedragon 0:25fa8795676b 450
leothedragon 0:25fa8795676b 451 int64_t result = 0;
leothedragon 0:25fa8795676b 452
leothedragon 0:25fa8795676b 453 int sign;
leothedragon 0:25fa8795676b 454
leothedragon 0:25fa8795676b 455 int digit;
leothedragon 0:25fa8795676b 456
leothedragon 0:25fa8795676b 457 // return value, will be set to true if at least one digit is found
leothedragon 0:25fa8795676b 458 // and a false is returned if
leothedragon 0:25fa8795676b 459 // a) no digits found, ie. string is empty
leothedragon 0:25fa8795676b 460 // b) a non-digit or non-'+' or non-'-' char is found.
leothedragon 0:25fa8795676b 461 // c) more than one +, - chars are found
leothedragon 0:25fa8795676b 462 //
leothedragon 0:25fa8795676b 463 bool success = false;
leothedragon 0:25fa8795676b 464
leothedragon 0:25fa8795676b 465 // have predictable output value even on error
leothedragon 0:25fa8795676b 466 conversion_result = 0;
leothedragon 0:25fa8795676b 467
leothedragon 0:25fa8795676b 468 // the optional sign needs to be the first char
leothedragon 0:25fa8795676b 469 if ((length > 0) && (value[index] == '+')) {
leothedragon 0:25fa8795676b 470 sign = 1;
leothedragon 0:25fa8795676b 471 index++;
leothedragon 0:25fa8795676b 472 } else if ((length > 0) && (value[index] == '-')) {
leothedragon 0:25fa8795676b 473 sign = -1;
leothedragon 0:25fa8795676b 474 index++;
leothedragon 0:25fa8795676b 475 } else {
leothedragon 0:25fa8795676b 476 sign = 1;
leothedragon 0:25fa8795676b 477 }
leothedragon 0:25fa8795676b 478
leothedragon 0:25fa8795676b 479 while ((index < length) && (value[index] != 0)) {
leothedragon 0:25fa8795676b 480
leothedragon 0:25fa8795676b 481 const char c = value[index++];
leothedragon 0:25fa8795676b 482
leothedragon 0:25fa8795676b 483 switch (c) {
leothedragon 0:25fa8795676b 484
leothedragon 0:25fa8795676b 485 case '0':
leothedragon 0:25fa8795676b 486 case '1':
leothedragon 0:25fa8795676b 487 case '2':
leothedragon 0:25fa8795676b 488 case '3':
leothedragon 0:25fa8795676b 489 case '4':
leothedragon 0:25fa8795676b 490 case '5':
leothedragon 0:25fa8795676b 491 case '6':
leothedragon 0:25fa8795676b 492 case '7':
leothedragon 0:25fa8795676b 493 case '8':
leothedragon 0:25fa8795676b 494 case '9':
leothedragon 0:25fa8795676b 495 digit = c - '0';
leothedragon 0:25fa8795676b 496 result *= 10;
leothedragon 0:25fa8795676b 497 result += digit;
leothedragon 0:25fa8795676b 498 success = true; // at least one digit was converted successfully
leothedragon 0:25fa8795676b 499 break;
leothedragon 0:25fa8795676b 500
leothedragon 0:25fa8795676b 501 // there can be only one sign char and it must be the first
leothedragon 0:25fa8795676b 502 case '+':
leothedragon 0:25fa8795676b 503 case '-':
leothedragon 0:25fa8795676b 504 default:
leothedragon 0:25fa8795676b 505 // Note: the handling of having a number with digits in front and
leothedragon 0:25fa8795676b 506 // non-digits at end (eg. "0zero") differs from sscanf() on glibc,
leothedragon 0:25fa8795676b 507 // as sscanf will return what it got converted and a success value
leothedragon 0:25fa8795676b 508 // even if the string ended with junk.
leothedragon 0:25fa8795676b 509 conversion_result = 0;
leothedragon 0:25fa8795676b 510 return false;
leothedragon 0:25fa8795676b 511 }
leothedragon 0:25fa8795676b 512 }
leothedragon 0:25fa8795676b 513
leothedragon 0:25fa8795676b 514 // put the sign in place
leothedragon 0:25fa8795676b 515 result *= sign;
leothedragon 0:25fa8795676b 516
leothedragon 0:25fa8795676b 517 // and pass the result to caller
leothedragon 0:25fa8795676b 518 conversion_result = result;
leothedragon 0:25fa8795676b 519
leothedragon 0:25fa8795676b 520 return success;
leothedragon 0:25fa8795676b 521 }
leothedragon 0:25fa8795676b 522
leothedragon 0:25fa8795676b 523 } // namespace