source: cpp/frams/util/sstring.h @ 972

Last change on this file since 972 was 955, checked in by Maciej Komosinski, 4 years ago

Genetic format ID becomes a string (no longer limited to a single character)

  • Property svn:eol-style set to native
File size: 7.6 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#ifndef _SSTRING_H_
6#define _SSTRING_H_
7
8#define SSTRING_SIMPLE
9
10#ifdef SSTRING_SIMPLE
11
12// simple sstring implementation using direct character arrays
13// - duplicate = copy all characters
14// - no mutex needed
15
16#include "sstring-simple.h"
17
18#else
19///////////////////////////////////////////////////////////////////////////
20// old sstring implementation using SBuf references
21// - duplicate = copy buffer pointer
22// - mutex required to be thread safe
23
24#include <stdint.h>
25#include <string.h>
26#include <stdlib.h>
27#include <stdio.h>
28
29class ExtValue;  //this include would result in recurrent inclusion: #include "extvalue.h"
30class ExtObject;
31
32class SBuf
33{
34        char *txt;
35        int used;       ///< data size
36        int size;       ///< buffer size, not including \0, special case: 0==buffer not allocated
37        int refcount;   ///< buffer is used by 'refcount' objects.
38        void initEmpty();
39        void ensureSize(int wantsize);
40        void copyFrom(const char* ch, int chlen = -1);
41        void freeBuf();
42        void append(const char* ch, int chlen = -1);
43        static SBuf &empty();
44        SBuf(int initsize);
45        friend class SString;
46        SBuf(const SBuf& b) {}
47public:
48        SBuf();
49        ~SBuf();
50        uint32_t hash() const; // 32-bit FNV-1 hash -> http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash
51};
52
53/// (not so) simple text string class
54
55class SString
56{
57private:
58        SBuf *buf;      ///< buffer
59        int appending;  ///< append mode, changes can occur after character # 'appending'
60        //int memhint;
61
62        void initEmpty();
63        int guessMemSize(int request);
64        void copyFrom(SString &from); ///< copy from SString, reference if possible
65        void detach(); ///< detach from shared buffer, if any
66        void detachEmpty(int ensuresize = 0); ///< detach and make empty
67        void detachCopy(int ensuresize = 0); ///< detach and make private copy
68
69public:
70        SString(); ///< make an empty string
71        SString(const char*t, int t_len = -1); ///< make a string from char*
72        SString(int x) = delete; ///< disallow the former 'int' constructor (so the new 'char' version is not used through implicit conversion)
73        SString(const SString& from); ///< duplicate string
74        SString(SString&& from); ///< move
75        SString(char in);
76        ~SString();
77
78        void copyFrom(const char* ch, int chlen = -1); ///< copy string, length of -1 == unknown
79
80        void* operator new(size_t s, void* mem) { return mem; }
81#ifdef _MSC_VER
82        void operator delete(void* mem, void* t) {}
83#endif
84        void* operator new(size_t s) { return malloc(sizeof(SString)); }
85        void operator delete(void* mem) { free(mem); }
86
87        int len() const { return buf->used; } ///< get string length
88        void shrink(); ///< free unnecessary buffer
89        void reserve(int needed) { ensureSize(needed); } ///< like in std::string
90
91        /// after this call, you can modify sstring directly.
92        /// returned value is the pointer to the internal buffer.
93        /// <B>ensuresize</B> is minimal value of bytes you need,
94        /// the buffer will be resized as needed.
95        /// all "direct" operations have to leave the buffer with trailing '\0'
96        /// at the end. endWrite() will search for this value in order to determine
97        /// new string length.
98        /// <P>Sample:<CODE>
99        /// SString t;
100        /// sprintf(t.directWrite(50),"a=%d,b=%f",a,b);
101        /// t.endWrite();</CODE>
102        char *directWrite(int ensuresize = -1);
103        //char *directWrite();
104        /// like directWrite, but it returns the pointer to the first char after current string
105        /// for easy appending. <B>maxappend</B> is minimum of character in buffer
106        /// that can be appended after this call.
107        /// <P>Sample:<CODE>
108        /// SString t;
109        /// sprintf(t.directAppend(10),"c=%d",c);
110        /// t.endAppend();</CODE>
111        char *directAppend(int maxappend = 0);
112        /// update string length, after directWrite.
113        /// you don't have to to call endWrite after directWrite if the string's length doesn't change.
114        /// optional <B>newlength</B> parameter gives a chance to further optimize
115        /// this operation if you know exact length of resulting string.
116        /// <P>Sample:<CODE>
117        /// SString t("samplestring");
118        /// strncpy(t.directWrite(50),src,bytecount);
119        /// t.endWrite(bytecount);</CODE>
120        void endWrite(int newlength = -1);
121        /// update string length, after directAppend.
122        /// you will usually need to call endAppend (or endWrite) after directAppend,
123        /// because the purpose of directAppend is to change string's length.
124        /// optional <B>appendlength</B> parameter gives a chance to further optimize
125        /// this operation if you know exact length of the appended string.
126        /// <P>Sample:<CODE>
127        /// SString t("samplestring");
128        /// strncpy(t.directAppend(50),src,bytecount);
129        /// t.endAppend(bytecount);</CODE>
130        void endAppend(int appendlength = -1);
131        /// argument is the amount of memory, that will be probably used
132        /// by this string instance. string can use this value
133        /// to optimize memory allocation (bigger chunks will be allocated).
134        void memoryHint(int howbig);
135        int directMaxLen() { return buf->size; } ///< when called after directWrite: max number of characters allowed (can be more than requested)
136
137        /// find a character in SString.
138        /// return index if the character was found or -1 otherwise.
139        int indexOf(int character, int start = 0) const;
140
141        /// find a substring.
142        /// return index if the substring was found or -1 otherwise.
143        int indexOf(const char *substring, int start = 0) const;
144
145        /// find a substring.
146        /// return index if the substring was found or -1 otherwise.
147        int indexOf(const SString & substring, int start = 0) const;
148
149        const char* c_str() const { return buf->txt; } ///< get SString's readonly buffer
150        //operator char*() {detachCopy(len()); return buf->txt;} ///< get SString's writable buffer
151        void operator=(const char*t); ///< assign from const char*
152        //void operator=(int x) {free(txt);nowy(x);} ///< clear string and make new empty one
153        void operator=(const SString &s);
154
155        void append(const char *txt, int count);
156        SString operator+(const SString &s) const;
157        void operator+=(int x); ///< append x spaces after current string
158        void operator+=(const char*); ///< append char* contents
159        void operator+=(const SString&); ///< append other SString
160
161        bool equals(const SString &s) const; ///< TRUE if equal
162        bool operator==(const SString &s) const { return equals(s); } ///< TRUE if equal
163        bool operator!=(const SString &s) const { return !equals(s); }
164        const char* operator()(int p) const { return buf->txt + p; } ///< pointer to p'th character in SString
165        char operator[](int i) const { return buf->txt[i]; } ///< get char like in array
166
167        /// return a substring of the current string
168        SString substr(int begin, int length = 1 << 30) const;
169
170        /// simple tokenization:
171        /// starting at <B>pos</B>, get next substring delimited by <B>separator</B> character
172        /// and put it in output parameter <B>token</B>.
173        /// <B>pos</B> is moved accordingly.
174        /// returns <B>false</B> if no more tokens are available or <B>true</B> otherwise.
175        bool getNextToken(int& pos, SString &token, char separator) const;
176
177        void operator+=(char ch) { directAppend(1)[0] = ch; endAppend(1); } ///< append single character
178
179        bool startsWith(const char *pattern) const;
180        char charAt(int pos) const { return buf->txt[pos]; }
181        uint32_t hash() const { return buf->hash(); }
182
183        static SString valueOf(int);
184        static SString valueOf(long);
185        static SString valueOf(double);
186        static SString valueOf(const SString&); //tylko do kompletu zeby mozna uzyc tej funkcji nie martwiac sie o typ argumentu
187        static SString valueOf(const ExtValue&); //tylko do kompletu zeby mozna uzyc tej funkcji nie martwiac sie o typ argumentu
188        static SString valueOf(const ExtObject&); //tylko do kompletu zeby mozna uzyc tej funkcji nie martwiac sie o typ argumentu
189        static SString sprintf(const char* format, ...);
190
191        static SString &empty();
192};
193
194#endif //#ifdef SSTRING_SIMPLE
195
196#endif
Note: See TracBrowser for help on using the repository browser.