Added class KPath. Convenient wrapper for a fixed-sized path buffer.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9541 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
42b568aeb5
commit
d68a188e6d
54
headers/private/kernel/fs/KPath.h
Normal file
54
headers/private/kernel/fs/KPath.h
Normal file
@ -0,0 +1,54 @@
|
||||
// KPath.h
|
||||
//
|
||||
// A simple class wrapping a path. Has a fixed-sized buffer.
|
||||
|
||||
#ifndef _K_PATH_H
|
||||
#define _K_PATH_H
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
class KPath {
|
||||
public:
|
||||
KPath(int32 bufferSize = B_PATH_NAME_LENGTH);
|
||||
KPath(const char* path, int32 bufferSize = B_PATH_NAME_LENGTH);
|
||||
KPath(const KPath& other);
|
||||
~KPath();
|
||||
|
||||
status_t SetTo(const char *path, int32 bufferSize = B_PATH_NAME_LENGTH);
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
status_t SetPath(const char *path);
|
||||
const char* Path() const;
|
||||
int32 Length() const;
|
||||
|
||||
int32 BufferSize() const;
|
||||
char *LockBuffer();
|
||||
void UnlockBuffer();
|
||||
|
||||
status_t Append(const char *component);
|
||||
|
||||
KPath& operator=(const KPath& other);
|
||||
KPath& operator=(const char* path);
|
||||
|
||||
bool operator==(const KPath& other) const;
|
||||
bool operator==(const char* path) const;
|
||||
bool operator!=(const KPath& other) const;
|
||||
bool operator!=(const char* path) const;
|
||||
|
||||
private:
|
||||
char* fBuffer;
|
||||
int32 fBufferSize;
|
||||
int32 fPathLength;
|
||||
bool fLocked;
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KPath;
|
||||
|
||||
#endif _K_PATH_H
|
233
src/kernel/core/fs/KPath.cpp
Normal file
233
src/kernel/core/fs/KPath.cpp
Normal file
@ -0,0 +1,233 @@
|
||||
// KPath.cpp
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <KPath.h>
|
||||
|
||||
// debugging
|
||||
#define DBG(x)
|
||||
//#define DBG(x) x
|
||||
#define OUT dprintf
|
||||
|
||||
// constructor
|
||||
KPath::KPath(int32 bufferSize)
|
||||
: fBuffer(NULL),
|
||||
fBufferSize(0),
|
||||
fPathLength(0),
|
||||
fLocked(false)
|
||||
{
|
||||
SetTo(NULL, bufferSize);
|
||||
}
|
||||
|
||||
// constructor
|
||||
KPath::KPath(const char* path, int32 bufferSize)
|
||||
: fBuffer(NULL),
|
||||
fBufferSize(0),
|
||||
fPathLength(0),
|
||||
fLocked(false)
|
||||
{
|
||||
SetTo(path, bufferSize);
|
||||
}
|
||||
|
||||
// copy constructor
|
||||
KPath::KPath(const KPath& other)
|
||||
: fBuffer(NULL),
|
||||
fBufferSize(0),
|
||||
fPathLength(0),
|
||||
fLocked(false)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
// destructor
|
||||
KPath::~KPath()
|
||||
{
|
||||
free(fBuffer);
|
||||
}
|
||||
|
||||
// SetTo
|
||||
status_t
|
||||
KPath::SetTo(const char* path, int32 bufferSize)
|
||||
{
|
||||
if (bufferSize <= 0)
|
||||
bufferSize = B_PATH_NAME_LENGTH;
|
||||
// free the previous buffer, if the buffer size differs
|
||||
if (fBuffer && fBufferSize != bufferSize) {
|
||||
free(fBuffer);
|
||||
fBuffer = NULL;
|
||||
fBufferSize = 0;
|
||||
}
|
||||
fPathLength = 0;
|
||||
fLocked = false;
|
||||
// allocate buffer
|
||||
if (!fBuffer)
|
||||
fBuffer = (char*)malloc(bufferSize);
|
||||
if (!fBuffer)
|
||||
return B_NO_MEMORY;
|
||||
if (fBuffer) {
|
||||
fBufferSize = bufferSize;
|
||||
fBuffer[0] = '\0';
|
||||
}
|
||||
return SetPath(path);
|
||||
}
|
||||
|
||||
// InitCheck
|
||||
status_t
|
||||
KPath::InitCheck() const
|
||||
{
|
||||
return (fBuffer ? B_OK : B_NO_MEMORY);
|
||||
}
|
||||
|
||||
// SetPath
|
||||
status_t
|
||||
KPath::SetPath(const char *path)
|
||||
{
|
||||
if (!fBuffer)
|
||||
return B_NO_INIT;
|
||||
if (path) {
|
||||
int32 len = strlen(path);
|
||||
if (len >= fBufferSize)
|
||||
return B_BUFFER_OVERFLOW;
|
||||
memcpy(fBuffer, path, len + 1);
|
||||
fPathLength = len;
|
||||
} else {
|
||||
fBuffer[0] = '\0';
|
||||
fPathLength = 0;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Path
|
||||
const char*
|
||||
KPath::Path() const
|
||||
{
|
||||
return fBuffer;
|
||||
}
|
||||
|
||||
// Length
|
||||
int32
|
||||
KPath::Length() const
|
||||
{
|
||||
return fPathLength;
|
||||
}
|
||||
|
||||
// BufferSize
|
||||
int32
|
||||
KPath::BufferSize() const
|
||||
{
|
||||
return fBufferSize;
|
||||
}
|
||||
|
||||
// LockBuffer
|
||||
char *
|
||||
KPath::LockBuffer()
|
||||
{
|
||||
if (!fBuffer || fLocked)
|
||||
return NULL;
|
||||
fLocked = true;
|
||||
return fBuffer;
|
||||
}
|
||||
|
||||
// UnlockBuffer
|
||||
void
|
||||
KPath::UnlockBuffer()
|
||||
{
|
||||
if (!fLocked) {
|
||||
DBG(OUT("KPath::UnlockBuffer(): ERROR: Buffer not locked!\n"));
|
||||
return;
|
||||
}
|
||||
fLocked = false;
|
||||
fPathLength = strnlen(fBuffer, fBufferSize);
|
||||
if (fPathLength == fBufferSize) {
|
||||
DBG(OUT("KPath::UnlockBuffer(): WARNING: Unterminated buffer!\n"));
|
||||
fPathLength--;
|
||||
fBuffer[fPathLength] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// Append
|
||||
status_t
|
||||
KPath::Append(const char *component)
|
||||
{
|
||||
// check initialization and parameter
|
||||
if (!fBuffer)
|
||||
return B_NO_INIT;
|
||||
if (!component)
|
||||
return B_BAD_VALUE;
|
||||
// get componentn length
|
||||
int32 componentLen = strlen(component);
|
||||
if (componentLen < 1)
|
||||
return B_OK;
|
||||
// if our current path is empty, we just copy the supplied one
|
||||
if (fPathLength == 0) {
|
||||
if (componentLen >= fBufferSize)
|
||||
return B_BUFFER_OVERFLOW;
|
||||
memcpy(fBuffer, component, componentLen + 1);
|
||||
fPathLength = componentLen;
|
||||
return B_OK;
|
||||
}
|
||||
// compute the result path len
|
||||
bool insertSlash = (fBuffer[fPathLength - 1] != '/'
|
||||
&& component[0] != '/');
|
||||
int32 resultPathLen = fPathLength + componentLen + (insertSlash ? 1 : 0);
|
||||
if (resultPathLen >= fBufferSize)
|
||||
return B_BUFFER_OVERFLOW;
|
||||
// compose the result path
|
||||
if (insertSlash)
|
||||
fBuffer[fPathLength++] = '/';
|
||||
memcpy(fBuffer + fPathLength, component, componentLen + 1);
|
||||
fPathLength = resultPathLen;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// =
|
||||
KPath&
|
||||
KPath::operator=(const KPath& other)
|
||||
{
|
||||
SetTo(other.fBuffer, other.fBufferSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// =
|
||||
KPath&
|
||||
KPath::operator=(const char* path)
|
||||
{
|
||||
SetTo(path);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ==
|
||||
bool
|
||||
KPath::operator==(const KPath& other) const
|
||||
{
|
||||
if (!fBuffer)
|
||||
return (!other.fBuffer);
|
||||
return (other.fBuffer
|
||||
&& fPathLength == other.fPathLength
|
||||
&& strcmp(fBuffer, other.fBuffer) == 0);
|
||||
}
|
||||
|
||||
// ==
|
||||
bool
|
||||
KPath::operator==(const char* path) const
|
||||
{
|
||||
if (!fBuffer)
|
||||
return (!path);
|
||||
return (path && strcmp(fBuffer, path) == 0);
|
||||
}
|
||||
|
||||
// !=
|
||||
bool
|
||||
KPath::operator!=(const KPath& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
// !=
|
||||
bool
|
||||
KPath::operator!=(const char* path) const
|
||||
{
|
||||
return !(*this == path);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user