xref: /haiku/src/add-ons/kernel/file_systems/ramfs/String.h (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 /*
2  * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * All rights reserved. Distributed under the terms of the MIT license.
4  */
5 #ifndef STRING_H
6 #define STRING_H
7 
8 #include <SupportDefs.h>
9 #include <string.h>
10 #include <new>
11 
12 
13 // string_hash
14 //
15 // from the Dragon Book: a slightly modified hashpjw()
16 static inline
17 uint32
18 string_hash(const char *name)
19 {
20 	uint32 h = 0;
21 	if (name) {
22 		for (; *name; name++) {
23 			uint32 g = h & 0xf0000000;
24 			if (g)
25 				h ^= g >> 24;
26 			h = (h << 4) + *name;
27 		}
28 	}
29 	return h;
30 }
31 
32 #ifdef __cplusplus
33 
34 // String
35 class String {
36 public:
37 	inline String();
38 	inline String(const String &string);
39 	inline String(const char *string, int32 length = -1);
40 	inline ~String();
41 
42 	inline bool SetTo(const char *string, int32 maxLength = -1);
43 	inline void Unset();
44 
45 	inline void Truncate(int32 newLength);
46 
47 	inline const char *GetString() const;
48 	inline int32 GetLength() const	{ return fLength; }
49 
50 	inline uint32 GetHashCode() const	{ return string_hash(GetString()); }
51 
52 	inline String &operator=(const String &string);
53 	inline bool operator==(const String &string) const;
54 	inline bool operator!=(const String &string) const { return !(*this == string); }
55 
56 private:
57 	inline bool _SetTo(const char *string, int32 length);
58 
59 private:
60 	int32	fLength;
61 	char	*fString;
62 };
63 
64 /*!
65 	\class String
66 	\brief A very simple string class.
67 */
68 
69 // constructor
70 String::String()
71 	: fLength(0),
72 	  fString(NULL)
73 {
74 }
75 
76 // copy constructor
77 String::String(const String &string)
78 	: fLength(0),
79 	  fString(NULL)
80 {
81 	*this = string;
82 }
83 
84 // constructor
85 String::String(const char *string, int32 length)
86 	: fLength(0),
87 	  fString(NULL)
88 {
89 	SetTo(string, length);
90 }
91 
92 // destructor
93 String::~String()
94 {
95 	Unset();
96 }
97 
98 // SetTo
99 bool
100 String::SetTo(const char *string, int32 maxLength)
101 {
102 	if (string) {
103 		if (maxLength > 0)
104 			maxLength = strnlen(string, maxLength);
105 		else if (maxLength < 0)
106 			maxLength = strlen(string);
107 	}
108 	return _SetTo(string, maxLength);
109 }
110 
111 // Unset
112 void
113 String::Unset()
114 {
115 	if (fString) {
116 		delete[] fString;
117 		fString = NULL;
118 	}
119 	fLength = 0;
120 }
121 
122 // Truncate
123 void
124 String::Truncate(int32 newLength)
125 {
126 	if (newLength < 0)
127 		newLength = 0;
128 	if (newLength < fLength) {
129 		char *string = fString;
130 		fString = NULL;
131 		if (!_SetTo(string, newLength)) {
132 			fString = string;
133 			fLength = newLength;
134 			fString[fLength] = '\0';
135 		} else
136 			delete[] string;
137 	}
138 }
139 
140 // GetString
141 const char *
142 String::GetString() const
143 {
144 	if (fString)
145 		return fString;
146 	return "";
147 }
148 
149 // =
150 String &
151 String::operator=(const String &string)
152 {
153 	if (&string != this)
154 		_SetTo(string.fString, string.fLength);
155 	return *this;
156 }
157 
158 // ==
159 bool
160 String::operator==(const String &string) const
161 {
162 	return (fLength == string.fLength
163 			&& (fLength == 0 || !strcmp(fString, string.fString)));
164 }
165 
166 // _SetTo
167 bool
168 String::_SetTo(const char *string, int32 length)
169 {
170 	bool result = true;
171 	Unset();
172 	if (string && length > 0) {
173 		fString = new(std::nothrow) char[length + 1];
174 		if (fString) {
175 			memcpy(fString, string, length);
176 			fString[length] = '\0';
177 			fLength = length;
178 		} else
179 			result = false;
180 	}
181 	return result;
182 }
183 
184 
185 #endif	// __cplusplus
186 
187 #endif	// STRING_H
188