Created
November 24, 2008 20:00
-
-
Save tekkub/28575 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** Fast String - Voice Technology | |
* Simple char[] substitute with faster appender. | |
* Fernando Gregianin Testa <[email protected]> | |
* v0.1 - Usando no provider v2. 2007-02-22 | |
*/ | |
#ifndef FSTRING_ | |
#define FSTRING_ | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdarg.h> | |
#include <stdio.h> | |
#define DEFAULT_FSTRING_capacity 256 | |
#define mymin(x,y) x<y?x:y | |
/** Fast string, use as a replacement to char* in your program. | |
* It performs faster than stl string and libc, when appending. | |
* It does not have the automagically growing feature, unless you explicitly calls append_growing() | |
* and this issue is by desing! | |
*/ | |
class fstring | |
{ | |
//! pointer to the internal buffer | |
char * _buffer; | |
//! integer to store the total buffer capacity | |
int _capacity; | |
//! integer to store the current end position, the "null character" | |
int _endpos; | |
//! the blocksize to grow the buffer, when needed. | |
int _blocksize; | |
//! Grows the internal buffer one blocksize. | |
void grow() | |
{ | |
char*newbuffer = (char*) malloc(_capacity+_blocksize); | |
for(int i=0;i<_capacity;i++) | |
newbuffer[i] = _buffer[i]; | |
free(_buffer); | |
_buffer = newbuffer; | |
_capacity += _blocksize; | |
} | |
public: | |
/* copy from other string | |
void copy(char*src,int size) | |
{ | |
int tc = mymin(size, _capacity); | |
for(int i=0;i<tc;i++) | |
_buffer[i] = src[i]; | |
} | |
*/ | |
/** Copy up to null char, or _capacity reached. | |
* | |
void copy(char*src) | |
{ | |
char*s=src; | |
for(_endpos=0 ; _endpos<_capacity && *s!=0 ; _endpos++, s++) | |
dest[_endpos] = *s; | |
} | |
*/ | |
/** Returns the lenght of a char, i.e., finds the null char on it. | |
*/ | |
static int mystrlen(const char * what) | |
{ | |
int len=0; | |
while (0!=what[len]) len++; | |
return len; | |
} | |
/** Constructs the string with a default capacity | |
*/ | |
fstring() { | |
_capacity = DEFAULT_FSTRING_capacity; | |
_blocksize = DEFAULT_FSTRING_capacity/2; | |
_buffer = (char*) malloc(_capacity); | |
_buffer[0] = 0; | |
_endpos = 0; | |
} | |
/** Constructs the string with the specified capacity | |
*/ | |
fstring(int size) { | |
if (size<32) size = 32; | |
_capacity = size; | |
_blocksize = size/2; | |
_buffer = (char*) malloc(_capacity); | |
*_buffer = 0; | |
_endpos = 0; | |
} | |
/** constructs a fstring with a initial buffer. | |
*/ | |
fstring(const char *buffer) { | |
int size = mystrlen(buffer)+1; | |
_blocksize= DEFAULT_FSTRING_capacity/2; | |
_capacity = size + _blocksize; | |
_buffer = (char*) malloc(_capacity); | |
// append(buffer); | |
for(_endpos=0;_endpos<_capacity && buffer[_endpos]!=0;_endpos++) | |
_buffer[_endpos]=buffer[_endpos]; | |
_buffer[_endpos]=0; | |
} | |
/** Copy constructor, creates a clone of provided fstring. | |
*/ | |
fstring(fstring& x) { | |
clone(x); | |
} | |
/** The destructor frees the buffer, since it is our responsibility. | |
*/ | |
~fstring() { | |
if (_buffer) free(_buffer); | |
} | |
/** Returns the internal buffer | |
*/ | |
char* c_str() { | |
return _buffer; | |
} | |
/** Appends data at the end of buffer | |
*/ | |
fstring& append(const char*what) | |
{ | |
char*w=(char*)what; | |
for(;;) | |
{ | |
_buffer[_endpos] = *w; | |
if (0 == *w || _endpos == _capacity) break; | |
w++; _endpos++; | |
} | |
return *this; | |
} | |
/** Appends data to the buffer and grows the buffer if needed | |
*/ | |
fstring& append_growing(const char*what) | |
{ | |
char*w=(char*)what; | |
for(;;) | |
{ | |
_buffer[_endpos] = *w; | |
if (0 == *w ) break; | |
if (_endpos == _capacity-1 ) grow(); | |
w++; _endpos++; | |
} | |
return *this; | |
} | |
/** reset the buffer | |
*/ | |
fstring& clear() { | |
_buffer[0]=0; | |
_endpos=0; | |
return *this; | |
} | |
fstring& operator=(fstring& x) { | |
return clone(x); | |
} | |
fstring& operator=(char*what) | |
{ | |
_endpos=0; | |
return append(what); | |
} | |
fstring& operator=(const char*what) | |
{ | |
_endpos=0; | |
return append(what); | |
} | |
fstring& operator+=(fstring& what) { return (*this += what.c_str()); } | |
fstring& operator+=(const char*what) { return append(what); } | |
operator const char *() { return _buffer; } | |
fstring& operator+=(const char what) | |
{ | |
if (_endpos == _capacity) return *this; | |
_buffer[_endpos] = what; | |
_endpos++; | |
} | |
int lenght() { return _endpos; } | |
int size() { return _endpos; } | |
bool isfull() { return _endpos == _capacity; } | |
/** Returns the remaining space in buffer */ | |
int remaining() { return _capacity-_endpos; } | |
fstring& format(const char * fmt,...) | |
{ | |
va_list ap; | |
va_start ( ap, fmt ); | |
vsprintf(_buffer, fmt, ap); | |
va_end(ap); | |
update_endpos(); | |
return *this; | |
} | |
fstring& clone(fstring&x) | |
{ | |
_capacity = x._capacity; | |
_blocksize = x._blocksize; | |
_endpos = x._endpos; | |
_buffer = (char*)malloc(_capacity); | |
for(int i=0;i<_capacity;i++) | |
_buffer[i] = x._buffer[i]; | |
return *this; | |
} | |
const char operator[](int c) | |
{ | |
if(c > _endpos) return 0; | |
return _buffer[c]; | |
} | |
/** Returns the internal string capacity */ | |
int capacity() | |
{ return _capacity; } | |
/** This is a sort of "correct the size" function. | |
* Users shouldn't use it. */ | |
void update_endpos() | |
{ | |
for(int i=0;i<_capacity;i++) | |
if (0 == _buffer[i]) | |
{ _endpos = i; break; } | |
} | |
}; | |
#endif /*FSTRING_*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment