1// Path.cpp 2 3#include <stdlib.h> 4#include <string.h> 5 6#include <StorageDefs.h> 7 8#include "Path.h" 9 10// constructor 11Path::Path() 12 : fBuffer(NULL), 13 fBufferSize(0), 14 fLength(0) 15{ 16} 17 18// destructor 19Path::~Path() 20{ 21 free(fBuffer); 22} 23 24// SetTo 25status_t 26Path::SetTo(const char* path, const char* leaf) 27{ 28 if (!path) 29 return B_BAD_VALUE; 30 31 // get the base path len 32 int32 len = strlen(path); 33 if (len == 0) 34 return B_BAD_VALUE; 35 36 // get leaf len and check, if a separator needs to be inserted 37 bool insertSeparator = false; 38 int32 leafLen = 0; 39 if (leaf) { 40 leafLen = strlen(leaf); 41 if (leafLen > 0) 42 insertSeparator = (path[len - 1] != '/' && leaf[0] != '/'); 43 } 44 45 // compute the resulting length and resize the buffer 46 int32 wholeLen = len + leafLen + (insertSeparator ? 1 : 0); 47 status_t error = _Resize(wholeLen + 1); 48 if (error != B_OK) 49 return error; 50 51 // copy path 52 memcpy(fBuffer, path, len); 53 54 // insert separator 55 if (insertSeparator) 56 fBuffer[len++] = '/'; 57 58 // append leaf 59 if (leafLen > 0) 60 memcpy(fBuffer + len, leaf, leafLen); 61 62 // null terminate 63 fBuffer[wholeLen] = '\0'; 64 fLength = wholeLen; 65 return B_OK; 66} 67 68// Append 69status_t 70Path::Append(const char* leaf) 71{ 72 if (!leaf) 73 return B_BAD_VALUE; 74 75 if (fLength == 0) 76 return SetTo(leaf); 77 78 // get the leaf len 79 int32 leafLen = strlen(leaf); 80 if (leafLen == 0) 81 return B_BAD_VALUE; 82 83 // check, if we need a separator 84 bool insertSeparator = (fBuffer[fLength - 1] != '/' && leaf[0] != '/'); 85 86 // compute the resulting length and resize the buffer 87 int32 wholeLen = fLength + leafLen + (insertSeparator ? 1 : 0); 88 status_t error = _Resize(wholeLen + 1); 89 if (error != B_OK) 90 return error; 91 92 // insert separator 93 if (insertSeparator) 94 fBuffer[fLength++] = '/'; 95 96 // append leaf 97 if (leafLen > 0) 98 memcpy(fBuffer + fLength, leaf, leafLen + 1); 99 100 fLength = wholeLen; 101 return B_OK; 102} 103 104// GetPath 105const char* 106Path::GetPath() const 107{ 108 return (fLength == 0 ? NULL : fBuffer); 109} 110 111// GetLength 112int32 113Path::GetLength() const 114{ 115 return fLength; 116} 117 118// _Resize 119status_t 120Path::_Resize(int32 minLen) 121{ 122 // align to multiples of B_PATH_NAME_LENGTH 123 minLen = (minLen + B_PATH_NAME_LENGTH - 1) 124 / B_PATH_NAME_LENGTH * B_PATH_NAME_LENGTH; 125 126 if (minLen != fBufferSize) { 127 char* buffer = (char*)realloc(fBuffer, minLen); 128 if (!buffer) 129 return B_NO_MEMORY; 130 131 fBuffer = buffer; 132 fBufferSize = minLen; 133 } 134 135 return B_OK; 136} 137