#include <SF/DataPtr.hpp>
#include <SF/Tools.hpp>
namespace SF {
DataPtr::DataPtr() :
ptr_(buffer_),
length_(RCF_DEFAULT_INIT),
allocatedLength_(RCF_DEFAULT_INIT),
whichDeleter_(RCF_DEFAULT_INIT),
pfn_deleter_(RCF_DEFAULT_INIT)
{}
DataPtr::DataPtr(const T *sz) :
ptr_( const_cast<T*>(sz) ),
length_( length(sz) ),
allocatedLength_(length_+1),
whichDeleter_(0),
pfn_deleter_(RCF_DEFAULT_INIT)
{
// Weak attach
RCF_ASSERT(ptr_);
}
DataPtr::DataPtr(const T *sz, UInt32 length) :
ptr_( const_cast<T*>(sz) ),
length_(length),
allocatedLength_(length_),
whichDeleter_(RCF_DEFAULT_INIT),
pfn_deleter_(RCF_DEFAULT_INIT)
{
// Weak attach
RCF_ASSERT(ptr_);
}
DataPtr::DataPtr(const DataPtr &rhs) :
ptr_(rhs.ptr_),
length_(rhs.length_),
allocatedLength_(rhs.allocatedLength_),
whichDeleter_(0),
pfn_deleter_(RCF_DEFAULT_INIT)
{
// Weak copy
}
DataPtr &DataPtr::operator=(const DataPtr &rhs)
{
// Weak copy
ptr_ = rhs.ptr_;
length_ = rhs.length_;
allocatedLength_ = rhs.allocatedLength_;
whichDeleter_ = 0;
pfn_deleter_ = NULL;
return *this;
}
DataPtr::~DataPtr()
{
RCF_DTOR_BEGIN
release();
RCF_DTOR_END
}
void DataPtr::assign(const T *sz, UInt32 length)
{
allocate(length);
memmove( get(), sz, length*sizeof(T) );
}
void DataPtr::assign(const T *sz)
{
assign(sz, length(sz));
}
void DataPtr::assign(const std::string &s)
{
assign(s.c_str(), static_cast<UInt32>(s.length()));
}
void DataPtr::release()
{
switch (whichDeleter_)
{
case 0:
break;
case 1:
delete ptr_;
break;
case 2:
delete [] ptr_;
break;
case 3:
RCF_ASSERT(pfn_deleter_);
pfn_deleter_(ptr_);
break;
default:
RCF_ASSERT(0);
}
ptr_ = NULL;
length_ = 0;
whichDeleter_ = 0;
pfn_deleter_ = NULL;
}
UInt32 DataPtr::allocate(UInt32 length)
{
release();
if (length <= 63)
{
ptr_ = buffer_;
length_ = length;
ptr_[length_] = 0;
allocatedLength_ = length_ + 1;
whichDeleter_ = 0;
pfn_deleter_ = NULL;
}
else
{
ptr_ = new T[length + 1];
allocatedLength_ = length + 1;
ptr_[length] = 0;
length_ = length;
whichDeleter_ = 2;
pfn_deleter_ = NULL;
}
return length;
}
void DataPtr::terminatebufferwithzero() const
{
if (ptr_ && ptr_[length_] != 0)
{
RCF_ASSERT(allocatedLength_ > length_)(allocatedLength_)(length_);
ptr_[length_] = 0;
}
}
void DataPtr::update_length()
{
if (ptr_)
length_ = length(ptr_);
}
DataPtr::T *DataPtr::get() const
{
return ptr_;
}
UInt32 DataPtr::length() const
{
return length_;
}
bool DataPtr::empty() const
{
return length_ == 0;
}
std::string DataPtr::cpp_str() const
{
return std::string(static_cast<char *>(ptr_), length_);
}
UInt32 DataPtr::length(const T *sz)
{
if (sz)
{
UInt32 i=0;
while (sz[i])
i++;
return i;
}
else
return 0;
}
bool operator<(const DataPtr &lhs, const DataPtr &rhs)
{
typedef Byte8 T;
RCF_ASSERT(lhs.get());
RCF_ASSERT(rhs.get());
if (lhs.length() < rhs.length())
return true;
else if (lhs.length() > rhs.length())
return false;
else {
RCF_ASSERT(lhs.length() == rhs.length());
return memcmp(lhs.get(), rhs.get(), lhs.length()*sizeof(T)) < 0;
}
}
bool operator==(const DataPtr &lhs, const DataPtr &rhs)
{
typedef Byte8 T;
RCF_ASSERT(lhs.get());
RCF_ASSERT(rhs.get());
return
lhs.length() == rhs.length() &&
0 == memcmp(lhs.get(), rhs.get(), lhs.length()*sizeof(T));
}
bool operator!=(const DataPtr &lhs, const DataPtr &rhs)
{
return ! (lhs == rhs);
}
} // namespace SF