1132 lines
16 KiB
C++
1132 lines
16 KiB
C++
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
xbf.cxx
|
|
|
|
Abstract:
|
|
|
|
Classes to handle extensible buffers
|
|
|
|
Author:
|
|
|
|
Philippe Choquier (phillich) 17-oct-1996
|
|
|
|
--*/
|
|
|
|
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <mbstring.h>
|
|
|
|
#include "lbxbf.hxx"
|
|
|
|
//
|
|
// Global functions
|
|
//
|
|
|
|
BOOL
|
|
Unserialize(
|
|
LPBYTE* ppB,
|
|
LPDWORD pC,
|
|
LPDWORD pU
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unserialize a DWORD
|
|
pU is updated with DWORD from *ppB, ppB & pC are updated
|
|
|
|
Arguments:
|
|
|
|
ppB - ptr to addr of buffer
|
|
pC - ptr to byte count in buffer
|
|
pU - ptr to DWORD where to unserialize
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
if ( *pC >= sizeof( DWORD ) )
|
|
{
|
|
*pU = *(DWORD UNALIGNED*)*ppB;
|
|
*ppB += sizeof(DWORD);
|
|
*pC -= sizeof(DWORD);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
Unserialize(
|
|
LPBYTE* ppB,
|
|
LPDWORD pC,
|
|
LPBOOL pU
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unserialize a BOOL
|
|
pU is updated with BOOL from *ppB, ppB & pC are updated
|
|
|
|
Arguments:
|
|
|
|
ppB - ptr to addr of buffer
|
|
pC - ptr to byte count in buffer
|
|
pU - ptr to BOOL where to unserialize
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
if ( *pC >= sizeof( BOOL ) )
|
|
{
|
|
*pU = *(BOOL UNALIGNED*)*ppB;
|
|
*ppB += sizeof(BOOL);
|
|
*pC -= sizeof(BOOL);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//
|
|
// Extensible buffer class
|
|
//
|
|
|
|
BOOL
|
|
CStoreXBF::Need(
|
|
DWORD dwNeed
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Insure that CStoreXBF can store at least dwNeed bytes
|
|
including bytes already stored.
|
|
|
|
Arguments:
|
|
|
|
dwNeed - minimum of bytes available for storage
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
if ( dwNeed > m_cAllocBuff )
|
|
{
|
|
dwNeed = ((dwNeed + m_cGrain)/m_cGrain)*m_cGrain;
|
|
LPBYTE pN = (LPBYTE)LocalAlloc( LMEM_FIXED, dwNeed );
|
|
if ( pN == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
if ( m_cUsedBuff )
|
|
{
|
|
memcpy( pN, m_pBuff, m_cUsedBuff );
|
|
}
|
|
m_cAllocBuff = dwNeed;
|
|
LocalFree( m_pBuff );
|
|
m_pBuff = pN;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CStoreXBF::Save(
|
|
HANDLE hFile
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Save to file
|
|
|
|
Arguments:
|
|
|
|
hFile - file handle
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
DWORD dwWritten;
|
|
|
|
return WriteFile( hFile, GetBuff(), GetUsed(), &dwWritten, NULL ) &&
|
|
dwWritten == GetUsed();
|
|
}
|
|
|
|
|
|
BOOL
|
|
CStoreXBF::Load(
|
|
HANDLE hFile
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Load from file
|
|
|
|
Arguments:
|
|
|
|
hFile - file handle
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
DWORD dwS = GetFileSize( hFile, NULL );
|
|
DWORD dwRead;
|
|
|
|
if ( dwS != 0xffffffff &&
|
|
Need( dwS ) &&
|
|
ReadFile( hFile, GetBuff(), dwS, &dwRead, NULL ) &&
|
|
dwRead == dwS )
|
|
{
|
|
m_cUsedBuff = dwRead;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
m_cUsedBuff = 0;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
Serialize(
|
|
CStoreXBF* pX,
|
|
DWORD dw
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Serialize a DWORD in CStoreXBF
|
|
|
|
Arguments:
|
|
|
|
pX - ptr to CStoreXBF where to add serialized DWORD
|
|
dw - DWORD to serialize
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
return pX->Append( (LPBYTE)&dw, sizeof(dw) );
|
|
}
|
|
|
|
|
|
BOOL
|
|
Serialize(
|
|
CStoreXBF* pX,
|
|
BOOL f
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Serialize a BOOL in CStoreXBF
|
|
|
|
Arguments:
|
|
|
|
pX - ptr to CStoreXBF where to add serialized BOOL
|
|
f - BOOL to serialize
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
return pX->Append( (LPBYTE)&f, sizeof(f) );
|
|
}
|
|
|
|
|
|
DWORD
|
|
CPtrXBF::AddPtr(
|
|
LPVOID pV
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Add a ptr to array
|
|
|
|
Arguments:
|
|
|
|
pV - ptr to be added at end of array
|
|
|
|
Return Value:
|
|
|
|
index ( 0-based ) in array where added or INDEX_ERROR if error
|
|
|
|
--*/
|
|
{
|
|
DWORD i = GetNbPtr();
|
|
if ( Append( (LPBYTE)&pV, sizeof(pV)) )
|
|
{
|
|
return i;
|
|
}
|
|
return INDEX_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
CPtrXBF::InsertPtr(
|
|
DWORD iBefore,
|
|
LPVOID pV
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Insert a ptr to array
|
|
|
|
Arguments:
|
|
|
|
iBefore - index where to insert entry, or 0xffffffff if add to array
|
|
pV - ptr to be inserted
|
|
|
|
Return Value:
|
|
|
|
index ( 0-based ) in array where added or INDEX_ERROR if error
|
|
|
|
--*/
|
|
{
|
|
if ( iBefore == INDEX_ERROR || iBefore >= GetNbPtr() )
|
|
{
|
|
return AddPtr( pV );
|
|
}
|
|
if ( AddPtr( NULL ) != INDEX_ERROR )
|
|
{
|
|
memmove( GetBuff()+(iBefore+1)*sizeof(LPVOID),
|
|
GetBuff()+iBefore*sizeof(LPVOID),
|
|
GetUsed()-(iBefore+1)*sizeof(LPVOID) );
|
|
|
|
SetPtr( iBefore, pV );
|
|
|
|
return iBefore;
|
|
}
|
|
return INDEX_ERROR;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CPtrXBF::DeletePtr(
|
|
DWORD i
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Delete a ptr from array
|
|
|
|
Arguments:
|
|
|
|
i - index of ptr to delete
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
memmove( GetBuff()+i*sizeof(LPVOID),
|
|
GetBuff()+(i+1)*sizeof(LPVOID),
|
|
GetUsed()-(i+1)*sizeof(LPVOID) );
|
|
|
|
DecreaseUse( sizeof(LPVOID) );
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CPtrXBF::Unserialize(
|
|
LPBYTE* ppB,
|
|
LPDWORD pC,
|
|
DWORD cNbEntry
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unserialize a ptr array
|
|
|
|
Arguments:
|
|
|
|
ppB - ptr to addr of buffer to unserialize from
|
|
pC - ptr to count of bytes in buffer
|
|
cNbEntry - # of ptr to unserialize from buffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
Reset();
|
|
if ( *pC >= cNbEntry * sizeof(LPVOID) &&
|
|
Append( *ppB, cNbEntry * sizeof(LPVOID) ) )
|
|
{
|
|
*ppB += cNbEntry * sizeof(LPVOID);
|
|
*pC -= cNbEntry * sizeof(LPVOID);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CPtrXBF::Serialize(
|
|
CStoreXBF* pX
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Serialize a ptr array
|
|
|
|
Arguments:
|
|
|
|
pX - ptr to CStoreXBF to serialize to
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
return pX->Append( (LPBYTE)GetBuff(), (DWORD)GetUsed() );
|
|
}
|
|
|
|
|
|
BOOL
|
|
CAllocString::Set(
|
|
LPWSTR pS
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Set a string content, freeing prior content if any
|
|
|
|
Arguments:
|
|
|
|
pS - string to copy
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
size_t l;
|
|
Reset();
|
|
if ( m_pStr = (LPWSTR)LocalAlloc( LMEM_FIXED, l = (wcslen(pS)+1)*sizeof(WCHAR) ) )
|
|
{
|
|
memcpy( m_pStr, pS, l );
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CAllocString::Append(
|
|
LPWSTR pS
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Append a string content
|
|
|
|
Arguments:
|
|
|
|
pS - string to append
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
size_t l = m_pStr ? wcslen(m_pStr )*sizeof(WCHAR) : 0;
|
|
size_t nl;
|
|
LPWSTR pStr;
|
|
|
|
if ( pStr = (LPWSTR)LocalAlloc( LMEM_FIXED, l + (nl = (wcslen(pS)+1)*sizeof(WCHAR) )) )
|
|
{
|
|
memcpy( pStr, m_pStr, l );
|
|
memcpy( pStr+l/sizeof(WCHAR), pS, nl );
|
|
|
|
m_pStr = pStr;
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CAllocString::Unserialize(
|
|
LPBYTE* ppb,
|
|
LPDWORD pc
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unserialize a string
|
|
|
|
Arguments:
|
|
|
|
ppB - ptr to addr of buffer to unserialize from
|
|
pC - ptr to count of bytes in buffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
DWORD dwL;
|
|
|
|
if ( ::Unserialize( ppb, pc, &dwL ) &&
|
|
(m_pStr = (LPWSTR)LocalAlloc( LMEM_FIXED, (dwL + 1) * sizeof(WCHAR))) )
|
|
{
|
|
memcpy( m_pStr, *ppb, dwL*sizeof(WCHAR) );
|
|
m_pStr[dwL] = L'\0';
|
|
|
|
*ppb += dwL*sizeof(WCHAR);
|
|
*pc -= dwL*sizeof(WCHAR);
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CAllocString::Serialize(
|
|
CStoreXBF* pX
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Serialize a string
|
|
|
|
Arguments:
|
|
|
|
pX - ptr to CStoreXBF to serialize to
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
LPWSTR pS = m_pStr ? m_pStr : L"";
|
|
|
|
return ::Serialize( pX, (DWORD)wcslen(pS) ) && pX->Append( pS );
|
|
}
|
|
|
|
|
|
BOOL
|
|
CBlob::Set(
|
|
LPBYTE pStr,
|
|
DWORD cStr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Store a buffer in a blob object
|
|
buffer is copied inside blob
|
|
blob is reset before copy
|
|
|
|
Arguments:
|
|
|
|
pStr - ptr to buffer to copy
|
|
cStr - length of buffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
Reset();
|
|
|
|
return InitSet( pStr, cStr);
|
|
}
|
|
|
|
|
|
BOOL
|
|
CBlob::InitSet(
|
|
LPBYTE pStr,
|
|
DWORD cStr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Store a buffer in a blob object
|
|
buffer is copied inside blob
|
|
blob is not reset before copy, initial blob content ignored
|
|
|
|
Arguments:
|
|
|
|
pStr - ptr to buffer to copy
|
|
cStr - length of buffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
if ( m_pStr = (LPBYTE)LocalAlloc( LMEM_FIXED, cStr ) )
|
|
{
|
|
memcpy( m_pStr, pStr, cStr );
|
|
m_cStr = cStr;
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CBlob::Unserialize(
|
|
LPBYTE* ppB,
|
|
LPDWORD pC
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unserialize a blob
|
|
|
|
Arguments:
|
|
|
|
ppB - ptr to addr of buffer to unserialize from
|
|
pC - ptr to count of bytes in buffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
Reset();
|
|
|
|
if ( ::Unserialize( ppB, pC, &m_cStr ) &&
|
|
*pC >= m_cStr &&
|
|
( m_pStr = (LPBYTE)LocalAlloc( LMEM_FIXED, m_cStr ) ) )
|
|
{
|
|
memcpy( m_pStr, *ppB, m_cStr );
|
|
|
|
*ppB += m_cStr;
|
|
*pC -= m_cStr;
|
|
}
|
|
else
|
|
{
|
|
m_cStr = 0;
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CBlob::Serialize(
|
|
CStoreXBF* pX
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Serialize a blob
|
|
|
|
Arguments:
|
|
|
|
pX - ptr to CStoreXBF to serialize to
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
return ::Serialize( pX, m_cStr ) &&
|
|
pX->Append( m_pStr, m_cStr );
|
|
}
|
|
|
|
|
|
CStrPtrXBF::~CStrPtrXBF(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
CStrPtrXBF destructor
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
Nothing
|
|
|
|
--*/
|
|
{
|
|
DWORD iM = GetNbPtr();
|
|
UINT i;
|
|
for ( i = 0 ; i < iM ; ++i )
|
|
{
|
|
((CAllocString*)GetPtrAddr(i))->Reset();
|
|
}
|
|
}
|
|
|
|
|
|
DWORD
|
|
CStrPtrXBF::AddEntry(
|
|
LPWSTR pS
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Add a string to array
|
|
string content is copied in array
|
|
|
|
Arguments:
|
|
|
|
pS - string to be added at end of array
|
|
|
|
Return Value:
|
|
|
|
index ( 0-based ) in array where added or INDEX_ERROR if error
|
|
|
|
--*/
|
|
{
|
|
DWORD i;
|
|
|
|
if ( (i = AddPtr( NULL )) != INDEX_ERROR )
|
|
{
|
|
return ((CAllocString*)GetPtrAddr(i))->Set( pS ) ? i : INDEX_ERROR;
|
|
}
|
|
return INDEX_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
CStrPtrXBF::InsertEntry(
|
|
DWORD iBefore,
|
|
LPWSTR pS
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Insert a string in array
|
|
string content is copied in array
|
|
|
|
Arguments:
|
|
|
|
iBefore - index where to insert entry, or 0xffffffff if add to array
|
|
pS - string to be inserted in array
|
|
|
|
Return Value:
|
|
|
|
index ( 0-based ) in array where added or INDEX_ERROR if error
|
|
|
|
--*/
|
|
{
|
|
DWORD i;
|
|
|
|
if ( (i = InsertPtr( iBefore, NULL )) != INDEX_ERROR )
|
|
{
|
|
return ((CAllocString*)GetPtrAddr(i))->Set( pS ) ? i : INDEX_ERROR;
|
|
}
|
|
return INDEX_ERROR;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CStrPtrXBF::DeleteEntry(
|
|
DWORD i
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Delete a string from array
|
|
|
|
Arguments:
|
|
|
|
i - index of string to delete
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
if ( i < GetNbPtr() )
|
|
{
|
|
((CAllocString*)GetPtrAddr(i))->Reset();
|
|
DeletePtr( i );
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CStrPtrXBF::Unserialize(
|
|
LPBYTE* ppB,
|
|
LPDWORD pC,
|
|
DWORD cNbEntry
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unserialize a string array
|
|
|
|
Arguments:
|
|
|
|
ppB - ptr to addr of buffer
|
|
pC - ptr to byte count in buffer
|
|
cNbEntry - # of entry to unserialize
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
UINT i;
|
|
|
|
Reset();
|
|
|
|
CAllocString empty;
|
|
for ( i = 0 ; i < cNbEntry ; ++i )
|
|
{
|
|
if ( !Append( (LPBYTE)&empty, sizeof(empty)) ||
|
|
!((CAllocString*)GetPtrAddr(i))->Unserialize( ppB, pC ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CStrPtrXBF::Serialize(
|
|
CStoreXBF* pX
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Serialize a string array
|
|
|
|
Arguments:
|
|
|
|
pX - ptr to CStoreXBF where to add serialized DWORD
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
UINT i;
|
|
|
|
for ( i = 0 ; i < GetNbEntry() ; ++i )
|
|
{
|
|
if ( !((CAllocString*)GetPtrAddr(i))->Serialize( pX ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
CBlobXBF::~CBlobXBF(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
CBlobXBF destructor
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
Nothing
|
|
|
|
--*/
|
|
{
|
|
DWORD iM = GetUsed()/sizeof(CBlob);
|
|
UINT i;
|
|
for ( i = 0 ; i < iM ; ++i )
|
|
{
|
|
GetBlob(i)->Reset();
|
|
}
|
|
}
|
|
|
|
|
|
VOID CBlobXBF::Reset(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Reset the blob content to NULL
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
Nothing
|
|
|
|
--*/
|
|
{
|
|
DWORD iM = GetUsed()/sizeof(CBlob);
|
|
UINT i;
|
|
for ( i = 0 ; i < iM ; ++i )
|
|
{
|
|
GetBlob(i)->Reset();
|
|
}
|
|
CStoreXBF::Reset();
|
|
}
|
|
|
|
|
|
DWORD
|
|
CBlobXBF::AddEntry(
|
|
LPBYTE pS,
|
|
DWORD cS
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Add a buffer to blob array
|
|
buffer content is copied in array
|
|
|
|
Arguments:
|
|
|
|
pS - buffer to be added at end of array
|
|
cS - length of buffer
|
|
|
|
Return Value:
|
|
|
|
index ( 0-based ) in array where added or INDEX_ERROR if error
|
|
|
|
--*/
|
|
{
|
|
DWORD i = GetNbEntry();
|
|
|
|
if ( Append( (LPBYTE)&pS, sizeof(CBlob) ) )
|
|
{
|
|
return GetBlob(i)->InitSet( pS, cS ) ? i : INDEX_ERROR;
|
|
}
|
|
return INDEX_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
CBlobXBF::InsertEntry(
|
|
DWORD iBefore,
|
|
LPBYTE pS,
|
|
DWORD cS
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Insert a buffer in blob array
|
|
buffer content is copied in array
|
|
|
|
Arguments:
|
|
|
|
iBefore - index where to insert entry, or 0xffffffff if add to array
|
|
pS - buffer to be inserted in array
|
|
cS - length of buffer
|
|
|
|
Return Value:
|
|
|
|
index ( 0-based ) in array where added or INDEX_ERROR if error
|
|
|
|
--*/
|
|
{
|
|
DWORD i;
|
|
|
|
if ( iBefore == INDEX_ERROR || iBefore >= GetNbEntry() )
|
|
{
|
|
return AddEntry( (LPBYTE)pS, cS );
|
|
}
|
|
|
|
if ( iBefore < GetNbEntry() && Append( (LPBYTE)&pS, sizeof(CBlob) ) )
|
|
{
|
|
memmove( GetBuff()+(iBefore+1)*sizeof(CBlob),
|
|
GetBuff()+iBefore*sizeof(CBlob),
|
|
GetUsed()-(iBefore+1)*sizeof(CBlob) );
|
|
|
|
return GetBlob(iBefore)->InitSet( (LPBYTE)pS, cS ) ? iBefore : INDEX_ERROR;
|
|
}
|
|
return INDEX_ERROR;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CBlobXBF::DeleteEntry(
|
|
DWORD i
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Delete a entry from blob array
|
|
|
|
Arguments:
|
|
|
|
i - index of string to delete
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
if ( i < GetNbEntry() )
|
|
{
|
|
GetBlob(i)->Reset();
|
|
|
|
memmove( GetBuff()+i*sizeof(CBlob),
|
|
GetBuff()+(i+1)*sizeof(CBlob),
|
|
GetUsed()-(i+1)*sizeof(CBlob) );
|
|
|
|
DecreaseUse( sizeof(CBlob) );
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CBlobXBF::Unserialize(
|
|
LPBYTE* ppB,
|
|
LPDWORD pC,
|
|
DWORD cNbEntry )
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unserialize a blob array
|
|
|
|
Arguments:
|
|
|
|
ppB - ptr to addr of buffer to unserialize from
|
|
pC - ptr to count of bytes in buffer
|
|
cNbEntry - # of ptr to unserialize from buffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if success, otherwise FALSE
|
|
|
|
--*/
|
|
{
|
|
UINT i;
|
|
|
|
Reset();
|
|
|
|
CBlob empty;
|
|
for ( i = 0 ; i < cNbEntry ; ++i )
|
|
{
|
|
if ( !Append( (LPBYTE)&empty, sizeof(empty) ) ||
|
|
!GetBlob(i)->Unserialize( ppB, pC ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CBlobXBF::Serialize(
|
|
CStoreXBF* pX
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Serialize a blob array
|
|
|
|
Arguments:
|
|
|
|
pX - ptr to CStoreXBF where to add serialized blob
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE on error
|
|
|
|
--*/
|
|
{
|
|
UINT i;
|
|
|
|
for ( i = 0 ; i < GetNbEntry() ; ++i )
|
|
{
|
|
if ( !GetBlob(i)->Serialize( pX ) )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|