#include "String.h"
#include <stdlib.h>
#include <stdio.h>
char String::ConversionBuffer[256];
int String::CaseSensitive = true;
String::String(const char* pData) {
for (_Length = 0; pData[_Length] != '\0'; _Length++);
Data = (char*)malloc(_Length + 1);
for (int I = 0; I <= _Length; I++)
Data[I] = pData[I];
}
String* String::Append(char* Buffer, int Size) {
char* NewBuffer = (char*)malloc(_Length + Size + 1);
for (int I = 0; I < _Length; I++)
NewBuffer[I] = Data[I];
for (int I = 0; I <= Size; I++)
NewBuffer[I + _Length] = Buffer[I];
return new String(NewBuffer, _Length + Size);
}
String* String::Prepend(char* Buffer, int Size) {
char* NewBuffer = (char*)malloc(_Length + Size + 1);
for (int I = 0; I < Size; I++)
NewBuffer[I] = Buffer[I];
for (int I = 0; I <= _Length; I++)
NewBuffer[I + Size] = Data[I];
return new String(NewBuffer, _Length + Size);
}
String* String::Append(char* Buffer) {
int Size;
for (Size = 0; Buffer[Size]; Size++);
return Append(Size);
}
String* String::Prepend(char* Buffer) {
int Size;
for (Size = 0; Buffer[Size]; Size++);
return Prepend(Size);
}
String* String::Append(String* Other) {
return Append(Other->Data, Other->_Length);
}
String* String::Append(bool Value) {
int Size = sprintf(ConversionBuffer, "%d", Value);
return Append(ConversionBuffer, Size);
}
String* String::Append(int Value) {
int Size = sprintf(ConversionBuffer, "%d", Value);
return Append(ConversionBuffer, Size);
}
String* String::Append(short Value) {
int Size = sprintf(ConversionBuffer, "%hd", Value);
return Append(ConversionBuffer, Size);
}
String* String::Append(long long int Value) {
int Size = ConvertLongLong(Value);
return Append(ConversionBuffer, Size);
}
String* String::Append(size_t Value) {
return Append((long long int)Value);
}
String* String::Append(float Value) {
int Size = sprintf(ConversionBuffer, "%f", Value);
return Append(ConversionBuffer, Size);
}
String* String::Append(double Value) {
int Size = sprintf(ConversionBuffer, "%f", Value);
return Append(ConversionBuffer, Size);
}
String* String::Prepend(String* Other) {
return Prepend(Other->Data, Other->_Length);
}
String* String::Prepend(bool Value) {
int Size = sprintf(ConversionBuffer, "%d", Value);
return Prepend(ConversionBuffer, Size);
}
String* String::Prepend(short Value) {
int Size = sprintf(ConversionBuffer, "%hd", Value);
return Prepend(ConversionBuffer, Size);
}
String* String::Prepend(int Value) {
int Size = sprintf(ConversionBuffer, "%d", Value);
return Prepend(ConversionBuffer, Size);
}
String* String::Prepend(long long int Value) {
int Size = ConvertLongLong(Value);
return Prepend(ConversionBuffer, Size);
}
String* String::Prepend(size_t Value) {
return Prepend((long long int)Value);
}
String* String::Prepend(float Value) {
int Size = sprintf(ConversionBuffer, "%f", Value);
return Prepend(ConversionBuffer, Size);
}
String* String::Prepend(double Value) {
int Size = sprintf(ConversionBuffer, "%f", Value);
return Prepend(ConversionBuffer, Size);
}
//Custom lli-to-string routine since sprintf provides no standardized way of doing that
int String::ConvertLongLong(long long int Value) {
int Sign = 0;
if (Value < 0) {
Sign = 1;
Value = -Value;
}
int Size = 0;
if (Value) {
while(Value) {
ConversionBuffer[Size++] = (Value % 10) + '0';
Value /= 10;
}
} else
ConversionBuffer[Size++] = '0';
if (Sign)
ConversionBuffer[Size++] = '-';
for (int I = 0; I < Size/2; I++) {
char Temp = ConversionBuffer[I];
ConversionBuffer[I] = ConversionBuffer[Size - I - 1];
ConversionBuffer[Size - I - 1] = Temp;
}
ConversionBuffer[Size] = '\0';
return Size;
}
String* String::Part(int from, int _to){
if (from <0){
from = 0;
}
if (_to > _Length){
_to = _Length;
}
char *buffer = (char*)malloc((_to+1-from)*sizeof(char));
//char *bufferptr = buffer;
for (int i = 0;i<=_to-from;i++){
buffer[i] = Data[from+i];
}
buffer[_to-from+1] = 0;
return new String(buffer);
}
int String::Find(String* search, int from){
if (CaseSensitive==true){
for (int i = from;i <=_Length - search->_Length;i++){
if (Data[i] == search->Data[0]){
//printf("i: %d\n",i);
int pos = 0;
while (Data[pos+i] == search->Data[pos]){
//printf("source = Data, Pos: %d\n"+pos);
pos++;
if (pos==search->_Length){
return i;
}
//pos++;
}
}
}
}
else{
String* s = this->ToLower();
String* s2 = search->ToLower();
for (int i = from;i <=_Length - search->_Length;i++){
if (s->Data[i] == s2->Data[0]){
//printf("i: %d\n",i);
int pos = 0;
while (s->Data[pos+i] == s2->Data[pos]){
//printf("source = Data, Pos: %d\n"+pos);
pos++;
if (pos==search->_Length){
return i;
}
//pos++;
}
}
}
}
return -1;
//return source.find(search,from);
}
int String::FindLast(String* search, int from){
if (CaseSensitive==true){
for (int i = _Length - search->_Length;i >= from;i--){
if (Data[i] == search->Data[0]){
//printf("i: %d\n",i);
int pos = 0;
while (Data[pos+i] == search->Data[pos]){
//printf("source = Data, Pos: %d\n"+pos);
pos++;
if (pos==search->_Length){
return i;
}
//pos++;
}
}
}
}
else{
String* s1 = this->ToLower();
String* s2 = search->ToLower();
for (int i = _Length - search->_Length;i >= from;i--){
if (s1->Data[i] == s2->Data[0]){
//printf("i: %d\n",i);
int pos = 0;
while (s1->Data[pos+i] == s2->Data[pos]){
//printf("source = Data, Pos: %d\n"+pos);
pos++;
if (pos==search->_Length){
return i;
}
//pos++;
}
}
}
}
return -1;
//return source.find(search,from);
}
String* String::Replace(String* search, String* restring)
{
int pos = Find(search,0);
int lastpos = 0;
//String* copy = Part(0,_Length);
String* result = new String("");
while (pos >=0){
result = result->Append(Part(lastpos,pos-1));
result = result->Append(restring);
lastpos = pos+search->_Length;
pos = Find(search,lastpos);
}
result = result->Append(Part(lastpos,_Length));
return result;
}
String* String::Between(String* _start, String* _end, int _skip)
{
//printf("Between: '%s', '%s', '%s' \n", &this->Data[0], &_start->Data[0], &_end->Data[0]);
if (_end->_Length==0) {_end=_start;}
if (_start->_Length==0) {return this;}
//printf("Between: %d, %d\n", _start->_Length, _end->_Length);
//printf("Between: '%s', '%s'\n", &_start->Data[0], &_end->Data[0]);
int pos1 = this->Find(_start, 0);
if (_skip>0)
{
//printf("Between: Skipping %d\n", _skip);
for (int i=0; i<_skip; i++)
{
pos1=this->Find(_start, pos1+_start->_Length);
}
}
int pos2 = this->Find(_end, pos1+_start->_Length);
if (pos1==-1 || pos2==-1) {return this;}
return this->Part(pos1+_start->_Length, pos2-1);
}
int String::ToInt()
{
return atoi(Data);
}
float String::ToFloat()
{
return atof(Data);
}
String* String::TrimLead()
{
int pos = 0;
for (int i=0 ;(this->Data[i]<=32) ; i++)
{
pos = i;
}
char *buffer = (char*)malloc(((this->_Length-pos)+1)*sizeof(char));
for (int j=pos ; j<=this->_Length ; j++)
{
buffer[j-pos] = this->Data[j+1];
}
buffer[this->_Length-pos] = 0;
return new String(buffer);
}
String* String::TrimTrail()
{
int pos = this->_Length;
for (int i=this->_Length ;(this->Data[i]<=32) ; i--)
{
pos = i;
}
char *buffer = (char*)malloc((pos+1)*sizeof(char));
for (int j=0 ; j<pos ; j++)
{
buffer[j] = this->Data[j];
}
buffer[pos] = 0;
return new String(buffer);
}
String* String::Trim()
{
String* result = TrimLead();
return result->TrimTrail();
}
String* String::FromChar(int code)
{
char* buffer = (char*)malloc(2*sizeof(char));
buffer[0]=code;
buffer[1]=0;
return new String(buffer);
}
int String::Ascii()
{
return (int)this->Data[0];
}
String* String::ToLower()
{
char* buffer = (char*)malloc(this->_Length*sizeof(char));
for( int i=0; i<=this->_Length;i++)
{
buffer[i]=this->Data[i];
//printf("%d\n",(int)buffer[i]);
if (((buffer[i]>=65)&&(buffer[i]<=90))||((buffer[i]>=-64)&&(buffer[i]<=-42))||((buffer[i]>=-40)&&(buffer[i]<=-34)))
{
//printf("%d\n",(int)buffer[i]);
buffer[i]+=32;
}
}
return new String(buffer);
}
String* String::ToUpper()
{
char* buffer = (char*)malloc(this->_Length*sizeof(char));
for( int i=0; i<=this->_Length;i++)
{
buffer[i]=this->Data[i];
if (((buffer[i]>=97)&&(buffer[i]<=122))||((buffer[i]>=-32)&&(buffer[i]<=-10))||((buffer[i]>=-8)&&(buffer[i]<=-2)))
{
buffer[i]-=32;
}
}
return new String(buffer);
}
int String::Contains(String* sub)
{
if (Find(sub,0)>=0){return true;}
return false;
}
int String::BeginsWith(String* sub)
{
if(Find(sub,0)==0){return true;}
return false;
}
int String::EndsWith(String* sub)
{
if(Find(sub,0)== this->_Length-sub->_Length){return true;}
return false;
}
int String::Length()
{
return _Length;
}
String* String::FromCString(char* pointer)
{
return new String(pointer);
}
String* String::FromCString(const char* pointer)
{
return new String((char*)(pointer));
}
bool String::Equals(String* Other) {
return !strcmp(Data, Other->Data);
}
String* String::Reverse()
{
char* Buffer = (char*)malloc((this->_Length+1)*sizeof(char));
for(int i = 0;i<=_Length;i++)
{
Buffer[i]=Data[_Length-i-1];
}
Buffer[_Length]=0;
return new String(Buffer);
}
String* String::Hex(int number)
{
char* Buffer = (char*)malloc(9*sizeof(char));
//Buffer[0]='$';
for (int k = 7 ; k>=0 ; k--)
{
int n = (number & 15) + 48;
if (n>57) {n=n+7;}
Buffer[k]=n;
number = number >> 4;
}
Buffer[8]=0;
return new String(Buffer);
}
String* String::Bin(int number)
{
char* Buffer = (char*)malloc(33*sizeof(char));
//Buffer[0]='$';
for (int k = 31 ; k>=0 ; k--)
{
int n = (number & 1) + 48;
//if (n>57) {n=n+7;}
Buffer[k]=n;
number = number >> 1;
}
Buffer[32]=0;
return new String(Buffer);
}
String* String::Oct(int number)
{
char* Buffer = (char*)malloc(12*sizeof(char));
//Buffer[0]='$';
for (int k = 10 ; k>=0 ; k--)
{
int n = (number & 7) + 48;
//if (n==55) {printf("hulla\n");}
Buffer[k]=n;
if (k>1)
{number = number >> 3;}
else
{number = (number&24) >>3;}
}
//sprintf("%d\n",(int)number);
//number = number >>2;
//Buffer[10]=int( (number & 7) + 48);
Buffer[11]=0;
return new String(Buffer);
}
String* String::LongOct(long long int number)
{
char* Buffer = (char*)malloc(23*sizeof(char));
//Buffer[0]='$';
for (int k = 21 ; k>=0 ; k--)
{
int n = (number & 7) + 48;
//if (n==55) {printf("hulla\n");}
Buffer[k]=n;
if (k>1)
{number = number >> 3;}
else
{number = (number&8) >>3;}
}
//sprintf("%d\n",(int)number);
//number = number >>2;
//Buffer[10]=int( (number & 7) + 48);
Buffer[22]=0;
return new String(Buffer);
}
String* String::FromBytes(Array<char, 1>* a, int number)
{
char* Buffer = (char*)malloc((number+1)*sizeof(char));
for (int i=0 ; i<number ; i++)
{
Buffer[i]=a->Data[i];
}
Buffer[number]=0;
return new String(Buffer);
}
char* String::ToCString()
{
return Data+'\0';
}
Array<String*,1>* String::Split(String* div)
{
return new Array<String*,1>(1);
Array<String*,1>* a = new Array<String*,1>(-1,CountOccurrences(div)+1);
for(int i = 0, count=0; this->Find(div,i)>=0; i=this->Find(div,i)+(div->_Length),count++)
{
a->Data[count] = Part(i,Find(div,i)-1);
}
a->Data[CountOccurrences(div)] = Part(FindLast(div,0)+div->_Length,_Length-1);
return a;
}
int String::CountOccurrences(String* sub)
{
if (Find(sub,0)>=0)
{
int count = 0;
for(int i = 0; this->Find(sub,i)>=0; i=this->Find(sub,i)+(sub->_Length))
{count++;}
return count;
}
return false;
}