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