Index: cpp/frams/util/sstring-simple.cpp
===================================================================
--- cpp/frams/util/sstring-simple.cpp	(revision 385)
+++ cpp/frams/util/sstring-simple.cpp	(revision 385)
@@ -0,0 +1,277 @@
+#include "sstring.h"
+#include <common/nonstd_stl.h>
+#include "extvalue.h"
+#include <assert.h>
+
+void SString::initEmpty()
+{
+txt=NULL; used=0; size=0;
+}
+
+SString::SString()
+{
+initEmpty();
+}
+
+SString::~SString()
+{
+resize(0);
+}
+
+SString::SString(int x)
+{
+initEmpty();
+if (x)
+	ensureSize(x+1);
+}
+
+SString::SString(const char *t,int t_len)
+{
+initEmpty();
+if (!t) return;
+copyFrom(t,t_len);
+}
+
+SString::SString(const SString &from)
+{
+initEmpty();
+operator=(from);
+}
+
+SString::SString(SString&& from)
+{
+txt=from.txt; size=from.size; used=from.used;
+from.txt=NULL; from.size=0; from.used=0;
+}
+
+void SString::resize(int newsize)
+{
+if (newsize==size) return;
+txt=(char*)realloc(txt,newsize);
+size=newsize;
+}
+
+void SString::ensureSize(int needed)
+{
+if (size>needed) return;
+resize( (size>0) ? (needed+needed/2+1) : (needed+1));
+}
+
+char *SString::directWrite(int ensuresize)
+{
+ensureSize(ensuresize);
+appending=used;
+return txt;
+}
+
+char *SString::directAppend(int maxappend)
+{
+ensureSize(used+maxappend);
+appending=used;
+return txt+appending;
+}
+
+void SString::endWrite(int newlength)
+{
+if (newlength<0) newlength=strlen(txt);
+else txt[newlength]=0;
+used=newlength;
+assert(used<size);
+}
+
+void SString::endAppend(int newappend)
+{
+if (newappend<0) newappend=strlen(txt+appending);
+else txt[appending+newappend]=0;
+used=appending+newappend;
+assert(used<size);
+}
+
+////////////// append /////////////////
+
+void SString::operator+=(const char *s)
+{
+if (!s) return;
+int x=strlen(s);
+if (!x) return;
+append(s,x);
+}
+
+void SString::append(const char *t,int n)
+{
+if (!n) return;
+ensureSize(used+n);
+memmove(txt+used,t,n);
+used+=n;
+txt[used]=0;
+}
+
+void SString::operator+=(const SString&s)
+{
+append(s.c_str(),s.len());
+}
+
+SString SString::operator+(const SString& s) const
+{
+SString ret(len()+s.len());
+ret=*this;
+ret+=s;
+return ret;
+}
+
+/////////////////////////////
+
+void SString::copyFrom(const char *ch,int chlen)
+{
+if (!ch) chlen=0;
+else if (chlen<0) chlen=strlen(ch);
+if (chlen)
+	{
+	ensureSize(chlen);
+	memmove(txt,ch,chlen);
+	txt[chlen]=0;
+	used=chlen;
+	}
+else
+	{
+	if (txt)
+		{
+		txt[0]=0;
+		used=0;
+		}
+	}
+}
+
+void SString::operator=(const char *ch)
+{
+copyFrom(ch);
+}
+
+void SString::operator=(const SString&s)
+{
+if (&s==this) return;
+copyFrom(s.c_str(),s.len());
+}
+
+///////////////////////////////////////
+
+SString SString::substr(int begin, int length) const
+{
+if (begin<0) { length+=begin; begin=0; }
+if (length>=(len()-begin)) length=len()-begin;
+if (length<=0) return SString();
+if (length==len()) return *this;
+return SString((*this)(begin),length);
+}
+
+///////////////////////////////////////
+
+int SString::equals(const SString& s) const
+{
+if (this==&s) return 1;
+if (len()!=s.len()) return 0;
+return !strcmp(getPtr(),s.getPtr());
+}
+
+///////////////////////////////////////
+
+int SString::indexOf(int character,int start) const
+{
+const char *found=strchr(getPtr()+start,character);
+return found?found-getPtr():-1;
+}
+
+int SString::indexOf(const char *substring,int start) const
+{
+const char *found=strstr(getPtr()+start,substring);
+return found?found-getPtr():-1;
+}
+
+int SString::indexOf(const SString & substring,int start) const
+{
+const char *found=strstr(getPtr()+start,substring.c_str());
+return found?found-getPtr():-1;
+}
+
+int SString::getNextToken (int& pos,SString &token,char separator) const
+{
+if (pos>=len()) {token=0;return 0;}
+int p1=pos,p2;
+const char *t1=getPtr()+pos;
+const char *t2=strchr(t1,separator);
+if (t2) pos=(p2=(t2-getPtr()))+1; else p2=pos=len();
+strncpy(token.directWrite(p2-p1),t1,p2-p1);
+token.endWrite(p2-p1);
+return 1;
+}
+
+int SString::startsWith(const char *pattern) const
+{
+const char *t=this->c_str();
+for (;*pattern;pattern++,t++)
+	if (*t != *pattern) return 0;
+return 1;
+}
+
+SString SString::valueOf(int i)
+{
+return SString::sprintf("%d",i);
+}
+SString SString::valueOf(long i)
+{
+return SString::sprintf("%d",i);
+}
+SString SString::valueOf(double d)
+{
+SString tmp=SString::sprintf("%.15g",d);
+if ((!strchr(tmp.c_str(),'.'))&&(!strchr(tmp.c_str(),'e'))) tmp+=".0";
+return tmp;
+}
+SString SString::valueOf(const SString& s)
+{
+return s;
+}
+
+SString SString::sprintf(const char* format, ...)
+{
+int n, size = 30;
+va_list ap;
+
+SString ret;
+
+#ifdef USE_VSCPRINTF
+va_start(ap, format);
+size=_vscprintf(format, ap);
+va_end(ap);
+#endif
+
+while (1)
+	{
+	char* p=ret.directWrite(size);
+	assert(p!=NULL);
+	size=ret.directMaxLen()+1;
+	/* Try to print in the allocated space. */
+	va_start(ap, format);
+	n = vsnprintf(p, size, format, ap);
+	va_end(ap);
+	/* If that worked, return the string. */
+	if (n > -1 && n < size)
+		{
+		ret.endWrite(n);
+		return ret;
+		}
+	/* Else try again with more space. */
+#ifdef VSNPRINTF_RETURNS_REQUIRED_SIZE
+	if (n > -1)    /* glibc 2.1 */
+		size = n; /* precisely what is needed */
+	else           /* glibc 2.0 */
+#endif
+		size *= 2;  /* twice the old size */
+	}
+}
+
+SString &SString::empty()
+{
+static SString empty;
+return empty;
+}
Index: cpp/frams/util/sstring-simple.h
===================================================================
--- cpp/frams/util/sstring-simple.h	(revision 385)
+++ cpp/frams/util/sstring-simple.h	(revision 385)
@@ -0,0 +1,146 @@
+#ifndef _SSTRING_SIMPLE_H_
+#define _SSTRING_SIMPLE_H_
+
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+class ExtValue;  //this include would result in recurrent inclusion: #include "extvalue.h"
+class ExtObject;
+
+class SString
+{
+private:
+char *txt;      ///< string buffer or NULL for empty string
+int size;       ///< allocated memory (including \0)
+int used;	///< string length
+int appending;  ///< append mode, changes can occur after character # 'appending'
+
+void initEmpty();
+void copyFrom(SString &from); ///< copy from SString
+void resize(int newsize);
+void ensureSize(int needed);
+const char* getPtr() const {return txt?txt:"";}
+
+public:
+SString(); ///< make an empty string
+SString(const char*t,int t_len=-1); ///< make a string from char*
+SString(int x); ///< string with initial buffer allocated for x characters
+SString(const SString& from); ///< duplicate string
+SString(SString&& from);///< move
+~SString();
+
+void copyFrom(const char* ch, int chlen=-1); ///< copy string, length of -1 == unknown
+
+void* operator new(size_t s, void* mem) {return mem;}
+#ifdef _MSC_VER
+void operator delete(void* mem, void* t) {}
+#endif
+void* operator new(size_t s) {return malloc(sizeof(SString));}
+void operator delete(void* mem) {free(mem);}
+
+int len() const {return used;} ///< get string length
+void shrink(); ///< free unnecessary buffer
+
+/// after this call, you can modify sstring directly.
+/// returned value is the pointer to the internal buffer.
+/// <B>ensuresize</B> is minimal value of bytes you need,
+/// the buffer will be resized as needed.
+/// all "direct" operations have to leave the buffer with trailing '\0'
+/// at the end. endWrite() will search for this value in order to determine
+/// new string length.
+/// <P>Sample:<CODE>
+/// SString t;
+/// sprintf(t.directWrite(50),"a=%d,b=%f",a,b);
+/// t.endWrite();</CODE>
+char *directWrite(int ensuresize=-1);
+//char *directWrite();
+/// like directWrite, but it returns the pointer to the first char after current string
+/// for easy appending. <B>maxappend</B> is minimum of character in buffer
+/// that can be appended after this call.
+/// <P>Sample:<CODE>
+/// SString t;
+/// sprintf(t.directAppend(10),"c=%d",c);
+/// t.endAppend();</CODE>
+char *directAppend(int maxappend=0);
+/// update string length, after directWrite.
+/// you don't have to to call endWrite after directWrite if the string's length doesn't change.
+/// optional <B>newlength</B> parameter gives a chance to further optimize
+/// this operation if you know exact length of resulting string.
+/// <P>Sample:<CODE>
+/// SString t("samplestring");
+/// strncpy(t.directWrite(50),src,bytecount);
+/// t.endWrite(bytecount);</CODE>
+void endWrite(int newlength=-1);
+/// update string length, after directAppend.
+/// you will usually need to call endAppend (or endWrite) after directAppend,
+/// because the purpose of directAppend is to change string's length.
+/// optional <B>appendlength</B> parameter gives a chance to further optimize
+/// this operation if you know exact length of the appended string.
+/// <P>Sample:<CODE>
+/// SString t("samplestring");
+/// strncpy(t.directAppend(50),src,bytecount);
+/// t.endAppend(bytecount);</CODE>
+void endAppend(int appendlength=-1);
+
+void memoryHint(int howbig) {ensureSize(howbig);}
+int directMaxLen() {return size-1;} ///< when called after directWrite: max number of characters allowed (can be more than requested)
+
+/// find a character in SString.
+/// return index if the character was found or -1 otherwise.
+int indexOf(int character,int start=0) const;
+
+/// find a substring.
+/// return index if the substring was found or -1 otherwise.
+int indexOf(const char *substring,int start=0) const;
+
+/// find a substring.
+/// return index if the substring was found or -1 otherwise.
+int indexOf(const SString & substring,int start=0) const;
+
+const char* c_str() const {return getPtr();} ///< get SString's readonly buffer
+void operator=(const char*t); ///< assign from const char*
+void operator=(const SString &s);
+
+void append(const char *t,int n);
+SString operator+(const SString &s) const;
+void operator+=(int x); ///< append x spaces after current string
+void operator+=(const char*); ///< append char* contents
+void operator+=(const SString&); ///< append other SString
+
+int equals(const SString &s) const; ///< TRUE if equal
+int operator==(const SString &s) const {return equals(s);} ///< TRUE if equal
+int operator!=(const SString &s) const {return !equals(s);} ///< TRUE if not equal
+bool operator<(const SString &s) const {return strcmp(getPtr(),s.getPtr())<1;}
+const char* operator()(int p) const {return getPtr()+p;} ///< pointer to p'th character in SString
+char operator[](int i) const {return getPtr()[i];} ///< get char like in array
+
+/// return a substring of the current string
+SString substr(int begin, int length=1<<30) const;
+
+/// simple tokenization:
+/// starting at <B>pos</B>, get next substring delimited by <B>separator</B> character
+/// and put it in output parameter <B>token</B>.
+/// <B>pos</B> is moved accordingly.
+/// returns <B>false</B> if no more tokens are available or <B>true</B> otherwise.
+int getNextToken(int& pos,SString &token,char separator) const;
+
+void operator+=(char ch) {directAppend(1)[0]=ch;endAppend(1);} ///< append single character
+
+int startsWith(const char *pattern) const;
+char charAt(int pos) const {return operator[](pos);}
+uint32_t hash() const;
+
+static SString valueOf(int);
+static SString valueOf(long);
+static SString valueOf(double);
+static SString valueOf(const SString&); //tylko do kompletu zeby mozna uzyc tej funkcji nie martwiac sie o typ argumentu
+static SString valueOf(const ExtValue&); //tylko do kompletu zeby mozna uzyc tej funkcji nie martwiac sie o typ argumentu
+static SString valueOf(const ExtObject&); //tylko do kompletu zeby mozna uzyc tej funkcji nie martwiac sie o typ argumentu
+static SString sprintf(const char* format, ...);
+
+static SString &empty();
+};
+
+#endif
Index: cpp/frams/util/sstring.h
===================================================================
--- cpp/frams/util/sstring.h	(revision 384)
+++ cpp/frams/util/sstring.h	(revision 385)
@@ -6,5 +6,5 @@
 #define _SSTRING_H_
 
-//#define SSTRING_SIMPLE
+#define SSTRING_SIMPLE
 
 #ifdef SSTRING_SIMPLE
