|
|
/*++
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; }
|