|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
icstring.cxx
Abstract:
Contains ICSTRING class methods. Split from ICSTRING.HXX (inline methods)
Contents: ICSTRING::ICSTRING(ICSTRING&) ICSTRING::~ICSTRING() ICSTRING::operator=(LPSTR) ICSTRING::operator=(ICSTRING&) ICSTRING::operator+=(LPSTR) ICSTRING::operator+=(char) ICSTRING::strncat(LPVOID, DWORD) ICSTRING::CreateStringBuffer(LPVOID, DWORD, DWORD) ICSTRING::CreateOffsetString(DWORD, DWORD) ICSTRING::CopyTo(LPSTR) ICSTRING::CopyTo(LPSTR, LPSTR) ICSTRING::CopyTo(LPSTR, DWORD) ICSTRING::CopyTo(LPSTR, LPDWORD)
Author:
Richard L Firth (rfirth) 18-Dec-1995
Revision History:
18-Dec-1995 rfirth Created
--*/
#include <wininetp.h>
//
// methods
//
//
//ICSTRING::ICSTRING(
// IN ICSTRING& String
// )
//
///*++
//
//Routine Description:
//
// copy constructor. We now create an entirely new string (used to be just a
// reference of the rvalue)
//
//Arguments:
//
// String - to copy
//
//Return Value:
//
// None.
//
//--*/
//
//{
// //
// // can't already have string in lvalue, & rvalue mustn't be an offset string
// //
//
// INET_ASSERT(!HaveString());
// INET_ASSERT(!String.IsOffset());
// INET_ASSERT(!String.IsError());
//
// *this = String.StringAddress();
//}
ICSTRING::~ICSTRING( VOID )
/*++
Routine Description:
destructor
Arguments:
None.
Return Value:
None.
--*/
{ //
// can only free the string if it is not a reference. Offset type
// implies reference
//
if (!IsReference() && (_String != NULL)) {
INET_ASSERT(!IsOffset());
(VOID)ResizeBuffer((HLOCAL)_String, 0, FALSE); _String = NULL; } }
ICSTRING& ICSTRING::operator=( IN LPSTR String )
/*++
Routine Description:
Copy/assigment. Copies a string to this object. If NULL, frees up the current buffer
Arguments:
String - to be assigned
Return Value:
ICSTRING&
--*/
{ //
// if this is an offset string then there's not much to do
//
if (IsOffset()) { Initialize(); return *this; }
//
// string MUST NOT be a copy (we'll free the real string pointer, owned
// by another object) and SHOULD NOT be copied itself (the objects with
// copies of the string will potentially have a bad pointer)
//
INET_ASSERT((String == NULL) ? TRUE : !IsReference()); INET_ASSERT(!IsReferenced());
//
// if the pointer is NULL or the string is empty then we are freeing the
// string pointer
//
DWORD len;
if (String == NULL) { len = 0; } else { len = ::strlen(String); if (len != 0) { INET_ASSERT(len < 0xffffffff); ++len; } }
//
// free or grow the buffer, depending on requirements
//
if ((len > _BufferLength) || ((len == 0) && (_String != NULL))) { _String = (LPSTR)ResizeBuffer((HLOCAL)_String, len, FALSE); _BufferLength = (_String != NULL) ? len : 0; } if (_String != NULL) {
INET_ASSERT(len != 0);
memcpy((LPVOID)_String, (LPVOID)String, len); _StringLength = len - 1; SetHaveString(TRUE); SetError(FALSE); } else { _StringLength = 0; SetHaveString(FALSE); SetError(len != 0); // an error might have occurred
} return *this; }
ICSTRING& ICSTRING::operator=( IN ICSTRING& String )
/*++
Routine Description:
Copy/assignment. Makes new copy of object (used to just make a reference)
Arguments:
String - ICSTRING object to be assigned
Return Value:
ICSTRING&
--*/
{ INET_ASSERT(!IsReferenced()); INET_ASSERT(!String.IsReferenced()); INET_ASSERT(!String.IsError());
//
// if we're copying an offset, make sure that any string we may already
// have is freed
//
if (String.IsOffset()) { if (_String != NULL) { ResizeBuffer(_String, 0, FALSE); } _String = String._String; _StringLength = String._StringLength; _BufferLength = String._BufferLength; _Union.Dword = String._Union.Dword; } else {
INET_ASSERT(!IsOffset() && !String.IsOffset());
//
// use string assignment to correctly setup this object
//
*this = String.StringAddress(); } return *this; }
VOID ICSTRING::operator+=( IN LPSTR String )
/*++
Routine Description:
Concatenates a string to the buffer. Reallocates it if necessary. String CANNOT be NULL
Arguments:
String - to concatenate
Return Value:
None.
--*/
{ INET_ASSERT(!IsReference()); INET_ASSERT(!IsReferenced()); INET_ASSERT(!IsOffset()); INET_ASSERT(String != NULL);
if (IsError()) { return; }
if (*String == '\0') { return; }
DWORD len = ::strlen(String); DWORD newlen = _StringLength + len + 1;
INET_ASSERT ((newlen > _StringLength) && (newlen > len));
if (_BufferLength < newlen) { _String = (LPSTR)ResizeBuffer((HLOCAL)_String, newlen, FALSE);
INET_ASSERT((_String == NULL) ? (newlen == 0) : TRUE);
_BufferLength = newlen; } if (_String != NULL) { memcpy((LPVOID)((LPBYTE)_String + _StringLength), (LPVOID)String, len + 1 ); _StringLength += len; } else { _StringLength = 0; _BufferLength = 0; SetError(TRUE); } }
VOID ICSTRING::operator+=( IN char Ch )
/*++
Routine Description:
Concatenates a character to the buffer. Reallocates it if necessary. Ch CAN be '\0'
Arguments:
Ch - to concatenate
Return Value:
None.
--*/
{ INET_ASSERT(!IsReference()); INET_ASSERT(!IsReferenced()); INET_ASSERT(!IsOffset());
if (IsError()) { return; }
DWORD newlen = _StringLength + 2;
INET_ASSERT (newlen > _StringLength);
if (_BufferLength < newlen) { _String = (LPSTR)ResizeBuffer((HLOCAL)_String, newlen, FALSE);
INET_ASSERT((_String == NULL) ? (newlen == 0) : TRUE);
_BufferLength = newlen; } if (_String != NULL) { _String[_StringLength] = Ch; ++_StringLength; _String[_StringLength] = '\0'; } else { _StringLength = 0; _BufferLength = 0; SetError(TRUE); } }
VOID ICSTRING::Strncat( IN LPVOID Pointer, IN DWORD Length )
/*++
Routine Description:
Copies Length characters from Pointer to the end of _String
Arguments:
Pointer - place to copy from
Length - number of characters to copy
Return Value:
None.
--*/
{ if (IsError()) { return; }
INET_ASSERT(Pointer != NULL); INET_ASSERT(Length != 0); INET_ASSERT(_String != NULL); INET_ASSERT(!IsReference()); INET_ASSERT(!IsReferenced());
DWORD newLength;
newLength = _StringLength + Length + 1;
INET_ASSERT ((newLength > _StringLength) && (newLength > Length));
if (_BufferLength < newLength) { _String = (LPSTR)ResizeBuffer((HLOCAL)_String, newLength, FALSE); _BufferLength = newLength; } if (_String != NULL) { memcpy((LPVOID)&_String[_StringLength], Pointer, Length); _StringLength += Length;
INET_ASSERT(_StringLength < _BufferLength);
_String[_StringLength] = '\0'; } else { _StringLength = 0; _BufferLength = 0; SetError(TRUE); } }
VOID ICSTRING::CreateStringBuffer( IN LPVOID Pointer, IN DWORD StringLength, IN DWORD BufferLength )
/*++
Routine Description:
In order to avoid reallocations, if we know the size of the buffer we want for several strcat()'s, e.g., we can allocate it once, copy the initial string here, then perform multiple concatenate operations (+=)
Arguments:
Pointer - place to start copying from
StringLength - length of string
BufferLength - length of buffer required
Return Value:
None.
--*/
{ INET_ASSERT(Pointer != NULL); INET_ASSERT(BufferLength > StringLength); INET_ASSERT(BufferLength != 0);
//
// if we currently have an offset string then initialize to a non-offset
//
if (IsOffset()) { Initialize(); } _String = (LPSTR)ResizeBuffer(_String, BufferLength, FALSE); if (_String != NULL) { _StringLength = StringLength; _BufferLength = BufferLength; memcpy((LPVOID)_String, Pointer, _StringLength); _String[_StringLength] = '\0'; SetHaveString(TRUE); SetReference(FALSE); SetReferenced(FALSE); SetOffset(FALSE); SetError(FALSE); } else { SetError(TRUE); } }
VOID ICSTRING::CreateOffsetString( IN DWORD Offset, IN DWORD Length )
/*++
Routine Description:
Create a reference ICSTRING that is an offset within another buffer
Arguments:
Offset - offset into buffer
Length - of string
Return Value:
None.
--*/
{ _String = (LPSTR)(DWORD_PTR)Offset; _StringLength = Length; _BufferLength = Length; ZapFlags(); SetHaveString(TRUE); // ICSTRING initialized with non-NULL
SetReference(TRUE); // reference to another string buffer
SetOffset(TRUE); // offset from base
SetError(FALSE); }
VOID ICSTRING::CopyTo( IN LPSTR Buffer )
/*++
Routine Description:
Copies source _String to destination Buffer
Arguments:
Buffer - place to copy to
Return Value:
None.
--*/
{ INET_ASSERT(Buffer != NULL); INET_ASSERT(!IsOffset());
memcpy((LPVOID)Buffer, (LPVOID)_String, _StringLength); Buffer[_StringLength] = '\0'; }
VOID ICSTRING::CopyTo( IN LPSTR Base, IN LPSTR Buffer )
/*++
Routine Description:
Copies a based (offset) string from source Base + _String to destination Buffer
Arguments:
Base - value for base
Buffer - place to write string
Return Value:
None.
--*/
{ INET_ASSERT(Buffer != NULL); //INET_ASSERT(IsOffset() ? (Base != NULL) : (Base == NULL));
memcpy((LPVOID)Buffer, IsOffset() ? (Base + (DWORD_PTR)_String) : _String, _StringLength ); Buffer[_StringLength] = '\0'; }
VOID ICSTRING::CopyTo( IN LPSTR Buffer, IN DWORD Length )
/*++
Routine Description:
Copies at most Length characters from source _String to destination Buffer
Arguments:
Buffer - place to write string
Length - number of characters to copy
Return Value:
None.
--*/
{ INET_ASSERT(Buffer != NULL); INET_ASSERT(!IsOffset());
DWORD length = min(Length - 1, _StringLength);
memcpy((LPVOID)Buffer, (LPVOID)_String, length); Buffer[length] = '\0'; }
VOID ICSTRING::CopyTo( IN LPSTR Buffer, IN OUT LPDWORD Length )
/*++
Routine Description:
Copies at most *Length characters from source _String to destination Buffer. Updates *Length to be number of characters copied, not including terminating NUL
Arguments:
Buffer - place to write string
Length - IN: length of buffer OUT: number of characters copied
Return Value:
None.
--*/
{ INET_ASSERT(Buffer != NULL); INET_ASSERT(!IsOffset());
DWORD length = min(*Length - 1, _StringLength);
memcpy((LPVOID)Buffer, (LPVOID)_String, length); Buffer[length] = '\0'; *Length = length; }
|