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 11 Path::Path() 12 : fBuffer(NULL), 13 fBufferSize(0), 14 fLength(0) 15 { 16 } 17 18 // destructor 19 Path::~Path() 20 { 21 free(fBuffer); 22 } 23 24 // SetTo 25 status_t 26 Path::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 69 status_t 70 Path::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 105 const char* 106 Path::GetPath() const 107 { 108 return (fLength == 0 ? NULL : fBuffer); 109 } 110 111 // GetLength 112 int32 113 Path::GetLength() const 114 { 115 return fLength; 116 } 117 118 // _Resize 119 status_t 120 Path::_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