1 /*****************************************************************
3 | Neptune - String Objects
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are met:
10 | * Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 | * Neither the name of Axiomatic Systems nor the
16 | names of its contributors may be used to endorse or promote products
17 | derived from this software without specific prior written permission.
19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 ****************************************************************/
32 #ifndef _NPT_STRINGS_H_
33 #define _NPT_STRINGS_H_
35 /*----------------------------------------------------------------------
37 +---------------------------------------------------------------------*/
38 #include "NptConfig.h"
39 #if defined(NPT_CONFIG_HAVE_NEW_H)
43 #include "NptConstants.h"
49 /*----------------------------------------------------------------------
51 +---------------------------------------------------------------------*/
52 const int NPT_STRING_SEARCH_FAILED
= -1;
54 /*----------------------------------------------------------------------
56 +---------------------------------------------------------------------*/
61 static NPT_String
FromInteger(NPT_Int64 value
);
62 static NPT_String
FromIntegerU(NPT_UInt64 value
);
63 static NPT_String
Format(const char* format
, ...);
66 NPT_String(const NPT_String
& str
);
67 NPT_String(const char* str
);
68 NPT_String(const char* str
, NPT_Size length
);
69 NPT_String(char c
, NPT_Cardinal repeat
= 1);
70 NPT_String() : m_Chars(NULL
) {}
71 ~NPT_String() { if (m_Chars
) GetBuffer()->Destroy(); }
73 // string info and manipulations
74 bool IsEmpty() const { return m_Chars
== NULL
|| GetBuffer()->GetLength() == 0; }
75 NPT_Size
GetLength() const { return m_Chars
? GetBuffer()->GetLength() : 0; }
76 NPT_Size
GetCapacity() const { return m_Chars
? GetBuffer()->GetAllocated() : 0; }
77 NPT_Result
SetLength(NPT_Size length
, bool pad
= false);
78 void Assign(const char* chars
, NPT_Size size
);
79 void Append(const char* chars
, NPT_Size size
);
80 void Append(const char* s
) { Append(s
, StringLength(s
)); }
81 int Compare(const char* s
, bool ignore_case
= false) const;
82 static int Compare(const char* s1
, const char* s2
, bool ignore_case
= false);
83 int CompareN(const char* s
, NPT_Size count
, bool ignore_case
= false) const;
84 static int CompareN(const char* s1
, const char* s2
, NPT_Size count
, bool ignore_case
= false);
87 NPT_String
SubString(NPT_Ordinal first
, NPT_Size length
) const;
88 NPT_String
SubString(NPT_Ordinal first
) const {
89 return SubString(first
, GetLength());
91 NPT_String
Left(NPT_Size length
) const {
92 return SubString(0, length
);
94 NPT_String
Right(NPT_Size length
) const {
95 return length
>= GetLength() ?
97 SubString(GetLength()-length
, length
);
99 NPT_List
<NPT_String
> Split(const char* separator
) const;
100 NPT_Array
<NPT_String
> SplitAny(const char* separator
) const;
101 static NPT_String
Join(NPT_List
<NPT_String
>& args
, const char* separator
);
104 void Reserve(NPT_Size length
);
107 NPT_UInt32
GetHash32() const;
108 NPT_UInt64
GetHash64() const;
111 NPT_String
ToLowercase() const;
112 NPT_String
ToUppercase() const;
113 NPT_Result
ToInteger(int& value
, bool relaxed
= true) const;
114 NPT_Result
ToInteger(unsigned int& value
, bool relaxed
= true) const;
115 NPT_Result
ToInteger(long& value
, bool relaxed
= true) const;
116 NPT_Result
ToInteger(unsigned long& value
, bool relaxed
= true) const;
117 NPT_Result
ToInteger32(NPT_Int32
& value
, bool relaxed
= true) const;
118 NPT_Result
ToInteger32(NPT_UInt32
& value
, bool relaxed
= true) const;
119 NPT_Result
ToInteger64(NPT_Int64
& value
, bool relaxed
= true) const;
120 NPT_Result
ToInteger64(NPT_UInt64
& value
, bool relaxed
= true) const;
121 NPT_Result
ToFloat(float& value
, bool relaxed
= true) const;
124 void MakeLowercase();
125 void MakeUppercase();
126 const NPT_String
& Replace(char a
, char b
);
127 const NPT_String
& Replace(char a
, const char* b
);
130 int Find(char c
, NPT_Ordinal start
= 0, bool ignore_case
= false) const;
131 int Find(const char* s
, NPT_Ordinal start
= 0, bool ignore_case
= false) const;
132 int FindAny(const char* s
, NPT_Ordinal start
, bool ignore_case
= false) const;
133 int ReverseFind(char c
, NPT_Ordinal start
= 0, bool ignore_case
= false) const;
134 int ReverseFind(const char* s
, NPT_Ordinal start
= 0, bool ignore_case
= false) const;
135 bool StartsWith(const char* s
, bool ignore_case
= false) const;
136 bool EndsWith(const char* s
, bool ignore_case
= false) const;
139 const NPT_String
& Insert(const char* s
, NPT_Ordinal where
= 0);
140 const NPT_String
& Erase(NPT_Ordinal start
, NPT_Cardinal count
= 1);
141 const NPT_String
& Replace(const char* before
, const char* after
);
142 // void Replace(NPT_Ordinal start, NPT_Cardinal count, const char* s);
143 const NPT_String
& TrimLeft();
144 const NPT_String
& TrimLeft(char c
);
145 const NPT_String
& TrimLeft(const char* chars
);
146 const NPT_String
& TrimRight();
147 const NPT_String
& TrimRight(char c
);
148 const NPT_String
& TrimRight(const char* chars
);
149 const NPT_String
& Trim();
150 const NPT_String
& Trim(char c
);
151 const NPT_String
& Trim(const char* chars
);
154 operator char*() const { return m_Chars
? m_Chars
: &EmptyString
; }
155 operator const char* () const { return m_Chars
? m_Chars
: &EmptyString
; }
156 const char* GetChars() const { return m_Chars
? m_Chars
: &EmptyString
; }
157 char* UseChars() { return m_Chars
? m_Chars
: &EmptyString
; }
159 // operator overloading
160 NPT_String
& operator=(const char* str
);
161 NPT_String
& operator=(const NPT_String
& str
);
162 NPT_String
& operator=(char c
);
163 const NPT_String
& operator+=(const NPT_String
& s
) {
164 Append(s
.GetChars(), s
.GetLength());
167 const NPT_String
& operator+=(const char* s
) {
171 const NPT_String
& operator+=(char c
) {
175 char operator[](int index
) const {
176 NPT_ASSERT((unsigned int)index
< GetLength());
177 return GetChars()[index
];
179 char& operator[](int index
) {
180 NPT_ASSERT((unsigned int)index
< GetLength());
181 return UseChars()[index
];
185 friend NPT_String
operator+(const NPT_String
& s1
, const NPT_String
& s2
) {
186 return s1
+s2
.GetChars();
188 friend NPT_String
operator+(const NPT_String
& s1
, const char* s2
);
189 friend NPT_String
operator+(const char* s1
, const NPT_String
& s2
);
190 friend NPT_String
operator+(const NPT_String
& s
, char c
);
191 friend NPT_String
operator+(char c
, const NPT_String
& s
);
198 static Buffer
* Allocate(NPT_Size allocated
, NPT_Size length
) {
199 void* mem
= ::operator new(sizeof(Buffer
)+allocated
+1);
200 return new(mem
) Buffer(allocated
, length
);
202 static char* Create(NPT_Size allocated
, NPT_Size length
=0) {
203 Buffer
* shared
= Allocate(allocated
, length
);
204 return shared
->GetChars();
206 static char* Create(const char* copy
) {
207 NPT_Size length
= StringLength(copy
);
208 Buffer
* shared
= Allocate(length
, length
);
209 CopyString(shared
->GetChars(), copy
);
210 return shared
->GetChars();
212 static char* Create(const char* copy
, NPT_Size length
) {
213 Buffer
* shared
= Allocate(length
, length
);
214 CopyBuffer(shared
->GetChars(), copy
, length
);
215 shared
->GetChars()[length
] = '\0';
216 return shared
->GetChars();
218 static char* Create(char c
, NPT_Cardinal repeat
) {
219 Buffer
* shared
= Allocate(repeat
, repeat
);
220 char* s
= shared
->GetChars();
225 return shared
->GetChars();
230 // return a pointer to the first char
231 return reinterpret_cast<char*>(this+1);
233 NPT_Size
GetLength() const { return m_Length
; }
234 void SetLength(NPT_Size length
) { m_Length
= length
; }
235 NPT_Size
GetAllocated() const { return m_Allocated
; }
236 void Destroy() { ::operator delete((void*)this); }
240 Buffer(NPT_Size allocated
, NPT_Size length
= 0) :
242 m_Allocated(allocated
) {}
245 NPT_Cardinal m_Length
;
246 NPT_Cardinal m_Allocated
;
247 // the actual string data follows
259 static char EmptyString
;
262 Buffer
* GetBuffer() const {
263 return reinterpret_cast<Buffer
*>(m_Chars
)-1;
266 if (m_Chars
!= NULL
) {
271 char* PrepareToWrite(NPT_Size length
);
272 void PrepareToAppend(NPT_Size length
, NPT_Size allocate
);
275 static void CopyString(char* dst
, const char* src
) {
276 while ((*dst
++ = *src
++)){}
279 static void CopyBuffer(char* dst
, const char* src
, NPT_Size size
) {
280 while (size
--) *dst
++ = *src
++;
283 static NPT_Size
StringLength(const char* str
) {
285 while (*str
++) length
++;
290 /*----------------------------------------------------------------------
292 +---------------------------------------------------------------------*/
293 inline bool operator==(const NPT_String
& s1
, const NPT_String
& s2
) {
294 return s1
.Compare(s2
) == 0;
296 inline bool operator==(const NPT_String
& s1
, const char* s2
) {
297 return s1
.Compare(s2
) == 0;
299 inline bool operator==(const char* s1
, const NPT_String
& s2
) {
300 return s2
.Compare(s1
) == 0;
302 inline bool operator!=(const NPT_String
& s1
, const NPT_String
& s2
) {
303 return s1
.Compare(s2
) != 0;
305 inline bool operator!=(const NPT_String
& s1
, const char* s2
) {
306 return s1
.Compare(s2
) != 0;
308 inline bool operator!=(const char* s1
, const NPT_String
& s2
) {
309 return s2
.Compare(s1
) != 0;
311 inline bool operator<(const NPT_String
& s1
, const NPT_String
& s2
) {
312 return s1
.Compare(s2
) < 0;
314 inline bool operator<(const NPT_String
& s1
, const char* s2
) {
315 return s1
.Compare(s2
) < 0;
317 inline bool operator<(const char* s1
, const NPT_String
& s2
) {
318 return s2
.Compare(s1
) > 0;
320 inline bool operator>(const NPT_String
& s1
, const NPT_String
& s2
) {
321 return s1
.Compare(s2
) > 0;
323 inline bool operator>(const NPT_String
& s1
, const char* s2
) {
324 return s1
.Compare(s2
) > 0;
326 inline bool operator>(const char* s1
, const NPT_String
& s2
) {
327 return s2
.Compare(s1
) < 0;
329 inline bool operator<=(const NPT_String
& s1
, const NPT_String
& s2
) {
330 return s1
.Compare(s2
) <= 0;
332 inline bool operator<=(const NPT_String
& s1
, const char* s2
) {
333 return s1
.Compare(s2
) <= 0;
335 inline bool operator<=(const char* s1
, const NPT_String
& s2
) {
336 return s2
.Compare(s1
) >= 0;
338 inline bool operator>=(const NPT_String
& s1
, const NPT_String
& s2
) {
339 return s1
.Compare(s2
) >= 0;
341 inline bool operator>=(const NPT_String
& s1
, const char* s2
) {
342 return s1
.Compare(s2
) >= 0;
344 inline bool operator>=(const char* s1
, const NPT_String
& s2
) {
345 return s2
.Compare(s1
) <= 0;
348 /*----------------------------------------------------------------------
350 +---------------------------------------------------------------------*/
352 struct NPT_Hash
<NPT_String
>
354 NPT_UInt32
operator()(const NPT_String
& s
) const { return s
.GetHash32(); }
358 #endif // _NPT_STRINGS_H_