xref: /haiku/src/add-ons/kernel/file_systems/userlandfs/shared/String.cpp (revision 83812f67529c88d4fb4b942162a9f21142e683fa)
1*83812f67SIngo Weinhold // String.cpp
2*83812f67SIngo Weinhold 
3*83812f67SIngo Weinhold #include <new.h>
4*83812f67SIngo Weinhold #include <string.h>
5*83812f67SIngo Weinhold 
6*83812f67SIngo Weinhold #include "String.h"
7*83812f67SIngo Weinhold 
8*83812f67SIngo Weinhold // strnlen
9*83812f67SIngo Weinhold size_t
10*83812f67SIngo Weinhold strnlen(const char *str, size_t maxLen)
11*83812f67SIngo Weinhold {
12*83812f67SIngo Weinhold 	if (str) {
13*83812f67SIngo Weinhold 		size_t origMaxLen = maxLen;
14*83812f67SIngo Weinhold 		while (maxLen > 0 && *str != '\0') {
15*83812f67SIngo Weinhold 			maxLen--;
16*83812f67SIngo Weinhold 			str++;
17*83812f67SIngo Weinhold 		}
18*83812f67SIngo Weinhold 		return origMaxLen - maxLen;
19*83812f67SIngo Weinhold 	}
20*83812f67SIngo Weinhold 	return 0;
21*83812f67SIngo Weinhold }
22*83812f67SIngo Weinhold 
23*83812f67SIngo Weinhold 
24*83812f67SIngo Weinhold /*!
25*83812f67SIngo Weinhold 	\class String
26*83812f67SIngo Weinhold 	\brief A very simple string class.
27*83812f67SIngo Weinhold */
28*83812f67SIngo Weinhold 
29*83812f67SIngo Weinhold // constructor
30*83812f67SIngo Weinhold String::String()
31*83812f67SIngo Weinhold 	: fLength(0),
32*83812f67SIngo Weinhold 	  fString(NULL)
33*83812f67SIngo Weinhold {
34*83812f67SIngo Weinhold }
35*83812f67SIngo Weinhold 
36*83812f67SIngo Weinhold // copy constructor
37*83812f67SIngo Weinhold String::String(const String &string)
38*83812f67SIngo Weinhold 	: fLength(0),
39*83812f67SIngo Weinhold 	  fString(NULL)
40*83812f67SIngo Weinhold {
41*83812f67SIngo Weinhold 	*this = string;
42*83812f67SIngo Weinhold }
43*83812f67SIngo Weinhold 
44*83812f67SIngo Weinhold // constructor
45*83812f67SIngo Weinhold String::String(const char *string, int32 length)
46*83812f67SIngo Weinhold 	: fLength(0),
47*83812f67SIngo Weinhold 	  fString(NULL)
48*83812f67SIngo Weinhold {
49*83812f67SIngo Weinhold 	SetTo(string, length);
50*83812f67SIngo Weinhold }
51*83812f67SIngo Weinhold 
52*83812f67SIngo Weinhold // destructor
53*83812f67SIngo Weinhold String::~String()
54*83812f67SIngo Weinhold {
55*83812f67SIngo Weinhold 	Unset();
56*83812f67SIngo Weinhold }
57*83812f67SIngo Weinhold 
58*83812f67SIngo Weinhold // SetTo
59*83812f67SIngo Weinhold bool
60*83812f67SIngo Weinhold String::SetTo(const char *string, int32 maxLength)
61*83812f67SIngo Weinhold {
62*83812f67SIngo Weinhold 	if (string) {
63*83812f67SIngo Weinhold 		if (maxLength > 0)
64*83812f67SIngo Weinhold 			maxLength = strnlen(string, maxLength);
65*83812f67SIngo Weinhold 		else if (maxLength < 0)
66*83812f67SIngo Weinhold 			maxLength = strlen(string);
67*83812f67SIngo Weinhold 	}
68*83812f67SIngo Weinhold 	return _SetTo(string, maxLength);
69*83812f67SIngo Weinhold }
70*83812f67SIngo Weinhold 
71*83812f67SIngo Weinhold // Unset
72*83812f67SIngo Weinhold void
73*83812f67SIngo Weinhold String::Unset()
74*83812f67SIngo Weinhold {
75*83812f67SIngo Weinhold 	if (fString) {
76*83812f67SIngo Weinhold 		delete[] fString;
77*83812f67SIngo Weinhold 		fString = NULL;
78*83812f67SIngo Weinhold 	}
79*83812f67SIngo Weinhold 	fLength = 0;
80*83812f67SIngo Weinhold }
81*83812f67SIngo Weinhold 
82*83812f67SIngo Weinhold // Truncate
83*83812f67SIngo Weinhold void
84*83812f67SIngo Weinhold String::Truncate(int32 newLength)
85*83812f67SIngo Weinhold {
86*83812f67SIngo Weinhold 	if (newLength < 0)
87*83812f67SIngo Weinhold 		newLength = 0;
88*83812f67SIngo Weinhold 	if (newLength < fLength) {
89*83812f67SIngo Weinhold 		char *string = fString;
90*83812f67SIngo Weinhold 		int32 len = fLength;
91*83812f67SIngo Weinhold 		fString = NULL;
92*83812f67SIngo Weinhold 		len = 0;
93*83812f67SIngo Weinhold 		if (!_SetTo(string, newLength)) {
94*83812f67SIngo Weinhold 			fString = string;
95*83812f67SIngo Weinhold 			fLength = newLength;
96*83812f67SIngo Weinhold 			fString[fLength] = '\0';
97*83812f67SIngo Weinhold 		} else
98*83812f67SIngo Weinhold 			delete[] string;
99*83812f67SIngo Weinhold 	}
100*83812f67SIngo Weinhold }
101*83812f67SIngo Weinhold 
102*83812f67SIngo Weinhold // GetString
103*83812f67SIngo Weinhold const char *
104*83812f67SIngo Weinhold String::GetString() const
105*83812f67SIngo Weinhold {
106*83812f67SIngo Weinhold 	if (fString)
107*83812f67SIngo Weinhold 		return fString;
108*83812f67SIngo Weinhold 	return "";
109*83812f67SIngo Weinhold }
110*83812f67SIngo Weinhold 
111*83812f67SIngo Weinhold // =
112*83812f67SIngo Weinhold String &
113*83812f67SIngo Weinhold String::operator=(const String &string)
114*83812f67SIngo Weinhold {
115*83812f67SIngo Weinhold 	if (&string != this)
116*83812f67SIngo Weinhold 		_SetTo(string.fString, string.fLength);
117*83812f67SIngo Weinhold 	return *this;
118*83812f67SIngo Weinhold }
119*83812f67SIngo Weinhold 
120*83812f67SIngo Weinhold // ==
121*83812f67SIngo Weinhold bool
122*83812f67SIngo Weinhold String::operator==(const String &string) const
123*83812f67SIngo Weinhold {
124*83812f67SIngo Weinhold 	return (fLength == string.fLength
125*83812f67SIngo Weinhold 			&& (fLength == 0 || !strcmp(fString, string.fString)));
126*83812f67SIngo Weinhold }
127*83812f67SIngo Weinhold 
128*83812f67SIngo Weinhold // _SetTo
129*83812f67SIngo Weinhold bool
130*83812f67SIngo Weinhold String::_SetTo(const char *string, int32 length)
131*83812f67SIngo Weinhold {
132*83812f67SIngo Weinhold 	bool result = true;
133*83812f67SIngo Weinhold 	Unset();
134*83812f67SIngo Weinhold 	if (string && length > 0) {
135*83812f67SIngo Weinhold 		fString = new(nothrow) char[length + 1];
136*83812f67SIngo Weinhold 		if (fString) {
137*83812f67SIngo Weinhold 			memcpy(fString, string, length);
138*83812f67SIngo Weinhold 			fString[length] = '\0';
139*83812f67SIngo Weinhold 			fLength = length;
140*83812f67SIngo Weinhold 		} else
141*83812f67SIngo Weinhold 			result = false;
142*83812f67SIngo Weinhold 	}
143*83812f67SIngo Weinhold 	return result;
144*83812f67SIngo Weinhold }
145*83812f67SIngo Weinhold 
146