1*66c7a2acSAugustin Cavalier /*
2*66c7a2acSAugustin Cavalier * Copyright 2004-2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3*66c7a2acSAugustin Cavalier * Copyright 2008-2017, Axel Dörfler, axeld@pinc-software.de.
4*66c7a2acSAugustin Cavalier * Distributed under the terms of the MIT License.
5*66c7a2acSAugustin Cavalier */
6*66c7a2acSAugustin Cavalier
7*66c7a2acSAugustin Cavalier
8*66c7a2acSAugustin Cavalier /*! A simple class wrapping a path. Has a fixed-sized buffer. */
9*66c7a2acSAugustin Cavalier
10*66c7a2acSAugustin Cavalier
11*66c7a2acSAugustin Cavalier #include <fs/KPath.h>
12*66c7a2acSAugustin Cavalier #include <Path.h>
13*66c7a2acSAugustin Cavalier
14*66c7a2acSAugustin Cavalier #include <stdlib.h>
15*66c7a2acSAugustin Cavalier #include <string.h>
16*66c7a2acSAugustin Cavalier
17*66c7a2acSAugustin Cavalier #include <team.h>
18*66c7a2acSAugustin Cavalier
19*66c7a2acSAugustin Cavalier
20*66c7a2acSAugustin Cavalier // debugging
21*66c7a2acSAugustin Cavalier #define TRACE(x) ;
22*66c7a2acSAugustin Cavalier //#define TRACE(x) dprintf x
23*66c7a2acSAugustin Cavalier
24*66c7a2acSAugustin Cavalier
KPath(size_t bufferSize)25*66c7a2acSAugustin Cavalier KPath::KPath(size_t bufferSize)
26*66c7a2acSAugustin Cavalier :
27*66c7a2acSAugustin Cavalier fBuffer(NULL),
28*66c7a2acSAugustin Cavalier fBufferSize(0),
29*66c7a2acSAugustin Cavalier fPathLength(0),
30*66c7a2acSAugustin Cavalier fLocked(false),
31*66c7a2acSAugustin Cavalier fLazy(false),
32*66c7a2acSAugustin Cavalier fFailed(false),
33*66c7a2acSAugustin Cavalier fIsNull(false)
34*66c7a2acSAugustin Cavalier {
35*66c7a2acSAugustin Cavalier SetTo(NULL, DEFAULT, bufferSize);
36*66c7a2acSAugustin Cavalier }
37*66c7a2acSAugustin Cavalier
38*66c7a2acSAugustin Cavalier
KPath(const char * path,int32 flags,size_t bufferSize)39*66c7a2acSAugustin Cavalier KPath::KPath(const char* path, int32 flags, size_t bufferSize)
40*66c7a2acSAugustin Cavalier :
41*66c7a2acSAugustin Cavalier fBuffer(NULL),
42*66c7a2acSAugustin Cavalier fBufferSize(0),
43*66c7a2acSAugustin Cavalier fPathLength(0),
44*66c7a2acSAugustin Cavalier fLocked(false),
45*66c7a2acSAugustin Cavalier fLazy(false),
46*66c7a2acSAugustin Cavalier fFailed(false),
47*66c7a2acSAugustin Cavalier fIsNull(false)
48*66c7a2acSAugustin Cavalier {
49*66c7a2acSAugustin Cavalier SetTo(path, flags, bufferSize);
50*66c7a2acSAugustin Cavalier }
51*66c7a2acSAugustin Cavalier
52*66c7a2acSAugustin Cavalier
KPath(const KPath & other)53*66c7a2acSAugustin Cavalier KPath::KPath(const KPath& other)
54*66c7a2acSAugustin Cavalier :
55*66c7a2acSAugustin Cavalier fBuffer(NULL),
56*66c7a2acSAugustin Cavalier fBufferSize(0),
57*66c7a2acSAugustin Cavalier fPathLength(0),
58*66c7a2acSAugustin Cavalier fLocked(false),
59*66c7a2acSAugustin Cavalier fLazy(false),
60*66c7a2acSAugustin Cavalier fFailed(false),
61*66c7a2acSAugustin Cavalier fIsNull(false)
62*66c7a2acSAugustin Cavalier {
63*66c7a2acSAugustin Cavalier *this = other;
64*66c7a2acSAugustin Cavalier }
65*66c7a2acSAugustin Cavalier
66*66c7a2acSAugustin Cavalier
~KPath()67*66c7a2acSAugustin Cavalier KPath::~KPath()
68*66c7a2acSAugustin Cavalier {
69*66c7a2acSAugustin Cavalier free(fBuffer);
70*66c7a2acSAugustin Cavalier }
71*66c7a2acSAugustin Cavalier
72*66c7a2acSAugustin Cavalier
73*66c7a2acSAugustin Cavalier status_t
SetTo(const char * path,int32 flags,size_t bufferSize)74*66c7a2acSAugustin Cavalier KPath::SetTo(const char* path, int32 flags, size_t bufferSize)
75*66c7a2acSAugustin Cavalier {
76*66c7a2acSAugustin Cavalier if (bufferSize == 0)
77*66c7a2acSAugustin Cavalier bufferSize = B_PATH_NAME_LENGTH;
78*66c7a2acSAugustin Cavalier
79*66c7a2acSAugustin Cavalier // free the previous buffer, if the buffer size differs
80*66c7a2acSAugustin Cavalier if (fBuffer != NULL && fBufferSize != bufferSize) {
81*66c7a2acSAugustin Cavalier free(fBuffer);
82*66c7a2acSAugustin Cavalier fBuffer = NULL;
83*66c7a2acSAugustin Cavalier fBufferSize = 0;
84*66c7a2acSAugustin Cavalier }
85*66c7a2acSAugustin Cavalier
86*66c7a2acSAugustin Cavalier fPathLength = 0;
87*66c7a2acSAugustin Cavalier fLocked = false;
88*66c7a2acSAugustin Cavalier fBufferSize = bufferSize;
89*66c7a2acSAugustin Cavalier fLazy = (flags & LAZY_ALLOC) != 0;
90*66c7a2acSAugustin Cavalier fIsNull = path == NULL;
91*66c7a2acSAugustin Cavalier
92*66c7a2acSAugustin Cavalier if (path != NULL || !fLazy) {
93*66c7a2acSAugustin Cavalier status_t status = _AllocateBuffer();
94*66c7a2acSAugustin Cavalier if (status != B_OK)
95*66c7a2acSAugustin Cavalier return status;
96*66c7a2acSAugustin Cavalier }
97*66c7a2acSAugustin Cavalier
98*66c7a2acSAugustin Cavalier return SetPath(path, flags);
99*66c7a2acSAugustin Cavalier }
100*66c7a2acSAugustin Cavalier
101*66c7a2acSAugustin Cavalier
102*66c7a2acSAugustin Cavalier void
Adopt(KPath & other)103*66c7a2acSAugustin Cavalier KPath::Adopt(KPath& other)
104*66c7a2acSAugustin Cavalier {
105*66c7a2acSAugustin Cavalier free(fBuffer);
106*66c7a2acSAugustin Cavalier
107*66c7a2acSAugustin Cavalier fBuffer = other.fBuffer;
108*66c7a2acSAugustin Cavalier fBufferSize = other.fBufferSize;
109*66c7a2acSAugustin Cavalier fPathLength = other.fPathLength;
110*66c7a2acSAugustin Cavalier fLazy = other.fLazy;
111*66c7a2acSAugustin Cavalier fFailed = other.fFailed;
112*66c7a2acSAugustin Cavalier fIsNull = other.fIsNull;
113*66c7a2acSAugustin Cavalier
114*66c7a2acSAugustin Cavalier other.fBuffer = NULL;
115*66c7a2acSAugustin Cavalier if (!other.fLazy)
116*66c7a2acSAugustin Cavalier other.fBufferSize = 0;
117*66c7a2acSAugustin Cavalier other.fPathLength = 0;
118*66c7a2acSAugustin Cavalier other.fFailed = false;
119*66c7a2acSAugustin Cavalier other.fIsNull = other.fLazy;
120*66c7a2acSAugustin Cavalier }
121*66c7a2acSAugustin Cavalier
122*66c7a2acSAugustin Cavalier
123*66c7a2acSAugustin Cavalier status_t
InitCheck() const124*66c7a2acSAugustin Cavalier KPath::InitCheck() const
125*66c7a2acSAugustin Cavalier {
126*66c7a2acSAugustin Cavalier if (fBuffer != NULL || (fLazy && !fFailed && fBufferSize != 0))
127*66c7a2acSAugustin Cavalier return B_OK;
128*66c7a2acSAugustin Cavalier
129*66c7a2acSAugustin Cavalier return fFailed ? B_NO_MEMORY : B_NO_INIT;
130*66c7a2acSAugustin Cavalier }
131*66c7a2acSAugustin Cavalier
132*66c7a2acSAugustin Cavalier
133*66c7a2acSAugustin Cavalier /*! \brief Sets the buffer to \a path.
134*66c7a2acSAugustin Cavalier
135*66c7a2acSAugustin Cavalier \param flags Understands the following two options:
136*66c7a2acSAugustin Cavalier - \c NORMALIZE
137*66c7a2acSAugustin Cavalier - \c TRAVERSE_LEAF_LINK
138*66c7a2acSAugustin Cavalier */
139*66c7a2acSAugustin Cavalier status_t
SetPath(const char * path,int32 flags)140*66c7a2acSAugustin Cavalier KPath::SetPath(const char* path, int32 flags)
141*66c7a2acSAugustin Cavalier {
142*66c7a2acSAugustin Cavalier if (path == NULL && fLazy && fBuffer == NULL) {
143*66c7a2acSAugustin Cavalier fIsNull = true;
144*66c7a2acSAugustin Cavalier return B_OK;
145*66c7a2acSAugustin Cavalier }
146*66c7a2acSAugustin Cavalier
147*66c7a2acSAugustin Cavalier if (fBuffer == NULL) {
148*66c7a2acSAugustin Cavalier if (fLazy) {
149*66c7a2acSAugustin Cavalier status_t status = _AllocateBuffer();
150*66c7a2acSAugustin Cavalier if (status != B_OK)
151*66c7a2acSAugustin Cavalier return B_NO_MEMORY;
152*66c7a2acSAugustin Cavalier } else
153*66c7a2acSAugustin Cavalier return B_NO_INIT;
154*66c7a2acSAugustin Cavalier }
155*66c7a2acSAugustin Cavalier
156*66c7a2acSAugustin Cavalier fIsNull = false;
157*66c7a2acSAugustin Cavalier
158*66c7a2acSAugustin Cavalier if (path != NULL) {
159*66c7a2acSAugustin Cavalier if ((flags & NORMALIZE) != 0) {
160*66c7a2acSAugustin Cavalier // normalize path
161*66c7a2acSAugustin Cavalier status_t status = _Normalize(path,
162*66c7a2acSAugustin Cavalier (flags & TRAVERSE_LEAF_LINK) != 0);
163*66c7a2acSAugustin Cavalier if (status != B_OK)
164*66c7a2acSAugustin Cavalier return status;
165*66c7a2acSAugustin Cavalier } else {
166*66c7a2acSAugustin Cavalier // don't normalize path
167*66c7a2acSAugustin Cavalier size_t length = strlen(path);
168*66c7a2acSAugustin Cavalier if (length >= fBufferSize)
169*66c7a2acSAugustin Cavalier return B_BUFFER_OVERFLOW;
170*66c7a2acSAugustin Cavalier
171*66c7a2acSAugustin Cavalier memcpy(fBuffer, path, length + 1);
172*66c7a2acSAugustin Cavalier fPathLength = length;
173*66c7a2acSAugustin Cavalier _ChopTrailingSlashes();
174*66c7a2acSAugustin Cavalier }
175*66c7a2acSAugustin Cavalier } else {
176*66c7a2acSAugustin Cavalier fBuffer[0] = '\0';
177*66c7a2acSAugustin Cavalier fPathLength = 0;
178*66c7a2acSAugustin Cavalier if (fLazy)
179*66c7a2acSAugustin Cavalier fIsNull = true;
180*66c7a2acSAugustin Cavalier }
181*66c7a2acSAugustin Cavalier return B_OK;
182*66c7a2acSAugustin Cavalier }
183*66c7a2acSAugustin Cavalier
184*66c7a2acSAugustin Cavalier
185*66c7a2acSAugustin Cavalier const char*
Path() const186*66c7a2acSAugustin Cavalier KPath::Path() const
187*66c7a2acSAugustin Cavalier {
188*66c7a2acSAugustin Cavalier return fIsNull ? NULL : fBuffer;
189*66c7a2acSAugustin Cavalier }
190*66c7a2acSAugustin Cavalier
191*66c7a2acSAugustin Cavalier
192*66c7a2acSAugustin Cavalier /*! \brief Locks the buffer for external changes.
193*66c7a2acSAugustin Cavalier
194*66c7a2acSAugustin Cavalier \param force In lazy mode, this will allocate a buffer when set.
195*66c7a2acSAugustin Cavalier Otherwise, \c NULL will be returned if set to NULL.
196*66c7a2acSAugustin Cavalier */
197*66c7a2acSAugustin Cavalier char*
LockBuffer(bool force)198*66c7a2acSAugustin Cavalier KPath::LockBuffer(bool force)
199*66c7a2acSAugustin Cavalier {
200*66c7a2acSAugustin Cavalier if (fBuffer == NULL && fLazy) {
201*66c7a2acSAugustin Cavalier if (fIsNull && !force)
202*66c7a2acSAugustin Cavalier return NULL;
203*66c7a2acSAugustin Cavalier
204*66c7a2acSAugustin Cavalier _AllocateBuffer();
205*66c7a2acSAugustin Cavalier }
206*66c7a2acSAugustin Cavalier
207*66c7a2acSAugustin Cavalier if (fBuffer == NULL || fLocked)
208*66c7a2acSAugustin Cavalier return NULL;
209*66c7a2acSAugustin Cavalier
210*66c7a2acSAugustin Cavalier fLocked = true;
211*66c7a2acSAugustin Cavalier fIsNull = false;
212*66c7a2acSAugustin Cavalier
213*66c7a2acSAugustin Cavalier return fBuffer;
214*66c7a2acSAugustin Cavalier }
215*66c7a2acSAugustin Cavalier
216*66c7a2acSAugustin Cavalier
217*66c7a2acSAugustin Cavalier void
UnlockBuffer()218*66c7a2acSAugustin Cavalier KPath::UnlockBuffer()
219*66c7a2acSAugustin Cavalier {
220*66c7a2acSAugustin Cavalier if (!fLocked) {
221*66c7a2acSAugustin Cavalier TRACE(("KPath::UnlockBuffer(): ERROR: Buffer not locked!\n"));
222*66c7a2acSAugustin Cavalier return;
223*66c7a2acSAugustin Cavalier }
224*66c7a2acSAugustin Cavalier
225*66c7a2acSAugustin Cavalier fLocked = false;
226*66c7a2acSAugustin Cavalier
227*66c7a2acSAugustin Cavalier if (fBuffer == NULL)
228*66c7a2acSAugustin Cavalier return;
229*66c7a2acSAugustin Cavalier
230*66c7a2acSAugustin Cavalier fPathLength = strnlen(fBuffer, fBufferSize);
231*66c7a2acSAugustin Cavalier if (fPathLength == fBufferSize) {
232*66c7a2acSAugustin Cavalier TRACE(("KPath::UnlockBuffer(): WARNING: Unterminated buffer!\n"));
233*66c7a2acSAugustin Cavalier fPathLength--;
234*66c7a2acSAugustin Cavalier fBuffer[fPathLength] = '\0';
235*66c7a2acSAugustin Cavalier }
236*66c7a2acSAugustin Cavalier _ChopTrailingSlashes();
237*66c7a2acSAugustin Cavalier }
238*66c7a2acSAugustin Cavalier
239*66c7a2acSAugustin Cavalier
240*66c7a2acSAugustin Cavalier char*
DetachBuffer()241*66c7a2acSAugustin Cavalier KPath::DetachBuffer()
242*66c7a2acSAugustin Cavalier {
243*66c7a2acSAugustin Cavalier char* buffer = fBuffer;
244*66c7a2acSAugustin Cavalier
245*66c7a2acSAugustin Cavalier if (fBuffer != NULL) {
246*66c7a2acSAugustin Cavalier fBuffer = NULL;
247*66c7a2acSAugustin Cavalier fPathLength = 0;
248*66c7a2acSAugustin Cavalier fLocked = false;
249*66c7a2acSAugustin Cavalier }
250*66c7a2acSAugustin Cavalier
251*66c7a2acSAugustin Cavalier return buffer;
252*66c7a2acSAugustin Cavalier }
253*66c7a2acSAugustin Cavalier
254*66c7a2acSAugustin Cavalier
255*66c7a2acSAugustin Cavalier const char*
Leaf() const256*66c7a2acSAugustin Cavalier KPath::Leaf() const
257*66c7a2acSAugustin Cavalier {
258*66c7a2acSAugustin Cavalier if (fBuffer == NULL)
259*66c7a2acSAugustin Cavalier return NULL;
260*66c7a2acSAugustin Cavalier
261*66c7a2acSAugustin Cavalier for (int32 i = fPathLength - 1; i >= 0; i--) {
262*66c7a2acSAugustin Cavalier if (fBuffer[i] == '/')
263*66c7a2acSAugustin Cavalier return fBuffer + i + 1;
264*66c7a2acSAugustin Cavalier }
265*66c7a2acSAugustin Cavalier
266*66c7a2acSAugustin Cavalier return fBuffer;
267*66c7a2acSAugustin Cavalier }
268*66c7a2acSAugustin Cavalier
269*66c7a2acSAugustin Cavalier
270*66c7a2acSAugustin Cavalier status_t
ReplaceLeaf(const char * newLeaf)271*66c7a2acSAugustin Cavalier KPath::ReplaceLeaf(const char* newLeaf)
272*66c7a2acSAugustin Cavalier {
273*66c7a2acSAugustin Cavalier const char* leaf = Leaf();
274*66c7a2acSAugustin Cavalier if (leaf == NULL)
275*66c7a2acSAugustin Cavalier return B_NO_INIT;
276*66c7a2acSAugustin Cavalier
277*66c7a2acSAugustin Cavalier int32 leafIndex = leaf - fBuffer;
278*66c7a2acSAugustin Cavalier // chop off the current leaf (don't replace "/", though)
279*66c7a2acSAugustin Cavalier if (leafIndex != 0 || fBuffer[leafIndex - 1]) {
280*66c7a2acSAugustin Cavalier fBuffer[leafIndex] = '\0';
281*66c7a2acSAugustin Cavalier fPathLength = leafIndex;
282*66c7a2acSAugustin Cavalier _ChopTrailingSlashes();
283*66c7a2acSAugustin Cavalier }
284*66c7a2acSAugustin Cavalier
285*66c7a2acSAugustin Cavalier // if a leaf was given, append it
286*66c7a2acSAugustin Cavalier if (newLeaf != NULL)
287*66c7a2acSAugustin Cavalier return Append(newLeaf);
288*66c7a2acSAugustin Cavalier return B_OK;
289*66c7a2acSAugustin Cavalier }
290*66c7a2acSAugustin Cavalier
291*66c7a2acSAugustin Cavalier
292*66c7a2acSAugustin Cavalier bool
RemoveLeaf()293*66c7a2acSAugustin Cavalier KPath::RemoveLeaf()
294*66c7a2acSAugustin Cavalier {
295*66c7a2acSAugustin Cavalier // get the leaf -- bail out, if not initialized or only the "/" is left
296*66c7a2acSAugustin Cavalier const char* leaf = Leaf();
297*66c7a2acSAugustin Cavalier if (leaf == NULL || leaf == fBuffer || leaf[0] == '\0')
298*66c7a2acSAugustin Cavalier return false;
299*66c7a2acSAugustin Cavalier
300*66c7a2acSAugustin Cavalier // chop off the leaf
301*66c7a2acSAugustin Cavalier int32 leafIndex = leaf - fBuffer;
302*66c7a2acSAugustin Cavalier fBuffer[leafIndex] = '\0';
303*66c7a2acSAugustin Cavalier fPathLength = leafIndex;
304*66c7a2acSAugustin Cavalier _ChopTrailingSlashes();
305*66c7a2acSAugustin Cavalier
306*66c7a2acSAugustin Cavalier return true;
307*66c7a2acSAugustin Cavalier }
308*66c7a2acSAugustin Cavalier
309*66c7a2acSAugustin Cavalier
310*66c7a2acSAugustin Cavalier status_t
Append(const char * component,bool isComponent)311*66c7a2acSAugustin Cavalier KPath::Append(const char* component, bool isComponent)
312*66c7a2acSAugustin Cavalier {
313*66c7a2acSAugustin Cavalier // check initialization and parameter
314*66c7a2acSAugustin Cavalier if (fBuffer == NULL)
315*66c7a2acSAugustin Cavalier return B_NO_INIT;
316*66c7a2acSAugustin Cavalier if (component == NULL)
317*66c7a2acSAugustin Cavalier return B_BAD_VALUE;
318*66c7a2acSAugustin Cavalier if (fPathLength == 0)
319*66c7a2acSAugustin Cavalier return SetPath(component);
320*66c7a2acSAugustin Cavalier
321*66c7a2acSAugustin Cavalier // get component length
322*66c7a2acSAugustin Cavalier size_t componentLength = strlen(component);
323*66c7a2acSAugustin Cavalier if (componentLength < 1)
324*66c7a2acSAugustin Cavalier return B_OK;
325*66c7a2acSAugustin Cavalier
326*66c7a2acSAugustin Cavalier // if our current path is empty, we just copy the supplied one
327*66c7a2acSAugustin Cavalier // compute the result path len
328*66c7a2acSAugustin Cavalier bool insertSlash = isComponent && fBuffer[fPathLength - 1] != '/'
329*66c7a2acSAugustin Cavalier && component[0] != '/';
330*66c7a2acSAugustin Cavalier size_t resultPathLength = fPathLength + componentLength
331*66c7a2acSAugustin Cavalier + (insertSlash ? 1 : 0);
332*66c7a2acSAugustin Cavalier if (resultPathLength >= fBufferSize)
333*66c7a2acSAugustin Cavalier return B_BUFFER_OVERFLOW;
334*66c7a2acSAugustin Cavalier
335*66c7a2acSAugustin Cavalier // compose the result path
336*66c7a2acSAugustin Cavalier if (insertSlash)
337*66c7a2acSAugustin Cavalier fBuffer[fPathLength++] = '/';
338*66c7a2acSAugustin Cavalier memcpy(fBuffer + fPathLength, component, componentLength + 1);
339*66c7a2acSAugustin Cavalier fPathLength = resultPathLength;
340*66c7a2acSAugustin Cavalier return B_OK;
341*66c7a2acSAugustin Cavalier }
342*66c7a2acSAugustin Cavalier
343*66c7a2acSAugustin Cavalier
344*66c7a2acSAugustin Cavalier status_t
Normalize(bool traverseLeafLink)345*66c7a2acSAugustin Cavalier KPath::Normalize(bool traverseLeafLink)
346*66c7a2acSAugustin Cavalier {
347*66c7a2acSAugustin Cavalier if (fBuffer == NULL)
348*66c7a2acSAugustin Cavalier return B_NO_INIT;
349*66c7a2acSAugustin Cavalier if (fPathLength == 0)
350*66c7a2acSAugustin Cavalier return B_BAD_VALUE;
351*66c7a2acSAugustin Cavalier
352*66c7a2acSAugustin Cavalier return _Normalize(fBuffer, traverseLeafLink);
353*66c7a2acSAugustin Cavalier }
354*66c7a2acSAugustin Cavalier
355*66c7a2acSAugustin Cavalier
356*66c7a2acSAugustin Cavalier KPath&
operator =(const KPath & other)357*66c7a2acSAugustin Cavalier KPath::operator=(const KPath& other)
358*66c7a2acSAugustin Cavalier {
359*66c7a2acSAugustin Cavalier SetTo(other.fBuffer, fLazy ? KPath::LAZY_ALLOC : KPath::DEFAULT,
360*66c7a2acSAugustin Cavalier other.fBufferSize);
361*66c7a2acSAugustin Cavalier return *this;
362*66c7a2acSAugustin Cavalier }
363*66c7a2acSAugustin Cavalier
364*66c7a2acSAugustin Cavalier
365*66c7a2acSAugustin Cavalier KPath&
operator =(const char * path)366*66c7a2acSAugustin Cavalier KPath::operator=(const char* path)
367*66c7a2acSAugustin Cavalier {
368*66c7a2acSAugustin Cavalier SetPath(path);
369*66c7a2acSAugustin Cavalier return *this;
370*66c7a2acSAugustin Cavalier }
371*66c7a2acSAugustin Cavalier
372*66c7a2acSAugustin Cavalier
373*66c7a2acSAugustin Cavalier bool
operator ==(const KPath & other) const374*66c7a2acSAugustin Cavalier KPath::operator==(const KPath& other) const
375*66c7a2acSAugustin Cavalier {
376*66c7a2acSAugustin Cavalier if (fBuffer == NULL)
377*66c7a2acSAugustin Cavalier return !other.fBuffer;
378*66c7a2acSAugustin Cavalier
379*66c7a2acSAugustin Cavalier return other.fBuffer != NULL
380*66c7a2acSAugustin Cavalier && fPathLength == other.fPathLength
381*66c7a2acSAugustin Cavalier && strcmp(fBuffer, other.fBuffer) == 0;
382*66c7a2acSAugustin Cavalier }
383*66c7a2acSAugustin Cavalier
384*66c7a2acSAugustin Cavalier
385*66c7a2acSAugustin Cavalier bool
operator ==(const char * path) const386*66c7a2acSAugustin Cavalier KPath::operator==(const char* path) const
387*66c7a2acSAugustin Cavalier {
388*66c7a2acSAugustin Cavalier if (fBuffer == NULL)
389*66c7a2acSAugustin Cavalier return path == NULL;
390*66c7a2acSAugustin Cavalier
391*66c7a2acSAugustin Cavalier return path != NULL && strcmp(fBuffer, path) == 0;
392*66c7a2acSAugustin Cavalier }
393*66c7a2acSAugustin Cavalier
394*66c7a2acSAugustin Cavalier
395*66c7a2acSAugustin Cavalier bool
operator !=(const KPath & other) const396*66c7a2acSAugustin Cavalier KPath::operator!=(const KPath& other) const
397*66c7a2acSAugustin Cavalier {
398*66c7a2acSAugustin Cavalier return !(*this == other);
399*66c7a2acSAugustin Cavalier }
400*66c7a2acSAugustin Cavalier
401*66c7a2acSAugustin Cavalier
402*66c7a2acSAugustin Cavalier bool
operator !=(const char * path) const403*66c7a2acSAugustin Cavalier KPath::operator!=(const char* path) const
404*66c7a2acSAugustin Cavalier {
405*66c7a2acSAugustin Cavalier return !(*this == path);
406*66c7a2acSAugustin Cavalier }
407*66c7a2acSAugustin Cavalier
408*66c7a2acSAugustin Cavalier
409*66c7a2acSAugustin Cavalier status_t
_AllocateBuffer()410*66c7a2acSAugustin Cavalier KPath::_AllocateBuffer()
411*66c7a2acSAugustin Cavalier {
412*66c7a2acSAugustin Cavalier if (fBuffer == NULL && fBufferSize != 0)
413*66c7a2acSAugustin Cavalier fBuffer = (char*)malloc(fBufferSize);
414*66c7a2acSAugustin Cavalier if (fBuffer == NULL) {
415*66c7a2acSAugustin Cavalier fFailed = true;
416*66c7a2acSAugustin Cavalier return B_NO_MEMORY;
417*66c7a2acSAugustin Cavalier }
418*66c7a2acSAugustin Cavalier
419*66c7a2acSAugustin Cavalier fBuffer[0] = '\0';
420*66c7a2acSAugustin Cavalier fFailed = false;
421*66c7a2acSAugustin Cavalier return B_OK;
422*66c7a2acSAugustin Cavalier }
423*66c7a2acSAugustin Cavalier
424*66c7a2acSAugustin Cavalier
425*66c7a2acSAugustin Cavalier status_t
_Normalize(const char * path,bool traverseLeafLink)426*66c7a2acSAugustin Cavalier KPath::_Normalize(const char* path, bool traverseLeafLink)
427*66c7a2acSAugustin Cavalier {
428*66c7a2acSAugustin Cavalier BPath normalizedPath;
429*66c7a2acSAugustin Cavalier status_t error = normalizedPath.SetTo(path, NULL, true);
430*66c7a2acSAugustin Cavalier if (error != B_OK) {
431*66c7a2acSAugustin Cavalier fBuffer[0] = '\0';
432*66c7a2acSAugustin Cavalier fPathLength = 0;
433*66c7a2acSAugustin Cavalier return error;
434*66c7a2acSAugustin Cavalier }
435*66c7a2acSAugustin Cavalier
436*66c7a2acSAugustin Cavalier strlcpy(fBuffer, normalizedPath.Path(), fBufferSize);
437*66c7a2acSAugustin Cavalier fPathLength = strlen(fBuffer);
438*66c7a2acSAugustin Cavalier return B_OK;
439*66c7a2acSAugustin Cavalier }
440*66c7a2acSAugustin Cavalier
441*66c7a2acSAugustin Cavalier
442*66c7a2acSAugustin Cavalier void
_ChopTrailingSlashes()443*66c7a2acSAugustin Cavalier KPath::_ChopTrailingSlashes()
444*66c7a2acSAugustin Cavalier {
445*66c7a2acSAugustin Cavalier if (fBuffer != NULL) {
446*66c7a2acSAugustin Cavalier while (fPathLength > 1 && fBuffer[fPathLength - 1] == '/')
447*66c7a2acSAugustin Cavalier fBuffer[--fPathLength] = '\0';
448*66c7a2acSAugustin Cavalier }
449*66c7a2acSAugustin Cavalier }
450*66c7a2acSAugustin Cavalier
451