Renamed version4 to flaim and version5 to xflaim

git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@7 0109f412-320b-0410-ab79-c3e0c5ffbbe6
This commit is contained in:
dsandersoremutah
2006-01-27 21:06:39 +00:00
parent 4072ed64c8
commit c55dab446f
612 changed files with 0 additions and 0 deletions

898
flaim/src/fcs_dos.cpp Normal file
View File

@@ -0,0 +1,898 @@
//-------------------------------------------------------------------------
// Desc: Data output stream class.
// Tabs: 3
//
// Copyright (c) 1998-2006 Novell, Inc. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the GNU General Public
// License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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, contact Novell, Inc.
//
// To contact Novell about this file by physical or electronic mail,
// you may find current contact information at www.novell.com
//
// $Id: fcs_dos.cpp 12329 2006-01-20 17:49:30 -0700 (Fri, 20 Jan 2006) ahodgkinson $
//-------------------------------------------------------------------------
#include "flaimsys.h"
/****************************************************************************
Desc:
****************************************************************************/
FCS_DOS::FCS_DOS( void)
{
m_pOStream = NULL;
m_uiBOffset = 0;
GedPoolInit( &m_tmpPool, 512);
m_bSetupCalled = FALSE;
}
/****************************************************************************
Desc:
****************************************************************************/
FCS_DOS::~FCS_DOS( void)
{
if( m_bSetupCalled)
{
(void)close();
}
GedPoolFree( &m_tmpPool);
}
/****************************************************************************
Desc: Writes a specified number of bytes from a buffer to the output
stream.
****************************************************************************/
RCODE FCS_DOS::write(
FLMBYTE * pucData,
FLMUINT uiLength)
{
RCODE rc = FERR_OK;
/*
Verify that setup has been called.
*/
flmAssert( m_bSetupCalled == TRUE);
/*
Write the data.
*/
Retry_Write:
if( FCS_DOS_BUFFER_SIZE - m_uiBOffset >= uiLength)
{
#if defined( FLM_NLM) || defined( FLM_WIN)
if( uiLength == 1)
{
m_pucBuffer[ m_uiBOffset] = *pucData;
m_uiBOffset++;
}
else if( uiLength == 2)
{
*(FLMUINT16 *)&(m_pucBuffer[ m_uiBOffset]) = *((FLMUINT16 *)pucData);
m_uiBOffset += 2;
}
else if( uiLength == 4)
{
*(FLMUINT32 *)&(m_pucBuffer[ m_uiBOffset]) = *((FLMUINT32 *)pucData);
m_uiBOffset += 4;
}
else
{
f_memcpy( &(m_pucBuffer[ m_uiBOffset]), pucData, uiLength);
m_uiBOffset += uiLength;
}
#else
f_memcpy( &(m_pucBuffer[ m_uiBOffset]), pucData, uiLength);
m_uiBOffset += uiLength;
#endif
}
else
{
if( m_uiBOffset > 0)
{
if( RC_BAD( rc = flush()))
{
goto Exit;
}
}
if( uiLength <= FCS_DOS_BUFFER_SIZE)
{
goto Retry_Write;
}
if( RC_BAD( rc = m_pOStream->write( pucData, uiLength)))
{
goto Exit;
}
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Writes a UNICODE string to the stream in the UTF-8 format.
****************************************************************************/
RCODE FCS_DOS::writeUTF(
FLMUNICODE * puzValue)
{
FLMUINT uiUTFLen;
FLMUNICODE * puzTmp;
RCODE rc = FERR_OK;
/*
Verify that setup has been called.
*/
flmAssert( m_bSetupCalled == TRUE);
/*
Verify pValue is valid.
*/
flmAssert( puzValue != NULL);
/*
Determine the size of the string.
*/
uiUTFLen = 0;
puzTmp = puzValue;
while( *puzTmp)
{
uiUTFLen++;
puzTmp++;
}
if( RC_BAD( rc = writeUShort( (FLMUINT16)uiUTFLen)))
{
goto Exit;
}
puzTmp = puzValue;
while( *puzTmp)
{
if( *puzTmp <= 0x007F)
{
if( RC_BAD( rc = writeByte( (FLMBYTE)(*puzTmp))))
{
goto Exit;
}
}
else if( *puzTmp >= 0x0080 && *puzTmp <= 0x07FF)
{
if( RC_BAD( rc = writeUShort((FLMUINT16)
((((FLMUINT16)(0xC0 | (FLMBYTE)((*puzTmp & 0x07C0) >> 6))) << 8) |
(FLMUINT16)(0x80 | (FLMBYTE)(*puzTmp & 0x003F))))))
{
goto Exit;
}
}
else
{
if( RC_BAD( rc = writeUShort((FLMUINT16)
((((FLMUINT16)(0xE0 | (FLMBYTE)((*puzTmp & 0xF000) >> 12))) << 8) |
(FLMUINT16)(0x80 | (FLMBYTE)((*puzTmp & 0x0FC0) >> 6))))))
{
goto Exit;
}
if( RC_BAD( rc = writeByte( (0x80 | (FLMBYTE)(*puzTmp & 0x003F)))))
{
goto Exit;
}
}
puzTmp++;
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Writes a binary token (including length) to the stream.
****************************************************************************/
RCODE FCS_DOS::writeBinary(
FLMBYTE * pucValue,
FLMUINT uiSize)
{
RCODE rc = FERR_OK;
flmAssert( uiSize <= 0x0000FFFF);
if( RC_BAD( rc = writeUShort( (FLMUINT16)uiSize)))
{
goto Exit;
}
if( uiSize)
{
if( RC_BAD( rc = write( pucValue, uiSize)))
{
goto Exit;
}
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Writes a large binary token (including length) to the stream.
****************************************************************************/
RCODE FCS_DOS::writeLargeBinary(
FLMBYTE * pucValue,
FLMUINT uiSize)
{
RCODE rc = FERR_OK;
if( RC_BAD( rc = writeUInt32( (FLMUINT32)uiSize)))
{
goto Exit;
}
if( uiSize)
{
if( RC_BAD( rc = write( pucValue, uiSize)))
{
goto Exit;
}
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Writes a Hierarchical Tagged Data record to the stream.
****************************************************************************/
RCODE FCS_DOS::writeHTD(
NODE * pHTD,
FlmRecord * pRecord,
FLMBOOL bSendForest,
FLMBOOL bSendAsGedcom)
{
FLMUINT uiPrevLevel = 0;
FLMUINT uiLevelsBack = 0;
FLMUINT uiDescriptor = 0;
FLMUINT uiCurLevel = 0;
FLMUINT uiCurValType = 0;
FLMUINT uiCurDataLen = 0;
FLMBOOL bLeftTruncated;
FLMBOOL bRightTruncated;
FLMBYTE * pucCurData = NULL;
FLMBYTE pucTmpBuf[ 32];
void * pvMark = GedPoolMark( &m_tmpPool);
NODE * pCurNode = NULL;
void * pCurField = NULL;
RCODE rc = FERR_OK;
/*
Verify that setup has been called.
*/
flmAssert( m_bSetupCalled == TRUE);
/*
Set the current node or field
*/
if( pHTD)
{
pCurNode = pHTD;
}
else
{
pCurField = pRecord->root();
}
while( pCurNode || pCurField)
{
/*
See if we are done sending the tree/forest.
*/
if( pCurNode)
{
if( !bSendForest && (pCurNode != pHTD) &&
(GedNodeLevel( pCurNode) == GedNodeLevel( pHTD)))
{
break;
}
}
/*
Output the attribute's tag number.
*/
if( pCurNode)
{
intToByte( (FLMUINT16)GedTagNum( pCurNode), pucTmpBuf);
}
else if( pCurField)
{
intToByte( (FLMUINT16)pRecord->getFieldID( pCurField), pucTmpBuf);
}
if( RC_BAD( rc = write( pucTmpBuf, 2)))
{
goto Exit;
}
/*
Setup the attribute's descriptor.
*/
uiDescriptor = 0;
uiLevelsBack = 0;
if( pCurNode)
{
uiCurLevel = GedNodeLevel( pCurNode);
}
else
{
uiCurLevel = pRecord->getLevel( pCurField);
}
if( uiCurLevel == uiPrevLevel)
{
(void)(uiDescriptor |= (HTD_LEVEL_SIBLING << HTD_LEVEL_POS));
}
else if( uiCurLevel == uiPrevLevel + 1)
{
uiDescriptor |= (HTD_LEVEL_CHILD << HTD_LEVEL_POS);
}
else if( uiCurLevel == uiPrevLevel - 1)
{
uiDescriptor |= (HTD_LEVEL_BACK << HTD_LEVEL_POS);
}
else if( uiCurLevel < uiPrevLevel)
{
uiDescriptor |= (HTD_LEVEL_BACK_X << HTD_LEVEL_POS);
uiLevelsBack = uiPrevLevel - uiCurLevel;
}
else
{
flmAssert( 0);
rc = RC_SET( FERR_FAILURE);
goto Exit;
}
if( pCurNode)
{
uiCurDataLen = GedValLen( pCurNode);
uiCurValType = GedValType( pCurNode) & 0x0F;
bLeftTruncated = GedIsLeftTruncated( pCurNode);
bRightTruncated = GedIsRightTruncated( pCurNode);
pucCurData = (FLMBYTE *)GedValPtr( pCurNode);
}
else
{
uiCurDataLen = pRecord->getDataLength( pCurField);
uiCurValType = (FLMUINT)pRecord->getDataType( pCurField);
bLeftTruncated = pRecord->isLeftTruncated( pCurField);
bRightTruncated = pRecord->isRightTruncated( pCurField);
pucCurData = (FLMBYTE *)(pRecord->getDataPtr( pCurField));
}
if( uiCurDataLen)
{
uiDescriptor |= HTD_HAS_VALUE_FLAG;
}
if( bSendAsGedcom)
{
uiDescriptor |= HTD_TYPE_GEDCOM;
}
else
{
switch( uiCurValType)
{
case FLM_TEXT_TYPE:
{
uiDescriptor |= HTD_TYPE_UNICODE;
break;
}
case FLM_NUMBER_TYPE:
{
/*
To save conversion time, cheat to determine if
the number is negative.
*/
if( ((*pucCurData & 0xF0) == 0xB0))
{
uiDescriptor |= HTD_TYPE_INT;
}
else
{
uiDescriptor |= HTD_TYPE_UINT;
}
break;
}
case FLM_CONTEXT_TYPE:
{
uiDescriptor |= HTD_TYPE_CONTEXT;
break;
}
case FLM_BINARY_TYPE:
{
uiDescriptor |= HTD_TYPE_BINARY;
break;
}
default:
{
rc = RC_SET( FERR_NOT_IMPLEMENTED);
goto Exit;
}
}
}
/*
Output the attribute's descriptor.
*/
pucTmpBuf[ 0] = (FLMBYTE)uiDescriptor;
if( RC_BAD( rc = write( pucTmpBuf, 1)))
{
goto Exit;
}
/*
Output the "levels back" value (if available).
*/
if( uiLevelsBack)
{
flmAssert( uiLevelsBack <= 0xFF);
pucTmpBuf[ 0] = (FLMBYTE)uiLevelsBack;
if( RC_BAD( rc = write( pucTmpBuf, 1)))
{
goto Exit;
}
}
/*
Output the attribute's value.
*/
if( bSendAsGedcom)
{
/*
Output the GEDCOM data type and flags
*/
pucTmpBuf[ 0] = (FLMBYTE)uiCurValType;
if( bLeftTruncated)
{
pucTmpBuf[ 0] |= 0x10;
}
if( bRightTruncated)
{
pucTmpBuf[ 0] |= 0x20;
}
if( RC_BAD( rc = write( pucTmpBuf, 1)))
{
goto Exit;
}
if( uiCurDataLen)
{
/*
Output the data size.
*/
flmAssert( uiCurDataLen <= 0x0000FFFF);
intToByte( (FLMUINT16)uiCurDataLen, pucTmpBuf);
if( RC_BAD( rc = write( pucTmpBuf, 2)))
{
goto Exit;
}
/*
Send the data.
*/
if( RC_BAD( rc = write( pucCurData, uiCurDataLen)))
{
goto Exit;
}
}
}
else
{
/*
Send the value.
*/
switch( uiCurValType)
{
case FLM_TEXT_TYPE:
{
/*
Extract the value.
*/
if( uiCurDataLen)
{
FLMUINT uiBufSize;
FLMUNICODE * puzValue;
/*
Reset the temporary pool.
*/
GedPoolReset( &m_tmpPool, pvMark);
if( uiCurDataLen <= 32751)
{
/*
Allocate a buffer that is twice the size of the
attribute's value length. This is necessary because the
UNICODE conversion will may double the size of the
attribute's value. A "safety" zone of 32 bytes is added
to the buffer size to allow for strings that may require
more than 2x the attribute's size and to account for
null-termination bytes.
*/
uiBufSize = (2 * uiCurDataLen) + 32;
}
else
{
/*
Allocate a full 64K.
*/
uiBufSize = 65535;
}
if( (puzValue = (FLMUNICODE *)GedPoolAlloc( &m_tmpPool,
uiBufSize)) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
/*
Extract UNICODE from the attribute.
*/
if( (pCurNode && RC_BAD( rc = GedGetUNICODE( pCurNode, puzValue, &uiBufSize))) ||
(pCurField && RC_BAD( rc = pRecord->getUnicode( pCurField, puzValue, &uiBufSize))))
{
if( rc == FERR_CONV_DEST_OVERFLOW)
{
/*
Since we did not correctly guess the buffer size,
try again. This time, take the slow (but safe)
approach of calculating the size of the UNICODE string.
*/
if( (pCurNode && RC_BAD( rc = GedGetUNICODE( pCurNode, NULL, &uiBufSize))) ||
(pCurField && RC_BAD( rc = pRecord->getUnicodeLength( pCurField, &uiBufSize))))
{
goto Exit;
}
/*
Add two bytes to account for null-termination.
*/
uiBufSize += 2;
/*
Reset the pool to clear the prior allocation.
*/
GedPoolReset( &m_tmpPool, pvMark);
/*
Allocate the new buffer.
*/
if( (puzValue = (FLMUNICODE *)GedPoolAlloc( &m_tmpPool,
uiBufSize)) == NULL)
{
rc = RC_SET( FERR_MEM);
goto Exit;
}
/*
Extract the UNICODE string.
*/
if( (pCurNode && RC_BAD( rc = GedGetUNICODE(
pCurNode, puzValue, &uiBufSize))) ||
(pCurField && RC_BAD( rc = pRecord->getUnicode(
pCurField, puzValue, &uiBufSize))))
{
goto Exit;
}
}
else
{
goto Exit;
}
}
/*
Write the attribute's value.
*/
if( RC_BAD( rc = writeUTF( puzValue)))
{
goto Exit;
}
}
break;
}
case FLM_NUMBER_TYPE:
{
if( uiCurDataLen)
{
if( uiDescriptor & HTD_TYPE_INT)
{
/*
Since the number is negative, extract and send it
as a signed 32-bit value.
*/
FLMINT iValue;
if( (pCurNode && RC_BAD( rc = GedGetINT( pCurNode, &iValue))) ||
(pCurField && RC_BAD( rc = pRecord->getINT( pCurField, &iValue))))
{
goto Exit;
}
/*
Write the value.
*/
if( RC_BAD( rc = writeInt32( (FLMINT32)iValue)))
{
goto Exit;
}
}
else
{
/*
The number is non-negative
*/
FLMUINT uiValue;
if( (pCurNode && RC_BAD( rc = GedGetUINT( pCurNode, &uiValue))) ||
(pCurField && RC_BAD( rc = pRecord->getUINT( pCurField, &uiValue))))
{
goto Exit;
}
/*
Write the value.
*/
if( RC_BAD( rc = writeUInt32( (FLMUINT32)uiValue)))
{
goto Exit;
}
}
}
break;
}
case FLM_CONTEXT_TYPE:
{
/*
Extract the value.
*/
if( uiCurDataLen)
{
/*
The context node has a DRN value associated with
it. Send the value as an unsigned 32-bit number.
*/
FLMUINT uiDrn;
if( (pCurNode && RC_BAD( rc = GedGetRecPtr( pCurNode, &uiDrn))) ||
(pCurField && RC_BAD( rc = pRecord->getUINT( pCurField, &uiDrn))))
{
goto Exit;
}
if( RC_BAD( rc = writeUInt32( (FLMUINT32)uiDrn)))
{
goto Exit;
}
}
break;
}
case FLM_BINARY_TYPE:
{
/*
Extract the value.
*/
if( uiCurDataLen)
{
if( RC_BAD( rc = writeUShort( (FLMUINT16)uiCurDataLen)))
{
goto Exit;
}
if( RC_BAD( rc = write( pucCurData, uiCurDataLen)))
{
goto Exit;
}
}
break;
}
default:
{
rc = RC_SET( FERR_NOT_IMPLEMENTED);
goto Exit;
}
}
}
uiPrevLevel = uiCurLevel;
if( pCurNode)
{
pCurNode = GedNodeNext( pCurNode);
}
else
{
pCurField = pRecord->next( pCurField);
}
}
/*
Write a zero tag to indicate the end of the transmission.
*/
if( RC_BAD( rc = writeUShort( 0)))
{
goto Exit;
}
Exit:
GedPoolReset( &m_tmpPool, pvMark);
return( rc);
}
/****************************************************************************
Desc: Flushes any pending data and closes the stream.
****************************************************************************/
RCODE FCS_DOS::close( void)
{
RCODE rc = FERR_OK;
/*
Verify that setup has been called.
*/
flmAssert( m_bSetupCalled == TRUE);
/*
Flush and terminate any pending message.
*/
if( RC_BAD( rc = endMessage()))
{
goto Exit;
}
Exit:
return( rc);
}
/****************************************************************************
Desc: Flushes pending data.
****************************************************************************/
RCODE FCS_DOS::flush( void)
{
/*
Verify that setup has been called.
*/
flmAssert( m_bSetupCalled == TRUE);
/*
Flush the output buffer.
*/
if( m_uiBOffset > 0)
{
m_pOStream->write( m_pucBuffer, m_uiBOffset);
m_uiBOffset = 0;
}
/*
Flush the parent stream.
*/
return( m_pOStream->flush());
}
/****************************************************************************
Desc: Flushes and terminates the current parent stream message
****************************************************************************/
RCODE FCS_DOS::endMessage( void)
{
RCODE rc = FERR_OK;
/*
Verify that Setup has been called.
*/
flmAssert( m_bSetupCalled == TRUE);
if( !m_pOStream)
{
rc = RC_SET( FERR_FAILURE);
goto Exit;
}
/*
Flush any pending data.
*/
if( RC_BAD( rc = flush()))
{
goto Exit;
}
/*
Terminate the message.
*/
if( RC_BAD( rc = m_pOStream->endMessage()))
{
goto Exit;
}
Exit:
return( rc);
}