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:
898
flaim/src/fcs_dos.cpp
Normal file
898
flaim/src/fcs_dos.cpp
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user