* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef UNIX_ADDRESS_H
#define UNIX_ADDRESS_H
#include <sys/un.h>
#include <SupportDefs.h>
#define INTERNAL_UNIX_ADDRESS_LEN (2 + 1 + 5)
struct vnode;
class UnixAddress {
public:
UnixAddress()
{
Unset();
}
UnixAddress(const UnixAddress& other)
{
*this = other;
}
UnixAddress(int32 internalID)
{
SetTo(internalID);
}
UnixAddress(dev_t volumeID, ino_t nodeID, struct vnode* vnode)
{
SetTo(volumeID, nodeID, vnode);
}
void SetTo(int32 internalID)
{
fInternalID = internalID;
fVolumeID = -1;
fNodeID = -1;
fVnode = NULL;
}
void SetTo(dev_t volumeID, ino_t nodeID, struct vnode* vnode)
{
fInternalID = -1;
fVolumeID = volumeID;
fNodeID = nodeID;
fVnode = vnode;
}
void Unset()
{
fInternalID = -1;
fVolumeID = -1;
fNodeID = -1;
fVnode = NULL;
}
bool IsValid() const
{
return fInternalID >= 0 || fVolumeID >= 0;
}
bool IsInternalAddress() const
{
return fInternalID >= 0;
}
int32 InternalID() const
{
return fInternalID;
}
int32 VolumeID() const
{
return fVolumeID;
}
int32 NodeID() const
{
return fNodeID;
}
struct vnode* Vnode() const
{
return fVnode;
}
uint32 HashCode() const
{
return fInternalID >= 0
? fInternalID
: uint32(fVolumeID) ^ uint32(fNodeID);
}
char* ToString(char *buffer, size_t bufferSize) const;
UnixAddress& operator=(const UnixAddress& other)
{
fInternalID = other.fInternalID;
fVolumeID = other.fVolumeID;
fNodeID = other.fNodeID;
fVnode = other.fVnode;
return *this;
}
bool operator==(const UnixAddress& other) const
{
return fInternalID >= 0
? fInternalID == other.fInternalID
: fVolumeID == other.fVolumeID
&& fNodeID == other.fNodeID;
}
bool operator!=(const UnixAddress& other) const
{
return !(*this == other);
}
static bool IsEmptyAddress(const sockaddr_un& address)
{
return address.sun_len == sizeof(sockaddr)
&& address.sun_path[0] == '\0' && address.sun_path[1] == '\0';
}
static int32 InternalID(const sockaddr_un& address)
{
if (address.sun_len < INTERNAL_UNIX_ADDRESS_LEN
|| address.sun_path[0] != '\0') {
return B_BAD_VALUE;
}
int32 id = 0;
for (int32 i = 0; i < 5; i++) {
char c = address.sun_path[i + 1];
if (c >= '0' && c <= '9')
id = (id << 4) + (c - '0');
else if (c >= 'a' && c <= 'f')
id = (id << 4) + 10 + (c - 'a');
else
return B_BAD_VALUE;
}
return id;
}
private:
int32 fInternalID;
dev_t fVolumeID;
ino_t fNodeID;
struct vnode* fVnode;
};
#endif