/***************************************************************************
* Copyright (C) 2013 by Terraneo Federico *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* As a special exception, if other files instantiate templates or use *
* macros or inline functions from this file, or you compile this file *
* and link it with other works to produce a work based on this file, *
* this file does not by itself cause the resulting work to be covered *
* by the GNU General Public License. However the source code for this *
* file must still be made available in accordance with the GNU General *
* Public License. This exception does not invalidate any other reasons *
* why a work based on this file might be covered by the GNU General *
* Public License. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see *
***************************************************************************/
//Makes memrchr available in newer GCCs
#define _GNU_SOURCE
#include
#include "stringpart.h"
#include
using namespace std;
namespace miosix {
//
// class StringPart
//
StringPart::StringPart(string& str, size_t idx, size_t off)
: str(&str), index(idx), offset(off), saved('\0'), owner(false),
type(CPPSTR)
{
if(index==string::npos || index>=str.length()) index=str.length();
else {
saved=str[index];
str[index]='\0';
}
offset=min(offset,index);
}
StringPart::StringPart(char* s, size_t idx, size_t off)
: cstr(s), index(idx), offset(off), saved('\0'), owner(false),
type(CSTR)
{
assert(cstr); //Passed pointer can't be null
size_t len=strlen(cstr);
if(index==string::npos || index>=len) index=len;
else {
saved=cstr[index];
cstr[index]='\0';
}
offset=min(offset,index);
}
StringPart::StringPart(const char* s)
: ccstr(s), offset(0), saved('\0'), owner(false), type(CCSTR)
{
assert(ccstr); //Passed pointer can't be null
index=strlen(s);
}
StringPart::StringPart(StringPart& rhs, size_t idx, size_t off)
: saved('\0'), owner(false), type(rhs.type)
{
switch(type)
{
case CSTR:
this->cstr=rhs.cstr;
break;
case CCSTR:
type=CSTR; //To make a substring of a CCSTR we need to make a copy
if(rhs.empty()==false) assign(rhs); else cstr=&saved;
break;
case CPPSTR:
this->str=rhs.str;
break;
}
if(idx!=string::npos && idxlength()c_str(),rhs.c_str(),rhs.length())==0;
}
size_t StringPart::findLastOf(char c) const
{
const char *begin=c_str();
//Not strrchr() to take advantage of knowing the string length
void *index=memrchr(begin,c,length());
if(index==0) return std::string::npos;
return reinterpret_cast(index)-begin;
}
const char *StringPart::c_str() const
{
switch(type)
{
case CSTR: return cstr+offset;
case CCSTR: return ccstr; //Offset always 0
default: return str->c_str()+offset;
}
}
char StringPart::operator[] (size_t index) const
{
switch(type)
{
case CSTR: return cstr[offset+index];
case CCSTR: return ccstr[index]; //Offset always 0
default: return (*str)[offset+index];
}
}
void StringPart::clear()
{
if(type==CSTR)
{
cstr[index]=saved;//Worst case we'll overwrite terminating \0 with an \0
if(owner) delete[] cstr;
} else if(type==CPPSTR) {
if(index!=str->length()) (*str)[index]=saved;
if(owner) delete str;
} //For CCSTR there's nothing to do
cstr=&saved; //Reusing saved as an empty string
saved='\0';
index=offset=0;
owner=false;
type=CSTR;
}
void StringPart::assign(const StringPart& rhs)
{
cstr=new char[rhs.length()+1];
strcpy(cstr,rhs.c_str());
index=rhs.length();
offset=0;
owner=true;
}
} //namespace miosix