blob: a82c11dd8d0d7fc2625c9a5ad28cc41a537eac3c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017 protos software gmbh (http://www.protos.de).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* CONTRIBUTORS:
* Henrik Rentz-Reichert (initial contribution)
*
*******************************************************************************/
#include "common/containers/String.h"
namespace etRuntime {
size_t String::nallocs = 0;
size_t String::ndeallocs = 0;
size_t String::ncreated = 0;
size_t String::ndestroyed = 0;
String::String()
: _size(0)
, _data(new char[1])
{
++nallocs;
++ncreated;
_data[0] = '\0';
}
String::~String(void) {
++ndestroyed;
if (_data) {
delete[] _data;
++ndeallocs;
}
}
/*
* added this according to
* http://stackoverflow.com/questions/1634359/is-there-a-reverse-function-for-strstr
*/
static const char *rstrstr(const char * s1, const char * s2) {
size_t s1len = strlen(s1);
size_t s2len = strlen(s2);
const char *s;
if (s2len > s1len) {
return NULL;
}
for (s = s1 + s1len - s2len; s >= s1; --s) {
if (strncmp(s, s2, s2len) == 0) {
return s;
}
}
return NULL;
}
String& String::operator=(const char *rhs) {
if (rhs && rhs!=this->_data) {
size_t new_size = std::strlen(rhs) + 1;
if (new_size > _size) {
_size = new_size;
if (_data) {
delete[] _data;
++ndeallocs;
}
_data = new char[new_size];
++nallocs;
}
std::strcpy(this->_data, rhs);
}
return *this;
}
const String String::operator+=(const char* rhs) {
if (rhs) {
size_t new_size = this->length() + std::strlen(rhs) + 1;
if (new_size > _size) {
_size = new_size;
char* new_data = new char[new_size];
++nallocs;
if (_data) {
std::strcpy(new_data, _data);
delete[] _data;
++ndeallocs;
}
else {
new_data[0] = '\0';
}
_data = new_data;
}
std::strcat(this->_data, rhs);
}
// Note: this function returns a const, not a const&!
// this prohibits things like (a + b) = c
return *this;
}
const String String::operator+=(char c) {
size_t new_size = this->length() + 2;
if (new_size > _size) {
_size = new_size;
char* new_data = new char[new_size];
++nallocs;
if (_data) {
std::strcpy(new_data, _data);
delete[] _data;
++ndeallocs;
}
_data = new_data;
}
_data[new_size-2] = c;
_data[new_size-1] = '\0';
// Note: this function returns a const, not a const&!
// this prohibits things like (a + b) = c
return *this;
}
size_t String::find(const String& str, size_t pos) const {
if (pos>length()) {
return npos;
}
return std::strstr(_data + pos, str._data) - _data;
}
size_t String::find(const char* str, size_t pos) const {
if (pos>length()) {
return npos;
}
return std::strstr(_data + pos, str) - _data;
}
size_t String::find(char c, size_t pos) const {
if (pos>length()) {
return npos;
}
return std::strchr(_data + pos, c) - _data;
}
size_t String::rfind(const String& str) const {
return rstrstr(_data, str._data) - _data;
}
size_t String::rfind(const char* str) const {
return rstrstr(_data, str) - _data;
}
size_t String::rfind(char c) const {
return std::strrchr(_data, c) - _data;
}
String String::substr(size_t pos, size_t len) const {
if (pos > length()) {
return String("");
}
String result(_data+pos);
if (len < result.length()) {
result._data[len] = '\0';
}
return result;
}
} /* namespace etRuntime */