343 lines
7.6 KiB
C++
343 lines
7.6 KiB
C++
//
|
|
// The developer of the original code and/or files is Tripwire, Inc.
|
|
// Portions created by Tripwire, Inc. are copyright (C) 2000 Tripwire,
|
|
// Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights
|
|
// reserved.
|
|
//
|
|
// This program is free software. The contents of this file are subject
|
|
// to the terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 2 of the License, or (at your
|
|
// option) any later version. You may redistribute it and/or modify it
|
|
// only in compliance with the GNU General Public License.
|
|
//
|
|
// This program is distributed in the hope that it will be useful.
|
|
// However, this program is distributed AS-IS WITHOUT ANY
|
|
// WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
|
|
// FOR A PARTICULAR PURPOSE. Please see the GNU General Public License
|
|
// for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
// USA.
|
|
//
|
|
// Nothing in the GNU General Public License or any other license to use
|
|
// the code or files shall permit you to use Tripwire's trademarks,
|
|
// service marks, or other intellectual property without Tripwire's
|
|
// prior written consent.
|
|
//
|
|
// If you have any questions, please contact Tripwire, Inc. at either
|
|
// info@tripwire.org or www.tripwire.org.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// wchar16.h
|
|
//
|
|
// Function and classes dealing with the WCHAR16 type
|
|
//
|
|
#include "stdcore.h"
|
|
#include "config.h"
|
|
#include "wchar16.h"
|
|
#include "debug.h"
|
|
#include <stdexcept> // for stl::out_of_range
|
|
#ifdef HAVE_MEMORY_H
|
|
# include <memory.h>
|
|
#endif
|
|
|
|
int wchar16len(const WCHAR16* s)
|
|
{
|
|
int i;
|
|
for (i = 0; *s != 0; ++s, ++i)
|
|
;
|
|
|
|
return i;
|
|
}
|
|
|
|
//=============================================================================
|
|
// class wc16_string
|
|
//
|
|
// This clas implements enough of the std::basic_string interface so we
|
|
// can use it like an STL string.
|
|
//
|
|
// In an ideal world we this would be a std::basic_string instantiation, but
|
|
// UNIX doesn't seem to dealing 16 bit wide chars, it uses 32 bit chars.
|
|
//=============================================================================
|
|
|
|
class wc16_string_impl
|
|
{
|
|
public:
|
|
int length;
|
|
WCHAR16* pString;
|
|
int refCount;
|
|
|
|
wc16_string_impl();
|
|
wc16_string_impl(const wc16_string_impl& rhs);
|
|
|
|
void AddRef();
|
|
void Release();
|
|
void Resize(int newlen);
|
|
void CopyString(const wc16_string_impl& rhs);
|
|
// note: does not alter this->referenceCount, and ASSERTs that refcount == 1
|
|
|
|
~wc16_string_impl(); // call Release() to delete
|
|
private:
|
|
void operator = (const wc16_string_impl& rhs) { return; } // don't call
|
|
};
|
|
|
|
static WCHAR16 NULL_WCHAR16 = 0;
|
|
|
|
wc16_string::wc16_string()
|
|
: mpData(0)
|
|
{
|
|
}
|
|
|
|
wc16_string::wc16_string(const wc16_string& rhs)
|
|
{
|
|
mpData = rhs.mpData;
|
|
if (mpData)
|
|
mpData->AddRef();
|
|
}
|
|
|
|
wc16_string::wc16_string(const_iterator pStr)
|
|
{
|
|
mpData = new wc16_string_impl;
|
|
|
|
int len = wchar16len(pStr);
|
|
mpData->Resize(len);
|
|
memcpy(mpData->pString, pStr, len * sizeof(WCHAR16));
|
|
}
|
|
|
|
wc16_string::~wc16_string()
|
|
{
|
|
if (mpData)
|
|
mpData->Release();
|
|
}
|
|
|
|
void wc16_string::operator = (const wc16_string& rhs)
|
|
{
|
|
if (mpData)
|
|
mpData->Release();
|
|
|
|
mpData = rhs.mpData;
|
|
|
|
if( mpData )
|
|
mpData->AddRef();
|
|
}
|
|
|
|
|
|
int wc16_string::compare(const wc16_string& rhs) const
|
|
{
|
|
if( length() > rhs.length() )
|
|
return 1;
|
|
else if ( length() < rhs.length() )
|
|
return -1;
|
|
else
|
|
return memcmp( c_str(), rhs.c_str(), length()*sizeof( WCHAR16 ) );
|
|
}
|
|
|
|
wc16_string::size_type
|
|
wc16_string::length() const
|
|
{
|
|
return mpData ? mpData->length : 0;
|
|
}
|
|
|
|
wc16_string::size_type
|
|
wc16_string::size() const
|
|
{
|
|
return mpData ? mpData->length : 0;
|
|
}
|
|
|
|
wc16_string::const_iterator
|
|
wc16_string::c_str() const
|
|
{
|
|
if (mpData == 0)
|
|
return &NULL_WCHAR16;
|
|
|
|
mpData->pString[mpData->length] = 0;
|
|
|
|
return mpData->pString;
|
|
}
|
|
|
|
wc16_string::const_iterator
|
|
wc16_string::begin() const
|
|
{
|
|
return (const_cast<wc16_string*>(this))->begin();
|
|
}
|
|
|
|
wc16_string::iterator
|
|
wc16_string::begin()
|
|
{
|
|
return mpData ? mpData->pString : &NULL_WCHAR16;
|
|
}
|
|
|
|
wc16_string::const_iterator
|
|
wc16_string::end() const
|
|
{
|
|
return
|
|
const_cast< iterator >(
|
|
mpData
|
|
? mpData->pString + mpData->length
|
|
: &NULL_WCHAR16 );
|
|
}
|
|
|
|
wc16_string::iterator
|
|
wc16_string::end()
|
|
{
|
|
return
|
|
mpData
|
|
? mpData->pString + mpData->length
|
|
: &NULL_WCHAR16;
|
|
}
|
|
|
|
wc16_string::const_iterator wc16_string::data() const
|
|
{
|
|
return begin();
|
|
}
|
|
|
|
const wc16_string::value_type& wc16_string::operator [] (int i) const
|
|
{
|
|
ASSERT(i >= 0);
|
|
|
|
if (mpData == 0 || i >= mpData->length || i < 0)
|
|
{
|
|
ASSERT(false);
|
|
throw std::out_of_range("wc16_string[]");
|
|
}
|
|
|
|
return mpData->pString[i];
|
|
}
|
|
|
|
wc16_string::value_type& wc16_string::operator [] (int i)
|
|
{
|
|
ASSERT(i >= 0);
|
|
|
|
if (mpData == 0 || i >= mpData->length || i < 0)
|
|
{
|
|
ASSERT(false);
|
|
throw std::out_of_range("wc16_string[]");
|
|
}
|
|
|
|
if (mpData->refCount > 1)
|
|
{
|
|
wc16_string_impl* newImpl = new wc16_string_impl(*mpData);
|
|
mpData->Release();
|
|
mpData = newImpl;
|
|
}
|
|
|
|
return mpData->pString[i];
|
|
}
|
|
|
|
void wc16_string::resize( size_type nCount )
|
|
{
|
|
if ( mpData == 0 )
|
|
{
|
|
mpData = new wc16_string_impl;
|
|
}
|
|
else if ( mpData->refCount > 1 )
|
|
{
|
|
wc16_string_impl* newImpl = new wc16_string_impl( *mpData );
|
|
mpData->Release();
|
|
mpData = newImpl;
|
|
}
|
|
|
|
mpData->Resize( nCount );
|
|
}
|
|
|
|
// useful to convert to network byte order
|
|
void wc16_string::swapbytes()
|
|
{
|
|
if (mpData)
|
|
{
|
|
if (mpData->refCount > 1)
|
|
{
|
|
wc16_string_impl* newImpl = new wc16_string_impl(*mpData);
|
|
mpData->Release();
|
|
mpData = newImpl;
|
|
}
|
|
|
|
int i;
|
|
for (i = 0; i < mpData->length; ++i)
|
|
{
|
|
mpData->pString[i] = SWAPBYTES16(mpData->pString[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
wc16_string_impl::wc16_string_impl()
|
|
{
|
|
length = 0;
|
|
pString = new WCHAR16[1];
|
|
refCount = 1;
|
|
}
|
|
|
|
wc16_string_impl::wc16_string_impl(const wc16_string_impl& rhs)
|
|
{
|
|
int newlen = rhs.length;
|
|
pString = new WCHAR16[newlen + 1];
|
|
length = newlen;
|
|
refCount = 1;
|
|
|
|
memcpy(pString, rhs.pString, newlen * sizeof(WCHAR16));
|
|
}
|
|
|
|
wc16_string_impl::~wc16_string_impl()
|
|
{
|
|
delete [] pString;
|
|
}
|
|
|
|
void wc16_string_impl::AddRef()
|
|
{
|
|
++refCount;
|
|
}
|
|
|
|
void wc16_string_impl::Release()
|
|
{
|
|
ASSERT(refCount > 0);
|
|
|
|
if (--refCount == 0)
|
|
{
|
|
delete this;
|
|
}
|
|
}
|
|
|
|
void wc16_string_impl::Resize(int newlen)
|
|
{
|
|
ASSERT(newlen >= 0);
|
|
if (newlen == length)
|
|
return;
|
|
|
|
WCHAR16* newString = new WCHAR16[newlen + 1];
|
|
|
|
if (newlen < length)
|
|
{
|
|
memcpy(newString, pString, newlen * sizeof(WCHAR16));
|
|
delete [] pString;
|
|
pString = newString;
|
|
length = newlen;
|
|
}
|
|
else
|
|
{
|
|
memcpy(newString, pString, length * sizeof(WCHAR16));
|
|
memset(newString + length, 0, (newlen - length) * sizeof(WCHAR16));
|
|
delete [] pString;
|
|
pString = newString;
|
|
length = newlen;
|
|
}
|
|
}
|
|
|
|
void wc16_string_impl::CopyString(const wc16_string_impl& rhs)
|
|
{
|
|
ASSERT(refCount == 1);
|
|
|
|
int newlen = rhs.length;
|
|
|
|
if (rhs.length != this->length)
|
|
{
|
|
delete [] pString;
|
|
pString = new WCHAR16[newlen + 1];
|
|
this->length = newlen;
|
|
}
|
|
|
|
memcpy(this->pString, rhs.pString, newlen * sizeof(WCHAR16));
|
|
}
|
|
|