Skip to content

Instantly share code, notes, and snippets.

@tekkub
Created November 24, 2008 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tekkub/28575 to your computer and use it in GitHub Desktop.
Save tekkub/28575 to your computer and use it in GitHub Desktop.
/** Fast String - Voice Technology
* Simple char[] substitute with faster appender.
* Fernando Gregianin Testa <testa@voicetechnology.com.br>
* 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