Ram Gandikota
/
IOTMetronome
FRDM K64F Metronome
Diff: mbed-client/source/m2mstring.cpp
- Revision:
- 0:dbad57390bd1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-client/source/m2mstring.cpp Sun May 14 18:37:05 2017 +0000 @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed-client/m2mstring.h" +#include <string.h> // strlen +#include <stdlib.h> // malloc, realloc +#include <assert.h> +#include <algorithm> // min + +namespace m2m { + +const String::size_type String::npos = static_cast<size_t>(-1); + +char* String::strdup(const char* s) +{ + const size_t len = strlen(s)+1; + char *p2 = static_cast<char*>(malloc(len)); + memcpy(p2, s, len); + allocated_ = len; + size_ = len-1; + return p2; +} + +String::String() + : p( strdup("") ) +{ +} + +String::~String() +{ + free(p); + p = 0; +} + +String::String(const String& s) + : p(0) +{ + if( &s != NULL ) { + p = static_cast<char*>(malloc(s.size_ + 1)); + + allocated_ = s.size_ + 1; + size_ = s.size_; + memcpy(p, s.p, size_ + 1); + } +} + +String::String(const char* s) + : p(strdup(s)) +{ +} + +String::String(const char* str, size_t n) +{ + p = static_cast<char*>(malloc(n + 1)); + + allocated_ = n + 1; + size_ = n; + memcpy(p, str, n); + p[n] = 0; +} + +String& String::operator=(const char* s) +{ + if ( p != s ) { + // s could point into our own string, so we have to allocate a new string + const size_t len = strlen(s); + char* copy = (char*) malloc( len + 1); + memmove(copy, s, len+1); // trailing 0 + free( p ); + p = copy; + size_ = len; + allocated_ = len+1; + } + return *this; +} + +String& String::operator=(const String& s) +{ + return operator=(s.p); +} + +String& String::operator+=(const String& s) +{ + if (s.size_ > 0) { + this->reserve(size_ + s.size_); + memmove(p+size_, s.p, s.size_+1); // trailing 0 + size_ += s.size_; + } + return *this; +} + +// since p and s may overlap, we have to copy our own string first +String& String::operator+=(const char* s) +{ + const size_type lens = strlen(s); + if (lens > 0) { + if (size_ + lens + 1 <= allocated_) { + memmove(p+size_, s, lens+1); // trailing 0 + size_ += lens; + } else { + String s2( *this ); // copy own data + s2.reserve(size_ + lens); + memmove(s2.p+size_, s, lens+1); // trailing 0 + s2.size_ = size_ + lens; + this->swap( s2 ); + } + } + return *this; +} + +String& String::operator+=(const char c) +{ + push_back(c); + return *this; +} + +void String::push_back(const char c) { + + if (size_ == allocated_ - 1) { + size_t more = (allocated_* 3) / 2; // factor 1.5 + if ( more < 4 ) more = 4; + reserve( size_ + more ); + } + + p[size_] = c; + size_++; + p[size_] = 0; +} + +bool String::operator==(const char* s) const +{ + if( s == NULL ) { + if( p == NULL ) { + return true; + } + return false; + } + bool ret = strcmp(p, s); + return !ret; +} + +bool String::operator==(const String& s) const +{ + bool ret = strcmp(p, s.p); + return !ret; +} + +void String::clear() +{ + size_ = 0; + p[0] = 0; +} + +String String::substr(const size_type pos, size_type length) const +{ + String s; + const size_type len = size_; + + if ( pos <= len ) { + + size_type remain = len - pos; + + if ( length > remain ) + length = remain; + + s.reserve( length ); + + memcpy(s.p, p + pos, length); + s.p[length] = '\0'; + s.size_ = length; + } + return s; +} + + +// checked access, accessing the NUL at end is allowed +char String::at(const size_type i) const +{ + if ( i <= strlen(p) ) { + return p[i]; + } else { + return '\0'; + } +} + +String& String::erase(size_type pos, size_type len) +{ + if (len > 0) { + + if ( pos < size_ ) { // user must not remove trailing 0 + + size_type s2 = size_; + size_type remain = s2 - pos - len; + + if (remain > 0) { + // erase by overwriting + memmove(p + pos, p + pos + len, remain); + } + + //if ( remain < 0 ) remain = 0; + + // remove unused space + this->resize( pos+remain ); + + } + } + return *this; +} + +String& String::append( const char* str, size_type n) { + if (str && n > 0) { + size_t lens = strlen(str); + if (n > lens) + n = lens; + size_t newlen = size_ + n; + this->reserve( newlen ); + memmove(p+size_, str, n); // p and s.p MAY overlap + p[newlen] = 0; // add NUL termination + size_ = newlen; + } + return *this; +} + +String& String::append_raw( const char* str, size_type n) { + if (str && n > 0) { + size_t newlen = size_ + n; + this->reserve( newlen ); + memmove(p+size_, str, n); // p and s.p MAY overlap + p[newlen] = 0; // add NUL termination + size_ = newlen; + } + return *this; +} + +void String::append_int(int param) { + + // max len of "-9223372036854775808" plus zero termination + char conv_buff[20+1]; + + int len = itoa_c(param, conv_buff); + append_raw(conv_buff, len); +} + +int String::compare( size_type pos, size_type len, const String& str ) const { + int r = -1; + if (pos <= size_) { + if ( len > size_ - pos) + len = size_ - pos; // limit len to available length + + const size_type osize = str.size(); + const size_type len2 = std::min(len, osize); + r = strncmp( p + pos, str.p, len2); + if (r==0) // equal so far, now compare sizes + r = len < osize ? -1 : ( len == osize ? 0 : +1 ); + } + return r; +} + +int String::compare( size_type pos, size_type len, const char* str ) const { + int r = -1; + if (pos <= size_) { + + if ( len > size_ - pos) + len = size_ - pos; // limit len to available length + + const size_type osize = strlen(str); + const size_type len2 = std::min(len, osize); + r = strncmp( p + pos, str, len2); + if (r==0) // equal so far, now compare sizes + r = len < osize ? -1 : ( len == osize ? 0 : +1 ); + } + return r; +} + +int String::find_last_of(char c) const { + int r = -1; + char *v; + v = strrchr(p,c); + if (v != NULL) { + r = 0; + char* i = p; + while (v != i) { + i++; + r++; + } + } + return r; +} + +void String::new_realloc( size_type n) { + if (n > 0 ) { + char* pnew = static_cast<char*>(realloc(p, n)); // could return NULL + if (pnew) + p = pnew; + } +} + +void String::reserve( const size_type n) { + if (n >= allocated_ ) { + this->new_realloc(n + 1); + allocated_ = n + 1; + } +} + +void String::resize( const size_type n) { + this->resize( n, 0 ); +} + +void String::resize( const size_type n, const char c) { + if (n < size_ ) { + p[n] = 0; + size_ = n; + } + else if (n > size_ ) { + this->reserve( n ); + for (size_type i=size_; i < n; ++i ) + p[i] = c; + p[n] = 0; + size_ = n; + } +} + +void String::swap( String& s ) { + std::swap( allocated_, s.allocated_ ); + std::swap( size_, s.size_ ); + std::swap( p, s.p ); +} + + +// Comparison +bool operator<( const String& s1, const String& s2 ) { + return strcmp( s1.c_str(), s2.c_str() ) < 0; +} + +void reverse(char s[], uint32_t length) +{ + uint32_t i, j; + char c; + + for (i = 0, j = length-1; i<j; i++, j--) { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } +} + +uint32_t itoa_c (int64_t n, char s[]) +{ + int64_t sign; + uint32_t i; + + if ((sign = n) < 0) + n = -n; + + i = 0; + + do { + s[i++] = n % 10 + '0'; + } + while ((n /= 10) > 0); + + if (sign < 0) + s[i++] = '-'; + + s[i] = '\0'; + + m2m::reverse(s, i); + return i; +} + +uint8_t* String::convert_integer_to_array(int64_t value, uint8_t &size, uint8_t *array, uint32_t array_size) +{ + uint8_t* buffer = NULL; + size = 0; + if (array) { + value = String::convert_array_to_integer(array, array_size); + } + + if(value < 0xFF) { + size = 1; + } else if(value < 0xFFFF) { + size = 2; + } else if(value < 0xFFFFFF) { + size = 3; + } else if(value < 0xFFFFFFFF) { + size = 4; + } else if(value < 0xFFFFFFFFFF) { + size = 5; + } else if(value < 0xFFFFFFFFFFFF) { + size = 6; + } else if(value < 0xFFFFFFFFFFFFFF) { + size = 7; + } else { + size = 8; + } + + buffer = (uint8_t*)malloc(size); + if (buffer) { + for (int i = 0; i < size; i++) { + buffer[i] = (value >> ((size - i - 1) * 8)); + } + } else { + size = 0; + } + return buffer; +} + +int64_t String::convert_array_to_integer(uint8_t *value, uint32_t size) +{ + int64_t temp_64 = 0; + for (int i = size - 1; i >= 0; i--) { + temp_64 += (uint64_t)(*value++) << i * 8; + } + return temp_64; +} + +} // namespace