From c8016f0b2d195f9304985299ff7fcc5e87470cca Mon Sep 17 00:00:00 2001 From: ahodgkinson Date: Thu, 27 Apr 2006 19:40:44 +0000 Subject: [PATCH] Got rid of DOM code. git-svn-id: https://svn.code.sf.net/p/flaim/code/trunk@361 0109f412-320b-0410-ab79-c3e0c5ffbbe6 --- ftk/src/ftk.h | 626 +--- ftk/src/ftkerror.cpp | 14 +- ftk/src/ftksys.h | 63 - ftk/src/ftkxml.cpp | 6953 ------------------------------------------ 4 files changed, 82 insertions(+), 7574 deletions(-) diff --git a/ftk/src/ftk.h b/ftk/src/ftk.h index f181b87..ea6b33a 100644 --- a/ftk/src/ftk.h +++ b/ftk/src/ftk.h @@ -400,7 +400,6 @@ flminterface IF_LogMessageClient; flminterface IF_Thread; flminterface IF_IOBuffer; - flminterface IF_DOMNode; /**************************************************************************** CROSS PLATFORM DEFINITIONS @@ -639,95 +638,6 @@ FLM_ATTRIBUTE } eNodeInsertLoc; - /**************************************************************************** - Desc: XML - ****************************************************************************/ - typedef enum - { - FLM_XML_UTF8_ENCODING, - FLM_XML_USASCII_ENCODING - } XMLEncoding; - - typedef enum - { - XML_NO_ERROR = 0, - XML_ERR_BAD_ELEMENT_NAME, // 1 Invalid element name - does not start with a valid character for element names - XML_ERR_XMLNS_IN_ELEMENT_NAME, // 2 Element names cannot be "xmlns" or have "xmlns:" as a prefix - XML_ERR_ELEMENT_NAME_MISMATCH, // 3 The element name inside the "' - XML_ERR_EXPECTING_ELEMENT_LT, // 6 Expecting a '<' to begin an element name - XML_ERR_EXPECTING_EQ, // 7 Expecting a '=' after the attribute name - XML_ERR_MULTIPLE_XMLNS_DECLS, // 8 Multiple "xmlns" default namespace declarations in an element - XML_ERR_MULTIPLE_PREFIX_DECLS, // 9 Multiple definitions for the same prefix ("xmlns:prefix=...") in an element - XML_ERR_EXPECTING_QUEST_GT, // 10 Expecting "?>" to terminate "poolReset( NULL); - } - - RCODE allocAttribute( - XML_ATTR ** ppAttr) - { - XML_ATTR * pAttr = NULL; - RCODE rc = NE_FLM_OK; - - if( RC_BAD( rc = m_pAttrPool->poolCalloc( - sizeof( XML_ATTR), (void **)&pAttr))) - { - goto Exit; - } - - if( (pAttr->pPrev = m_pLastAttr) == NULL) - { - m_pFirstAttr = pAttr; - } - else - { - m_pLastAttr->pNext = pAttr; - } - - m_pLastAttr = pAttr; - - Exit: - - *ppAttr = pAttr; - return( rc); - } - - RCODE setPrefix( - XML_ATTR * pAttr, - FLMUNICODE * puzPrefix) - { - RCODE rc = NE_FLM_OK; - FLMUINT uiStrLen; - - if( !puzPrefix) - { - pAttr->puzPrefix = NULL; - goto Exit; - } - - uiStrLen = f_unilen( puzPrefix); - - if( RC_BAD( rc = m_pAttrPool->poolAlloc( - sizeof( FLMUNICODE) * (uiStrLen + 1), (void **)&pAttr->puzPrefix))) - { - goto Exit; - } - - f_memcpy( pAttr->puzPrefix, puzPrefix, - sizeof( FLMUNICODE) * (uiStrLen + 1)); - - Exit: - - return( rc); - } - - RCODE setLocalName( - XML_ATTR * pAttr, - FLMUNICODE * puzLocalName) - { - RCODE rc = NE_FLM_OK; - FLMUINT uiStrLen; - - if( !puzLocalName) - { - pAttr->puzLocalName = NULL; - goto Exit; - } - - uiStrLen = f_unilen( puzLocalName); - - if( RC_BAD( rc = m_pAttrPool->poolAlloc( - sizeof( FLMUNICODE) * (uiStrLen + 1), - (void **)&pAttr->puzLocalName))) - { - goto Exit; - } - - f_memcpy( pAttr->puzLocalName, puzLocalName, - sizeof( FLMUNICODE) * (uiStrLen + 1)); - - Exit: - - return( rc); - } - - RCODE setUnicode( - XML_ATTR * pAttr, - FLMUNICODE * puzUnicode) - { - RCODE rc = NE_FLM_OK; - FLMUINT uiStrLen; - - if( !puzUnicode) - { - pAttr->puzVal = NULL; - goto Exit; - } - - uiStrLen = f_unilen( puzUnicode); - - if( RC_BAD( rc = m_pAttrPool->poolAlloc( - sizeof( FLMUNICODE) * (uiStrLen + 1), - (void **)&pAttr->puzVal))) - { - goto Exit; - } - - f_memcpy( pAttr->puzVal, puzUnicode, - sizeof( FLMUNICODE) * (uiStrLen + 1)); - - Exit: - - return( rc); - } - - RCODE addAttributesToElement( - IF_DOMNode * pElement); - - FINLINE void setErrInfo( - FLMUINT uiErrLineNum, - FLMUINT uiErrLineOffset, - XMLParseError eErrorType, - FLMUINT uiErrLineFilePos, - FLMUINT uiErrLineBytes) - { - m_importStats.uiErrLineNum = uiErrLineNum; - m_importStats.uiErrLineOffset = uiErrLineOffset; - m_importStats.eErrorType = eErrorType; - m_importStats.uiErrLineFilePos = uiErrLineFilePos; - m_importStats.uiErrLineBytes = uiErrLineBytes; - } - - FLMBYTE m_ucUngetByte; - FLMUNICODE * m_puzCurrLineBuf; - FLMUINT m_uiCurrLineBufMaxChars; - FLMUINT m_uiCurrLineNumChars; - FLMUINT m_uiCurrLineOffset; - FLMUINT m_uiCurrLineNum; - FLMUINT m_uiCurrLineFilePos; - FLMUINT m_uiCurrLineBytes; -#define FLM_XML_MAX_CHARS 128 - FLMUNICODE m_uChars[ FLM_XML_MAX_CHARS]; - FLMBOOL m_bSetup; - IF_IStream * m_pStream; - FLMBYTE * m_pucValBuf; - FLMUINT m_uiValBufSize; // Number of Unicode characters - FLMUINT m_uiFlags; - FLMBOOL m_bExtendDictionary; - XMLEncoding m_eXMLEncoding; - XML_STATUS_HOOK m_fnStatus; - void * m_pvCallbackData; - FLM_IMPORT_STATS m_importStats; - XML_ATTR * m_pFirstAttr; - XML_ATTR * m_pLastAttr; - IF_Pool * m_pTmpPool; - IF_Pool * m_pAttrPool; -}; - -#define FLM_XML_EXTEND_DICT_FLAG 0x00000001 -#define FLM_XML_COMPRESS_WHITESPACE_FLAG 0x00000002 -#define FLM_XML_TRANSLATE_ESC_FLAG 0x00000004 - -FINLINE FLMBOOL isXMLNS( - FLMUNICODE * puzName) -{ - return( (puzName [0] == FLM_UNICODE_x || puzName [0] == FLM_UNICODE_X) && - (puzName [1] == FLM_UNICODE_m || puzName [1] == FLM_UNICODE_M) && - (puzName [2] == FLM_UNICODE_l || puzName [2] == FLM_UNICODE_L) && - (puzName [3] == FLM_UNICODE_n || puzName [3] == FLM_UNICODE_N) && - (puzName [4] == FLM_UNICODE_s || puzName [4] == FLM_UNICODE_S) - ? TRUE - : FALSE); -} - /**************************************************************************** Desc: ****************************************************************************/ @@ -1349,6433 +826,3 @@ Exit: return( bValid); } -/**************************************************************************** -Desc: Constructor -****************************************************************************/ -F_XMLParser::F_XMLParser() -{ - m_uiValBufSize = 0; - m_pucValBuf = NULL; - m_bSetup = FALSE; - m_fnStatus = NULL; - m_pvCallbackData = NULL; - m_puzCurrLineBuf = NULL; - m_uiCurrLineBufMaxChars = 0; - m_pTmpPool = NULL; - m_pAttrPool = NULL; - - reset(); -} - -/**************************************************************************** -Desc: Destructor -****************************************************************************/ -F_XMLParser::~F_XMLParser() -{ - reset(); - - if( m_pucValBuf) - { - f_free( &m_pucValBuf); - } - - if (m_puzCurrLineBuf) - { - f_free( &m_puzCurrLineBuf); - } - - if( m_pTmpPool) - { - m_pTmpPool->Release(); - } - - if( m_pAttrPool) - { - m_pAttrPool->Release(); - } -} - -/**************************************************************************** -Desc: Resets member variables so the object can be reused -****************************************************************************/ -void FLMAPI F_XMLParser::reset( void) -{ - m_uiCurrLineNum = 0; - m_uiCurrLineNumChars = 0; - m_uiCurrLineOffset = 0; - m_ucUngetByte = 0; - m_uiCurrLineFilePos = 0; - m_uiCurrLineBytes = 0; - m_pStream = NULL; - m_uiFlags = 0; - m_eXMLEncoding = FLM_XML_USASCII_ENCODING; - f_memset( &m_importStats, 0, sizeof( FLM_IMPORT_STATS)); - - popNamespaces( getNamespaceCount()); - m_pTmpPool->poolReset( NULL); - resetAttrList(); -} - -/**************************************************************************** -Desc: Initializes the object (allocates buffers, etc.) -****************************************************************************/ -RCODE FLMAPI F_XMLParser::setup( void) -{ - RCODE rc = NE_FLM_OK; - - flmAssert( !m_bSetup); - - if( RC_BAD( rc = resizeValBuffer( 2048))) - { - goto Exit; - } - - if( RC_BAD( rc = F_XML::setup())) - { - goto Exit; - } - - if( RC_BAD( rc = FlmAllocPool( &m_pTmpPool))) - { - goto Exit; - } - - m_pTmpPool->poolInit( 4096); - - if( RC_BAD( rc = FlmAllocPool( &m_pAttrPool))) - { - goto Exit; - } - - m_pAttrPool->poolInit( 4096); - m_bSetup = TRUE; - -Exit: - - if( RC_BAD( rc)) - { - if( m_pucValBuf) - { - f_free( &m_pucValBuf); - m_pucValBuf = NULL; - } - } - - return( rc); -} - -/**************************************************************************** -Desc: Reads data from the input stream and builds a FLAIM record -****************************************************************************/ -RCODE FLMAPI F_XMLParser::import( - IF_IStream * pStream, - FLMUINT uiFlags, - IF_DOMNode * pNodeToLinkTo, - eNodeInsertLoc eInsertLoc, - IF_DOMNode ** ppNewNode, - FLM_IMPORT_STATS * pImportStats) -{ - RCODE rc = NE_FLM_OK; - - // Reset the state of the parser - - reset(); - - // Set up namespace support. Un-prefixed names (NULL prefix) are - // not bound to a namespace (NULL URI). The 'xml' namespace prefix - // is, by definition, bound to 'http://www.w3.org/XML/1998/namespace' - - if( RC_BAD( rc = pushNamespace( NULL, NULL))) - { - goto Exit; - } - - if( RC_BAD( rc = pushNamespace( - gv_puzXMLPrefix, gv_puzXMLNSURI))) - { - goto Exit; - } - - m_pStream = pStream; - m_uiFlags = uiFlags; - - if( RC_BAD( rc = processProlog())) - { - goto Exit; - } - - if( RC_BAD( rc = processElement( pNodeToLinkTo, eInsertLoc, ppNewNode))) - { - goto Exit; - } - - // Call the status hook one last time - - m_importStats.uiDocuments++; - if( m_fnStatus) - { - m_fnStatus( XML_STATS, - (void *)&m_importStats, NULL, NULL, m_pvCallbackData); - } - - // Tally and return the import stats - - if( pImportStats) - { - pImportStats->uiChars += m_importStats.uiChars; - pImportStats->uiAttributes += m_importStats.uiAttributes; - pImportStats->uiElements += m_importStats.uiElements; - pImportStats->uiText += m_importStats.uiText; - pImportStats->uiDocuments += m_importStats.uiDocuments; - } - -Exit: - - if( RC_BAD( rc) && pImportStats) - { - pImportStats->uiErrLineNum = m_importStats.uiErrLineNum - ? m_importStats.uiErrLineNum - : m_uiCurrLineNum; - - pImportStats->uiErrLineOffset = m_importStats.uiErrLineOffset - ? m_importStats.uiErrLineOffset - : m_uiCurrLineOffset; - - pImportStats->eErrorType = ( XMLParseError)( m_importStats.eErrorType); - - pImportStats->uiErrLineFilePos = m_importStats.uiErrLineFilePos; - pImportStats->uiErrLineBytes = m_importStats.uiErrLineBytes; - pImportStats->eXMLEncoding = m_importStats.eXMLEncoding; - } - - return( rc); -} - -/**************************************************************************** -Desc: Process an XML prolog -****************************************************************************/ -RCODE F_XMLParser::processProlog( void) -{ - RCODE rc = NE_FLM_OK; - - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - if (lineHasToken( "createNode( m_pDb, DATA_NODE, 0, -// FLM_LAST_CHILD, &pData))) -// { -// setErrInfo( m_uiCurrLineNum, -// m_uiCurrLineOffset, -// XML_ERR_CREATING_DATA_NODE, -// m_uiCurrLineFilePos, -// m_uiCurrLineBytes); -// goto Exit; -// } - - if( RC_BAD( rc = pParent->getDataType( &parentDataType))) - { - goto Exit; - } - - switch( parentDataType) - { - case FLM_TEXT_TYPE: - { -// if( RC_BAD( rc = pData->setUnicode( m_pDb, puzTextStart))) -// { -// goto Exit; -// } - - m_importStats.uiText++; - if( m_fnStatus && (m_importStats.uiText % 50) == 0) - { - m_fnStatus( XML_STATS, - (void *)&m_importStats, NULL, NULL, m_pvCallbackData); - } - - break; - } - - case FLM_NUMBER_TYPE: - { - FLMUINT64 ui64Val; - FLMBOOL bNeg; - - if( RC_BAD( rc = unicodeToNumber64( puzTextStart, &ui64Val, &bNeg))) - { - goto Exit; - } - - if( !bNeg) - { -// if( RC_BAD( rc = pData->setUINT64( m_pDb, ui64Val))) -// { -// goto Exit; -// } - } - else - { -// if( RC_BAD( rc = pData->setINT64( m_pDb, -((FLMINT64)ui64Val)))) -// { -// goto Exit; -// } - } - break; - } - - case FLM_BINARY_TYPE: - { -// if( RC_BAD( rc = pData->setBinary( m_pDb, pucValue, uiValueLen))) -// { -// goto Exit; -// } - break; - } - - default: - { - rc = RC_SET_AND_ASSERT( NE_FLM_NOT_IMPLEMENTED); - goto Exit; - } - } - -Exit: - - if( pData) - { - pData->Release(); - } - - return( rc); -} - -/**************************************************************************** -Desc: Processes an XML element -****************************************************************************/ -RCODE F_XMLParser::processElement( - IF_DOMNode * pNodeToLinkTo, - eNodeInsertLoc eInsertLoc, - IF_DOMNode ** ppNewNode) -{ - RCODE rc = NE_FLM_OK; - FLMBOOL bHasContent; - FLMBOOL bFlushedValue = FALSE; - FLMUINT uiChars; - FLMUINT uiOffset = 0; - FLMUNICODE uChar; - IF_DOMNode * pElement = NULL; - F_XMLNamespace * pNamespace = NULL; - FLMUNICODE * puzPrefix; - FLMUNICODE * puzLocal; - FLMUINT uiStartNSCount = getNamespaceCount(); - FLMUINT uiTmp; - FLMUINT uiWhitespaceStartOffset = 0; - FLMBOOL bNamespaceDecl; - FLMUINT uiSavedLineNum = 0; - FLMUINT uiSavedOffset = 0; - FLMUINT uiSavedFilePos = 0; - FLMUINT uiSavedLineBytes = 0; - eFlmDataType elmDataType; - FLMUINT uiElmNameId; - - if( RC_BAD( rc = processSTag( pNodeToLinkTo, eInsertLoc, - &bHasContent, &pElement))) - { - goto Exit; - } - - if (ppNewNode) - { - *ppNewNode = pElement; - (*ppNewNode)->AddRef(); - } - - if( !bHasContent) - { - goto Exit; - } - - if( RC_BAD( rc = pElement->getNameId( &uiElmNameId))) - { - goto Exit; - } - - if( RC_BAD( rc = pElement->getDataType( &elmDataType))) - { - goto Exit; - } - - for( ;;) - { - if ((uChar = getChar()) == 0) - { - uChar = ASCII_NEWLINE; - if (RC_BAD( rc = getLine())) - { - goto Exit; - } - } - - if( uChar == FLM_UNICODE_LT) - { - if( uiWhitespaceStartOffset) - { - // Set the offset to where the whitespace would - // have started. - - flmAssert( uiWhitespaceStartOffset <= uiOffset); - uiOffset = uiWhitespaceStartOffset; - uiWhitespaceStartOffset = 0; - } - - if( uiOffset) - { - // Flush the value - - if( pElement) - { - if( elmDataType == FLM_TEXT_TYPE || - elmDataType == FLM_NUMBER_TYPE) - { - if( uiOffset + 1 >= m_uiValBufSize) - { - if( RC_BAD( rc = resizeValBuffer( uiOffset + 2))) - { - goto Exit; - } - } - - m_pucValBuf[ uiOffset] = 0; - m_pucValBuf[ uiOffset + 1] = 0; - } - - if( RC_BAD( rc = flushElementValue( - pElement, m_pucValBuf, uiOffset))) - { - goto Exit; - } - } - - bFlushedValue = TRUE; - uiOffset = 0; - } - - // Preserve start location for error handling if necessary - - uiSavedLineNum = m_uiCurrLineNum; - uiSavedOffset = m_uiCurrLineOffset; - uiSavedFilePos = m_uiCurrLineFilePos; - uiSavedLineBytes = m_uiCurrLineBytes; - - if (lineHasToken( "?")) - { - if( RC_BAD( rc = processPI( pElement, - uiSavedLineNum, - uiSavedOffset, - uiSavedFilePos, - uiSavedLineBytes))) - { - goto Exit; - } - } - else if (lineHasToken( "!--")) - { - if( RC_BAD( rc = processComment( pElement, - uiSavedLineNum, - uiSavedOffset, - uiSavedFilePos, - uiSavedLineBytes))) - { - goto Exit; - } - } - else if (lineHasToken( "![CDATA[")) - { - if( RC_BAD( rc = processCDATA( pElement, - uiSavedLineNum, - uiSavedOffset, - uiSavedFilePos, - uiSavedLineBytes))) - { - goto Exit; - } - } - else if (lineHasToken( "/")) - { - break; - } - else if( isNameChar( peekChar())) - { - - // Unget the "<" - because processElement expect to see - // "= m_uiValBufSize) - { - if( RC_BAD( rc = resizeValBuffer( ~((FLMUINT)0)))) - { - goto Exit; - } - } - } - } - else - { - if( elmDataType != FLM_NODATA_TYPE) - { - if( m_uiFlags & FLM_XML_COMPRESS_WHITESPACE_FLAG) - { - if( isWhitespace( uChar)) - { - // If uiOffset is zero, this is still leading - // white space, and we should ignore it. - // Otherwise, we need to keep track of where - // whitespace began. - - if( !uiOffset) - { - uChar = 0; - } - else - { - uiWhitespaceStartOffset = uiOffset; - } - } - else - { - - // Last character is not whitespace. - - uiWhitespaceStartOffset = 0; - } - } - - if( uChar) - { - *((FLMUNICODE *)(&m_pucValBuf[ uiOffset])) = uChar; - uiOffset += sizeof( FLMUNICODE); - if( uiOffset >= m_uiValBufSize) - { - if( RC_BAD( rc = resizeValBuffer( ~((FLMUINT)0)))) - { - goto Exit; - } - } - } - } - } - } - - flmAssert( !uiOffset); - - - uiSavedOffset = m_uiCurrLineOffset; - if( RC_BAD( rc = getQualifiedName( &uiChars, - &puzPrefix, &puzLocal, &bNamespaceDecl, NULL))) - { - goto Exit; - } - - // Validate that the end tag matches the start tag - - if( pElement) - { - - // Element names cannot be "xmlns" or begin with "xmlns:" - - if (bNamespaceDecl) - { - setErrInfo( m_uiCurrLineNum, - uiSavedOffset, - XML_ERR_XMLNS_IN_ELEMENT_NAME, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - if( puzPrefix) - { - FLMUINT uiPrefixId1 = 0; - FLMUINT uiPrefixId2 = 0; - -// if( RC_BAD( rc = m_pDb->m_pDict->getPrefixId( -// m_pDb, puzPrefix, &uiPrefixId1))) -// { -// goto Exit; -// } - -// if( RC_BAD( rc = pElement->getPrefixId( m_pDb, &uiPrefixId2))) -// { -// goto Exit; -// } - - if( uiPrefixId1 != uiPrefixId2) - { - setErrInfo( m_uiCurrLineNum, - uiSavedOffset, - XML_ERR_ELEMENT_NAME_MISMATCH, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - } - else - { - if( RC_BAD( rc = pElement->getPrefixId( &uiTmp))) - { - goto Exit; - } - - if( uiTmp) - { - setErrInfo( m_uiCurrLineNum, - uiSavedOffset, - XML_ERR_ELEMENT_NAME_MISMATCH, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - } - - if( RC_BAD( rc = findNamespace( puzPrefix, &pNamespace))) - { - if( rc == NE_FLM_NOT_FOUND) - { - setErrInfo( m_uiCurrLineNum, - uiSavedOffset, - XML_ERR_PREFIX_NOT_DEFINED, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - } - goto Exit; - } - -// if( RC_BAD( rc = m_pDb->getElementNameId( -// pNamespace->getURIPtr(), puzLocal, &uiTmp))) -// { -// if( rc == NE_FLM_NOT_FOUND) -// { -// setErrInfo( m_uiCurrLineNum, -// uiSavedOffset, -// XML_ERR_ELEMENT_NAME_MISMATCH, -// m_uiCurrLineFilePos, -// m_uiCurrLineBytes); -// rc = RC_SET( NE_FLM_INVALID_XML); -// } -// goto Exit; -// } - - if( uiElmNameId != uiTmp) - { - setErrInfo( m_uiCurrLineNum, - uiSavedOffset, - XML_ERR_ELEMENT_NAME_MISMATCH, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - } - - // Skip any whitespace after the name - - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - // Get the ending ">" - - if( getChar() != FLM_UNICODE_GT) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_GT, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - -Exit: - - if( pNamespace) - { - pNamespace->Release(); - } - - popNamespaces( getNamespaceCount() - uiStartNSCount); - - if( pElement) - { - pElement->Release(); - } - - return( rc); -} - -/**************************************************************************** -Desc: Processes an XML STag -****************************************************************************/ -RCODE F_XMLParser::processSTag( - IF_DOMNode * pNodeToLinkTo, - eNodeInsertLoc eInsertLoc, - FLMBOOL * pbHasContent, - IF_DOMNode ** ppElement) -{ - RCODE rc = NE_FLM_OK; - FLMUNICODE uChar; - FLMUINT uiChars; - IF_DOMNode * pElement = NULL; - F_XMLNamespace * pNamespace = NULL; - FLMUNICODE * puzTmpPrefix; - FLMUNICODE * puzPrefix = NULL; - FLMUNICODE * puzTmpLocal; - FLMUNICODE * puzLocal = NULL; - FLMUINT uiNameId = 0; - FLMUINT uiAllocSize; - void * pvMark = m_pTmpPool->poolMark(); - FLMBOOL bNamespaceDecl; - FLMUINT uiSavedLineNum; - FLMUINT uiSavedOffset; - FLMUINT uiSavedFilePos; - FLMUINT uiSavedLineBytes; - - *pbHasContent = FALSE; - - if( getChar() != FLM_UNICODE_LT) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_ELEMENT_LT, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - uiSavedLineNum = m_uiCurrLineNum; - uiSavedOffset = m_uiCurrLineOffset; - uiSavedFilePos = m_uiCurrLineFilePos; - uiSavedLineBytes = m_uiCurrLineBytes; - if( RC_BAD( rc = getQualifiedName( &uiChars, &puzTmpPrefix, &puzTmpLocal, - &bNamespaceDecl, NULL))) - { - goto Exit; - } - - // Element names cannot be "xmlns" or begin with "xmlns:" - - if (bNamespaceDecl) - { - setErrInfo( uiSavedLineNum, - uiSavedOffset, - XML_ERR_XMLNS_IN_ELEMENT_NAME, - uiSavedFilePos, - uiSavedLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - uiAllocSize = (f_unilen( puzTmpLocal) + 1) * sizeof( FLMUNICODE); - if( RC_BAD( rc = m_pTmpPool->poolAlloc( uiAllocSize, (void **)&puzLocal))) - { - goto Exit; - } - f_unicpy( puzLocal, puzTmpLocal); - - if( puzTmpPrefix) - { - - // Need to save the prefix, because as parsing - // continues, the scratch buffer will be overwritten - - uiAllocSize = (f_unilen( puzTmpPrefix) + 1) * sizeof( FLMUNICODE); - if( RC_BAD( rc = m_pTmpPool->poolAlloc( uiAllocSize, (void **)&puzPrefix))) - { - goto Exit; - } - f_unicpy( puzPrefix, puzTmpPrefix); - } - - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - // Read the attributes - - resetAttrList(); - - uChar = peekChar(); - if( uChar != FLM_UNICODE_GT && uChar != FLM_UNICODE_FSLASH) - { - if( RC_BAD( rc = processAttributeList())) - { - goto Exit; - } - } - - // Find or create the element's name ID - - if( RC_BAD( rc = findNamespace( puzPrefix, &pNamespace))) - { - if( rc == NE_FLM_NOT_FOUND) - { - setErrInfo( uiSavedLineNum, - uiSavedOffset, - XML_ERR_PREFIX_NOT_DEFINED, - uiSavedFilePos, - uiSavedLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - } - goto Exit; - } - -// if( RC_BAD( rc = m_pDb->getElementNameId( -// pNamespace->getURIPtr(), puzLocal, &uiNameId))) -// { -// if( rc != NE_FLM_NOT_FOUND) -// { -// goto Exit; -// } -// -// if( !(m_uiFlags & FLM_XML_EXTEND_DICT_FLAG) || -// (pNamespace->getURIPtr() && -// f_unicmp( pNamespace->getURIPtr(), gv_uzXFLAIMNamespace) == 0)) -// { -// rc = RC_SET( NE_FLM_UNDEFINED_ELEMENT_NAME); -// goto Exit; -// } -// -// // Automatically extend the schema -// -// uiNameId = 0; -// if( RC_BAD( rc = m_pDb->createElementDef( -// pNamespace->getURIPtr(), -// puzLocal, FLM_TEXT_TYPE, &uiNameId))) -// { -// goto Exit; -// } -// } - - // Create the element node - - if( pNodeToLinkTo) - { - if( RC_BAD( rc = pNodeToLinkTo->createNode( ELEMENT_NODE, - uiNameId, eInsertLoc, &pElement))) - { - setErrInfo( uiSavedLineNum, - uiSavedOffset, - XML_ERR_CREATING_ELEMENT_NODE, - uiSavedFilePos, - uiSavedLineBytes); - goto Exit; - } - } - else - { -// if( RC_BAD( rc = m_pDb->createRootElement( uiNameId, &pElement))) -// { -// setErrInfo( uiSavedLineNum, -// uiSavedOffset, -// XML_ERR_CREATING_ROOT_ELEMENT, -// uiSavedFilePos, -// uiSavedLineBytes); -// goto Exit; -// } - } - - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - // Need to end with ">" or "/>" - - uChar = getChar(); - if( uChar == FLM_UNICODE_GT) - { - *pbHasContent = TRUE; - } - else if( uChar == FLM_UNICODE_FSLASH) - { - if( getChar() != FLM_UNICODE_GT) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_GT, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - } - else - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_GT, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - // Set the element's prefix - - if( RC_BAD( rc = addAttributesToElement( pElement))) - { - goto Exit; - } - - if( puzPrefix) - { - if( RC_BAD( rc = pElement->setPrefix( puzPrefix))) - { - goto Exit; - } - } - - if( ppElement) - { - *ppElement = pElement; - pElement = NULL; - } - - m_importStats.uiElements++; - if( m_fnStatus && (m_importStats.uiElements % 50) == 0) - { - m_fnStatus( XML_STATS, - (void *)&m_importStats, NULL, NULL, m_pvCallbackData); - } - -Exit: - - if( pElement) - { - pElement->Release(); - } - - if( pNamespace) - { - pNamespace->Release(); - } - - m_pTmpPool->poolReset( pvMark); - return( rc); -} - -/**************************************************************************** -Desc: Processes an element's attributes -****************************************************************************/ -RCODE F_XMLParser::processAttributeList( void) -{ - RCODE rc = NE_FLM_OK; - FLMUINT uiChars; - FLMUNICODE * puzLocal; - FLMUNICODE * puzPrefix; - XML_ATTR * pAttr = NULL; - FLMBOOL bFoundDefaultNamespace = FALSE; - FLMUINT uiNamespaceCount = 0; - FLMBOOL bNamespaceDecl; - FLMBOOL bDefaultNamespaceDecl; - FLMUINT uiSavedLineNum; - FLMUINT uiSavedOffset; - FLMUINT uiSavedFilePos; - FLMUINT uiSavedLineBytes; - - for( ;;) - { - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - if( !isNameChar( peekChar())) - { - break; - } - - uiSavedLineNum = m_uiCurrLineNum; - uiSavedOffset = m_uiCurrLineOffset; - uiSavedFilePos = m_uiCurrLineFilePos; - uiSavedLineBytes = m_uiCurrLineBytes; - if( RC_BAD( rc = getQualifiedName( &uiChars, - &puzPrefix, &puzLocal, &bNamespaceDecl, - &bDefaultNamespaceDecl))) - { - goto Exit; - } - - if( RC_BAD( rc = allocAttribute( &pAttr))) - { - goto Exit; - } - pAttr->uiLineNum = uiSavedLineNum; - pAttr->uiLineOffset = uiSavedOffset; - pAttr->uiLineFilePos = uiSavedFilePos; - pAttr->uiLineBytes = uiSavedLineBytes; - - if( RC_BAD( rc = setPrefix( pAttr, puzPrefix))) - { - goto Exit; - } - - if( RC_BAD( rc = setLocalName( pAttr, puzLocal))) - { - goto Exit; - } - if (bNamespaceDecl) - { - if (bDefaultNamespaceDecl) - { - pAttr->uiFlags |= F_DEFAULT_NS_DECL; - } - else - { - pAttr->uiFlags |= F_PREFIXED_NS_DECL; - } - } - - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - // Attribute name must be followed by an "=" - - if( getChar() != FLM_UNICODE_EQ) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_EQ, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - pAttr->uiValueLineNum = m_uiCurrLineNum; - pAttr->uiValueLineOffset = m_uiCurrLineOffset; - if( RC_BAD( rc = processAttValue( pAttr))) - { - goto Exit; - } - - m_importStats.uiAttributes++; - if( m_fnStatus && (m_importStats.uiAttributes % 50) == 0) - { - m_fnStatus( XML_STATS, - (void *)&m_importStats, NULL, NULL, m_pvCallbackData); - } - } - - // Push any namespace declarations onto the stack - - for( pAttr = m_pFirstAttr; pAttr; pAttr = pAttr->pNext) - { - // Duplicate namespace declarations are not allowed within a single element. - // So, multiple default namespace declarations or multiple uses of the same - // prefix in will result in a syntax error. - - if( pAttr->uiFlags & F_DEFAULT_NS_DECL) - { - // Default namespace declaration - - if( bFoundDefaultNamespace) - { - setErrInfo( pAttr->uiLineNum, - pAttr->uiLineOffset, - XML_ERR_MULTIPLE_XMLNS_DECLS, - pAttr->uiLineFilePos, - pAttr->uiLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - if( !pAttr->puzVal || *pAttr->puzVal == 0) - { - // No namespace - - if( RC_BAD( rc = pushNamespace( NULL, NULL))) - { - goto Exit; - } - } - else - { - if( RC_BAD( rc = pushNamespace( NULL, pAttr->puzVal))) - { - goto Exit; - } - } - - uiNamespaceCount++; - bFoundDefaultNamespace = TRUE; - } - else if( pAttr->uiFlags & F_PREFIXED_NS_DECL) - { - // Check for a unique prefix within current element - - if( RC_OK( rc = findNamespace( &pAttr->puzLocalName [6], - NULL, uiNamespaceCount))) - { - setErrInfo( pAttr->uiLineNum, - pAttr->uiLineOffset, - XML_ERR_MULTIPLE_PREFIX_DECLS, - pAttr->uiLineFilePos, - pAttr->uiLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - else if( rc != NE_FLM_NOT_FOUND) - { - goto Exit; - } - else - { - rc = NE_FLM_OK; - } - - if( RC_BAD( rc = pushNamespace( - &pAttr->puzLocalName [6], pAttr->puzVal))) - { - goto Exit; - } - - uiNamespaceCount++; - } - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Processes an XML declaration -****************************************************************************/ -RCODE F_XMLParser::processXMLDecl( void) -{ - RCODE rc = NE_FLM_OK; - FLMUNICODE uChar; - - // Have already eaten the "")) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset, - XML_ERR_EXPECTING_QUEST_GT, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Processes an XML document type declaration -****************************************************************************/ -RCODE F_XMLParser::processDocTypeDecl( void) -{ - RCODE rc = NE_FLM_OK; - FLMUNICODE uChar; - - // Have already eaten the "' - - if( RC_BAD( rc = skipWhitespace( TRUE))) - { - goto Exit; - } - } - - // Get the system ID - - if (RC_BAD( rc = getSystemLiteral())) - { - goto Exit; - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Processes a notation declaration -****************************************************************************/ -RCODE F_XMLParser::processNotationDecl( void) -{ - RCODE rc = NE_FLM_OK; - - // Have already eaten up the "#PCDATA" - - for( ;;) - { - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - uChar = getChar(); - if( uChar == FLM_UNICODE_RPAREN) - { - break; - } - else if( uChar == FLM_UNICODE_PIPE) - { - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - if( RC_BAD( rc = getName( NULL))) - { - goto Exit; - } - - bExpectingAsterisk = TRUE; - } - else - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_RPAREN_OR_PIPE, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - } - - if( bExpectingAsterisk) - { - if( getChar() != FLM_UNICODE_ASTERISK) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_ASTERISK, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Processes child content -****************************************************************************/ -RCODE F_XMLParser::processChildContent( void) -{ - RCODE rc = NE_FLM_OK; - FLMUNICODE uChar; - FLMUINT uiItemCount = 0; - FLMUINT uiDelimCount = 0; - FLMBOOL bChoice = FALSE; - FLMBOOL bSeq = FALSE; - - // Have eaten up the "(" - - for( ;;) - { - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - uChar = getChar(); - if( uChar == FLM_UNICODE_LPAREN) - { - if( RC_BAD( rc = processChildContent())) - { - goto Exit; - } - - uiItemCount++; - } - else if (uChar == FLM_UNICODE_RPAREN) - { - if( !uiItemCount || (uiItemCount - 1) != uiDelimCount) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EMPTY_CONTENT_INVALID, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - break; - } - else if (uChar == FLM_UNICODE_PIPE) - { - if( bSeq) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_CANNOT_MIX_CHOICE_AND_SEQ, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - bChoice = TRUE; - uiDelimCount++; - } - else if (uChar == FLM_UNICODE_COMMA) - { - if (bChoice) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_CANNOT_MIX_CHOICE_AND_SEQ, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - bSeq = TRUE; - uiDelimCount++; - } - else - { - ungetChar(); - if( RC_BAD( rc = getName( NULL))) - { - goto Exit; - } - uiItemCount++; - - uChar = peekChar(); - if (uChar == FLM_UNICODE_QUEST || - uChar == FLM_UNICODE_ASTERISK || - uChar == FLM_UNICODE_PLUS) - { - - // Eat up a "?", "*", or "+" - - (void)getChar(); - } - } - } - - uChar = peekChar(); - if( uChar == FLM_UNICODE_QUEST || - uChar == FLM_UNICODE_ASTERISK || - uChar == FLM_UNICODE_PLUS) - { - // Eat up a "?", "*", or "+" - - (void)getChar(); - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Processes a misc. declaration -****************************************************************************/ -RCODE F_XMLParser::processMisc( void) -{ - RCODE rc = NE_FLM_OK; - - for( ;;) - { - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - if( rc == NE_FLM_IO_END_OF_FILE || rc == NE_FLM_EOF_HIT) - { - rc = NE_FLM_OK; - } - - goto Exit; - } - - if (lineHasToken( "")) - { - break; - } - - if ((uChar = getChar()) == 0) - { - if (RC_BAD( rc = getLine())) - { - goto Exit; - } - uChar = ASCII_NEWLINE; - } - - *((FLMUNICODE *)(&m_pucValBuf[ uiOffset])) = uChar; - uiOffset += sizeof( FLMUNICODE); - - if( uiOffset >= uiMaxOffset) - { - if (RC_BAD( rc = resizeValBuffer( ~((FLMUINT)0)))) - { - goto Exit; - } - uiMaxOffset = m_uiValBufSize; - } - } - - if( pParent) - { - if( RC_BAD( rc = pParent->createNode( COMMENT_NODE, 0, - FLM_LAST_CHILD, &pComment))) - { - setErrInfo( uiSavedLineNum, - uiSavedOffset, - XML_ERR_CREATING_COMMENT_NODE, - uiSavedFilePos, - uiSavedLineBytes); - goto Exit; - } - - *((FLMUNICODE *)(&m_pucValBuf[ uiOffset])) = 0; - - if( RC_BAD( rc = pComment->setUnicode( (FLMUNICODE *)m_pucValBuf))) - { - goto Exit; - } - - pComment->Release(); - pComment = NULL; - } - -Exit: - - if( pComment) - { - pComment->Release(); - } - - return( rc); -} - -/**************************************************************************** -Desc: Processes a CDATA tag -****************************************************************************/ -RCODE F_XMLParser::processCDATA( - IF_DOMNode * pParent, - FLMUINT uiSavedLineNum, - FLMUINT uiSavedOffset, - FLMUINT uiSavedFilePos, - FLMUINT uiSavedLineBytes) -{ - RCODE rc = NE_FLM_OK; - FLMUNICODE uChar; - FLMUINT uiOffset = 0; - IF_DOMNode * pCData = NULL; - - // Have already eaten up the "")) - { - break; - } - if ((uChar = getChar()) == 0) - { - if (RC_BAD( rc = getLine())) - { - goto Exit; - } - uChar = ASCII_NEWLINE; - } - - *((FLMUNICODE *)(&m_pucValBuf[ uiOffset])) = uChar; - uiOffset += sizeof( FLMUNICODE); - - if( uiOffset >= m_uiValBufSize) - { - if( RC_BAD( rc = resizeValBuffer( ~((FLMUINT)0)))) - { - goto Exit; - } - } - } - - if( pParent) - { - if( RC_BAD( rc = pParent->createNode( CDATA_SECTION_NODE, 0, - FLM_LAST_CHILD, &pCData))) - { - setErrInfo( uiSavedLineNum, - uiSavedOffset, - XML_ERR_CREATING_CDATA_NODE, - uiSavedFilePos, - uiSavedLineBytes); - goto Exit; - } - - *((FLMUNICODE *)(&m_pucValBuf[ uiOffset])) = 0; - if( RC_BAD( rc = pCData->setUnicode( (FLMUNICODE *)m_pucValBuf))) - { - goto Exit; - } - - pCData->Release(); - pCData = NULL; - } - -Exit: - - if( pCData) - { - pCData->Release(); - } - - return( rc); -} - -/**************************************************************************** -Desc: Skips any whitespace characters in the input stream -****************************************************************************/ -RCODE F_XMLParser::skipWhitespace( - FLMBOOL bRequired) -{ - RCODE rc = NE_FLM_OK; - FLMUNICODE uChar; - FLMUINT uiCount = 0; - - for( ;;) - { - if ((uChar = getChar()) == 0) - { - uiCount++; - if (RC_BAD( rc = getLine())) - { - goto Exit; - } - continue; - } - - if( !isWhitespace( uChar)) - { - ungetChar(); - break; - } - uiCount++; - } - - if( !uiCount && bRequired) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset, - XML_ERR_EXPECTING_WHITESPACE, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - -Exit: - - return( rc); -} - -/***************************************************************************** -Desc: -******************************************************************************/ -RCODE F_XMLParser::resizeValBuffer( - FLMUINT uiSize) -{ - RCODE rc = NE_FLM_OK; - - if( uiSize == m_uiValBufSize) - { - goto Exit; - } - - if( uiSize == ~((FLMUINT)0)) - { - uiSize = m_uiValBufSize + 2048; - } - - if( m_pucValBuf) - { - if( uiSize) - { - if( RC_BAD( rc = f_realloc( uiSize, &m_pucValBuf))) - { - goto Exit; - } - } - else - { - f_free( &m_pucValBuf); - m_pucValBuf = NULL; - } - } - else - { - flmAssert( !m_pucValBuf); - - if( RC_BAD( rc = f_alloc( uiSize, &m_pucValBuf))) - { - goto Exit; - } - } - - m_uiValBufSize = uiSize; - -Exit: - - return( rc); -} - -/***************************************************************************** -Desc: -******************************************************************************/ -RCODE F_XMLParser::getBinaryVal( - FLMUINT * puiLength) -{ - RCODE rc = NE_FLM_OK; - FLMUNICODE uChar; - FLMUNICODE uChar2; - FLMUINT uiOffset = 0; - FLMBOOL bHavePreamble; - - flmAssert( *puiLength == 0); - - for( ;;) - { - bHavePreamble = FALSE; - - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - -Retry: - - uChar = getChar(); - if( !f_isHexChar( uChar)) - { - if( uChar != FLM_UNICODE_LT) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_HEX_DIGIT, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - ungetChar(); - break; - } - - uChar2 = getChar(); - if( uChar == FLM_UNICODE_0 && - (uChar2 == FLM_UNICODE_X || uChar2 == FLM_UNICODE_x)) - { - if( bHavePreamble) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_HEX_DIGIT, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - bHavePreamble = TRUE; - goto Retry; - } - - if( !f_isHexChar( uChar2)) - { - setErrInfo( m_uiCurrLineNum, - m_uiCurrLineOffset - 1, - XML_ERR_EXPECTING_HEX_DIGIT, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - if( uiOffset >= m_uiValBufSize) - { - if( RC_BAD( rc = resizeValBuffer( ~((FLMUINT)0)))) - { - goto Exit; - } - } - - m_pucValBuf[ uiOffset++] = - (f_getHexVal( uChar) << 4) | f_getHexVal( uChar2); - - if( RC_BAD( rc = skipWhitespace( FALSE))) - { - goto Exit; - } - - uChar = getChar(); - if( uChar != FLM_UNICODE_COMMA) - { - ungetChar(); - } - } - - *puiLength = uiOffset; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: Constructor -****************************************************************************/ -F_XMLNamespaceMgr::F_XMLNamespaceMgr() -{ - m_pFirstNamespace = NULL; - m_uiNamespaceCount = 0; -} - -/**************************************************************************** -Desc: Destructor -****************************************************************************/ -F_XMLNamespaceMgr::~F_XMLNamespaceMgr() -{ - popNamespaces( m_uiNamespaceCount); -} - -/**************************************************************************** -Desc: -****************************************************************************/ -void F_XMLNamespaceMgr::popNamespaces( - FLMUINT uiCount) -{ - F_XMLNamespace * pTmpNamespace; - - flmAssert( uiCount <= m_uiNamespaceCount); - - while( uiCount && m_pFirstNamespace) - { - pTmpNamespace = m_pFirstNamespace; - m_pFirstNamespace = m_pFirstNamespace->m_pNext; - pTmpNamespace->m_pNext = NULL; - pTmpNamespace->Release(); - m_uiNamespaceCount--; - uiCount--; - } -} - -/**************************************************************************** -Desc: -****************************************************************************/ -RCODE F_XMLNamespaceMgr::findNamespace( - FLMUNICODE * puzPrefix, - F_XMLNamespace ** ppNamespace, - FLMUINT uiMaxSearchSize) -{ - RCODE rc = NE_FLM_OK; - F_XMLNamespace * pTmpNamespace = m_pFirstNamespace; - - while( pTmpNamespace) - { - if( !uiMaxSearchSize) - { - pTmpNamespace = NULL; - break; - } - - if( !puzPrefix && !pTmpNamespace->m_puzPrefix) - { - break; - } - else if( puzPrefix && pTmpNamespace->m_puzPrefix) - { - if( f_unicmp( puzPrefix, pTmpNamespace->m_puzPrefix) == 0) - { - break; - } - } - - pTmpNamespace = pTmpNamespace->m_pNext; - uiMaxSearchSize--; - } - - if( !pTmpNamespace) - { - rc = RC_SET( NE_FLM_NOT_FOUND); - goto Exit; - } - - if( ppNamespace) - { - if( *ppNamespace) - { - (*ppNamespace)->Release(); - } - - pTmpNamespace->AddRef(); - *ppNamespace = pTmpNamespace; - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: -****************************************************************************/ -RCODE F_XMLNamespaceMgr::pushNamespace( - FLMUNICODE * puzPrefix, - FLMUNICODE * puzNamespaceURI) -{ - RCODE rc = NE_FLM_OK; - F_XMLNamespace * pNewNamespace = NULL; - - if( (pNewNamespace = f_new F_XMLNamespace) == NULL) - { - rc = RC_SET( NE_FLM_MEM); - goto Exit; - } - - if( RC_BAD( rc = pNewNamespace->setPrefix( puzPrefix))) - { - goto Exit; - } - - if( RC_BAD( rc = pNewNamespace->setURI( puzNamespaceURI))) - { - goto Exit; - } - - pNewNamespace->m_pNext = m_pFirstNamespace; - m_pFirstNamespace = pNewNamespace; - pNewNamespace = NULL; - m_uiNamespaceCount++; - -Exit: - - if( pNewNamespace) - { - pNewNamespace->Release(); - } - - return( rc); -} - -/**************************************************************************** -Desc: -****************************************************************************/ -RCODE F_XMLNamespaceMgr::pushNamespace( - F_XMLNamespace * pNamespace) -{ - flmAssert( m_pFirstNamespace != pNamespace && - !pNamespace->m_pNext); - - pNamespace->AddRef(); - pNamespace->m_pNext = m_pFirstNamespace; - m_pFirstNamespace = pNamespace; - m_uiNamespaceCount++; - - return( NE_FLM_OK); -} - -/**************************************************************************** -Desc: -****************************************************************************/ -RCODE F_XMLNamespace::setPrefix( - FLMUNICODE * puzPrefix) -{ - RCODE rc = NE_FLM_OK; - FLMUINT uiLen; - - if( m_puzPrefix) - { - f_free( &m_puzPrefix); - } - - if( puzPrefix) - { - uiLen = f_unilen( puzPrefix); - if( RC_BAD( rc = f_alloc( sizeof( FLMUNICODE) * (uiLen + 1), - &m_puzPrefix))) - { - goto Exit; - } - - f_unicpy( m_puzPrefix, puzPrefix); - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: -****************************************************************************/ -RCODE F_XMLNamespace::setURI( - FLMUNICODE * puzURI) -{ - RCODE rc = NE_FLM_OK; - FLMUINT uiLen; - - if( m_puzURI) - { - f_free( &m_puzURI); - } - - if( puzURI) - { - uiLen = f_unilen( puzURI); - if( RC_BAD( rc = f_alloc( - sizeof( FLMUNICODE) * (uiLen + 1), &m_puzURI))) - { - goto Exit; - } - - f_unicpy( m_puzURI, puzURI); - } - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: -****************************************************************************/ -RCODE F_XMLNamespace::setup( - FLMUNICODE * puzPrefix, - FLMUNICODE * puzURI, - F_XMLNamespace * pNext) -{ - RCODE rc = NE_FLM_OK; - FLMUINT uiLen; - - flmAssert( !m_puzPrefix); - flmAssert( !m_puzURI); - flmAssert( !m_pNext); - - if( puzPrefix) - { - uiLen = f_unilen( puzPrefix); - if( RC_BAD( rc = f_alloc( sizeof( FLMUNICODE) * (uiLen + 1), - &m_puzPrefix))) - { - goto Exit; - } - - f_unicpy( m_puzPrefix, puzPrefix); - } - - if( puzURI) - { - uiLen = f_unilen( puzURI); - if( RC_BAD( rc = f_alloc( sizeof( FLMUNICODE) * (uiLen + 1), - &m_puzURI))) - { - goto Exit; - } - - f_unicpy( m_puzURI, puzURI); - } - - m_pNext = pNext; - -Exit: - - return( rc); -} - -/**************************************************************************** -Desc: -****************************************************************************/ -#if 0 -RCODE F_XMLParser::addAttributesToElement( - IF_DOMNode * pElement) -{ - RCODE rc = NE_FLM_OK; - XML_ATTR * pAttr; - F_XMLNamespace * pNamespace = NULL; - IF_DOMNode * pTmpNode = NULL; - FLMUINT uiNameId; - eFlmDataType attrDataType; - - // Make sure any prefixes (e.g., xmlns:xxxx) are added to the database - // before they are used - in case they are used by the attributes - // themselves. - - for( pAttr = m_pFirstAttr; pAttr; pAttr = pAttr->pNext) - { - if( pAttr->uiFlags & F_PREFIXED_NS_DECL) - { - FLMUINT uiPrefixId; - - // Create the prefix (stored in &puzLocalName [6]) if it doesn't - // already exist - -// if( RC_BAD( rc = m_pDb->m_pDict->getPrefixId( m_pDb, -// &pAttr->puzLocalName [6], &uiPrefixId))) -// { -// if( rc != NE_FLM_NOT_FOUND) -// { -// goto Exit; -// } -// -// uiPrefixId = 0; -// if( RC_BAD( rc = m_pDb->createPrefixDef( TRUE, -// &pAttr->puzLocalName [6], &uiPrefixId))) -// { -// goto Exit; -// } -// } - } - } - - // Add the attributes to the element - // - // NOTE: The XML namespace specification states that the names - // of all unqualified attributes are assigned to the - // appropriate per-element-type partition. This means that - // the combination of the attribute name with the parent - // element's type and namespace name is used to uniquely - // identify each unqualified attribute. - // - // For sake of clarity and useability, however, the parser - // deviates from the namespace specification. Each unprefixed - // attribute encountered by the parser will inherit the - // namespace of the parent element, even if the namespace - // is a default namespace. - - for( pAttr = m_pFirstAttr; pAttr; pAttr = pAttr->pNext) - { - if( pAttr->uiFlags & F_DEFAULT_NS_DECL) - { - // Add the namespace declaration to the element - -// if( RC_BAD( rc = pElement->createAttribute( ATTR_XMLNS_TAG, -// &pTmpNode))) -// { -// goto Exit; -// } -// -// if( RC_BAD( rc = pTmpNode->setUnicode( pAttr->puzVal))) -// { -// goto Exit; -// } - -// if( RC_BAD( rc = pTmpNode->addModeFlags( m_pDb, FDOM_READ_ONLY))) -// { -// goto Exit; -// } - } - else if( pAttr->uiFlags & F_PREFIXED_NS_DECL) - { - // Find the attribute definition - -// if( RC_BAD( rc = m_pDb->getAttributeNameId( -// NULL, pAttr->puzLocalName, &uiNameId))) -// { -// if( rc != NE_FLM_NOT_FOUND) -// { -// goto Exit; -// } -// -// if( !(m_uiFlags & FLM_XML_EXTEND_DICT_FLAG)) -// { -// rc = RC_SET( NE_FLM_UNDEFINED_ATTRIBUTE_NAME); -// goto Exit; -// } -// -// uiNameId = 0; -// if( RC_BAD( rc = m_pDb->createAttributeDef( -// NULL, pAttr->puzLocalName, FLM_TEXT_TYPE, &uiNameId, -// &pTmpNode))) -// { -// goto Exit; -// } -// } - - // Add the namespace declaration to the element - -// if( RC_BAD( rc = pElement->createAttribute( m_pDb, uiNameId, -// &pTmpNode))) -// { -// goto Exit; -// } -// -// if( RC_BAD( rc = pTmpNode->setUnicode( m_pDb, pAttr->puzVal))) -// { -// goto Exit; -// } -// -// if( RC_BAD( rc = pTmpNode->addModeFlags( m_pDb, FDOM_READ_ONLY))) -// { -// goto Exit; -// } - } - else - { - if( pAttr->puzPrefix) - { - if( RC_BAD( rc = findNamespace( pAttr->puzPrefix, &pNamespace))) - { - if( rc == NE_FLM_NOT_FOUND) - { - setErrInfo( pAttr->uiLineNum, pAttr->uiLineOffset, - XML_ERR_PREFIX_NOT_DEFINED, pAttr->uiLineFilePos, - pAttr->uiLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - } - - goto Exit; - } - } - else - { - if( pNamespace) - { - pNamespace->Release(); - } - pNamespace = NULL; - } - -// if( RC_BAD( rc = m_pDb->getAttributeNameId( -// pNamespace ? pNamespace->getURIPtr() : NULL, -// pAttr->puzLocalName, &uiNameId))) -// { -// if( rc != NE_FLM_NOT_FOUND) -// { -// goto Exit; -// } -// -// if( !(m_uiFlags & FLM_XML_EXTEND_DICT_FLAG) || -// (pNamespace && -// f_unicmp( pNamespace->getURIPtr(), gv_uzXFLAIMNamespace) == 0)) -// { -// rc = RC_SET( NE_FLM_UNDEFINED_ATTRIBUTE_NAME); -// goto Exit; -// } -// -// uiNameId = 0; -// if( RC_BAD( rc = m_pDb->createAttributeDef( -// pNamespace ? pNamespace->getURIPtr() : NULL, -// pAttr->puzLocalName, FLM_TEXT_TYPE, &uiNameId))) -// { -// goto Exit; -// } -// } - -// if( RC_BAD( rc = pElement->createAttribute( m_pDb, uiNameId, -// &pTmpNode))) -// { -// goto Exit; -// } -// -// if (pAttr->puzPrefix) -// { -// if( RC_BAD( rc = pTmpNode->setPrefix( m_pDb, pAttr->puzPrefix))) -// { -// if( rc == NE_FLM_NOT_FOUND) -// { -// setErrInfo( pAttr->uiLineNum, -// pAttr->uiLineOffset, -// XML_ERR_PREFIX_NOT_DEFINED, -// pAttr->uiLineFilePos, -// pAttr->uiLineBytes); -// rc = RC_SET( NE_FLM_INVALID_XML); -// } -// goto Exit; -// } -// } -// - if( RC_BAD( rc = pTmpNode->getDataType( &attrDataType))) - { - goto Exit; - } - - switch( attrDataType) - { - case FLM_TEXT_TYPE: - { - if( RC_BAD( rc = pTmpNode->setUnicode( pAttr->puzVal))) - { - goto Exit; - } - break; - } - - case FLM_NUMBER_TYPE: - { - FLMUINT64 ui64Val; - FLMBOOL bNeg; - - if( RC_BAD( rc = unicodeToNumber64( - pAttr->puzVal, &ui64Val, &bNeg))) - { - goto Exit; - } - - if( !bNeg) - { - if( RC_BAD( rc = pTmpNode->setUINT64( ui64Val))) - { - goto Exit; - } - } - else - { - if( RC_BAD( rc = pTmpNode->setINT64( -((FLMINT64)ui64Val)))) - { - goto Exit; - } - } - - break; - } - - case FLM_BINARY_TYPE: - { - FLMBOOL bHavePreamble; - FLMUNICODE * puzStr = pAttr->puzVal; - FLMUINT uiOffset = 0; - - // Convert the Unicode value to binary - - while( puzStr && *puzStr) - { - bHavePreamble = FALSE; - - while( isWhitespace( *puzStr)) - { - puzStr++; - } - - Retry: - - if( !f_isHexChar( *puzStr)) - { - break; - } - - if( *puzStr == FLM_UNICODE_0 && - (puzStr[ 1] == FLM_UNICODE_X || puzStr[ 1] == FLM_UNICODE_x)) - { - if( bHavePreamble) - { - setErrInfo( pAttr->uiValueLineNum, - pAttr->uiValueLineOffset, - XML_ERR_INVALID_BINARY_ATTR_VALUE, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - bHavePreamble = TRUE; - puzStr += 2; - goto Retry; - } - - if( !f_isHexChar( puzStr[ 1])) - { - setErrInfo( pAttr->uiValueLineNum, - pAttr->uiValueLineOffset, - XML_ERR_INVALID_BINARY_ATTR_VALUE, - m_uiCurrLineFilePos, - m_uiCurrLineBytes); - rc = RC_SET( NE_FLM_INVALID_XML); - goto Exit; - } - - if( uiOffset >= m_uiValBufSize) - { - if( RC_BAD( rc = resizeValBuffer( ~((FLMUINT)0)))) - { - goto Exit; - } - } - - m_pucValBuf[ uiOffset++] = - (f_getHexVal( *puzStr) << 4) | f_getHexVal( puzStr[ 1]); - - puzStr += 2; - - while( isWhitespace( *puzStr)) - { - puzStr++; - } - - if( *puzStr == FLM_UNICODE_COMMA) - { - puzStr++; - } - } - - if( RC_BAD( rc = pTmpNode->setBinary( m_pucValBuf, uiOffset))) - { - goto Exit; - } - break; - } - - default: - { - rc = RC_SET_AND_ASSERT( NE_FLM_NOT_IMPLEMENTED); - goto Exit; - } - } - } - } - -Exit: - - if( pTmpNode) - { - pTmpNode->Release(); - } - - if( pNamespace) - { - pNamespace->Release(); - } - - return( rc); -} -#endif - -// Some forward declarations - -class F_Element; -class F_Attribute; - -/***************************************************************************** -Desc: Keeps track of an attribute that we are going to output -*****************************************************************************/ -class F_Attribute : public F_Base -{ -public: - F_Attribute( - F_Element * pElement) - { - m_uiTmpSpaceSize = sizeof( m_uzTmpSpace); - m_puzName = &m_uzTmpSpace [0]; - reset( pElement); - } - - ~F_Attribute(); - - FINLINE void reset( - F_Element * pElement) - { - m_uiNameChars = 0; - m_bIsNamespaceDecl = FALSE; - m_bDefaultNamespaceDecl = FALSE; - m_uiNamespaceChars = 0; - m_uiValueChars = 0; - m_uiPrefixChars = 0; - m_pElement = pElement; - } - - RCODE allocNameSpace( void); - -// RCODE setupAttribute( -// IF_Db * pDb, -// IF_DOMNode * pNode); - - RCODE setPrefix( void); - - RCODE outputAttr( - IF_OStream * pOStream); - - FINLINE F_Attribute * getNext( void) - { - return( m_pNext); - } - -private: - FLMUNICODE m_uzTmpSpace [150]; - FLMUINT m_uiTmpSpaceSize; - FLMBOOL m_bIsNamespaceDecl; - FLMBOOL m_bDefaultNamespaceDecl; - FLMUNICODE * m_puzName; - FLMUINT m_uiNameChars; - FLMUNICODE * m_puzNamespace; - FLMUINT m_uiNamespaceChars; - FLMUNICODE * m_puzValue; - FLMUINT m_uiValueChars; - FLMUNICODE * m_puzPrefix; - FLMUINT m_uiPrefixChars; - F_Element * m_pElement; - F_Attribute * m_pNext; - -friend class F_Element; -}; - -/***************************************************************************** -Desc: Destructor for F_Attribute class. -*****************************************************************************/ -F_Attribute::~F_Attribute() -{ - if (m_puzName != &m_uzTmpSpace [0]) - { - f_free( &m_puzName); - } -} - -/***************************************************************************** -Desc: Keeps track of an element that we are going to output -*****************************************************************************/ -class F_Element : public F_Base -{ -public: - F_Element( - F_Element * pParentElement, - F_Attribute ** ppAvailAttrs, - FLMUINT * puiNextPrefixNum) - { - m_uiTmpSpaceSize = sizeof( m_uzTmpSpace); - m_puzName = &m_uzTmpSpace [0]; - m_pFirstAttr = NULL; - m_pLastAttr = NULL; - m_pNext = NULL; - m_uiIndentCount = 0; - m_bIsDocumentRoot = FALSE; - reset( pParentElement, ppAvailAttrs, puiNextPrefixNum); - } - - ~F_Element() - { - F_Attribute * pAttr; - F_Attribute * pTmpAttr; - - // Delete all of the attributes - - pAttr = m_pFirstAttr; - while (pAttr) - { - pTmpAttr = pAttr; - pAttr = pAttr->m_pNext; - delete pTmpAttr; - } - - if (m_puzName != &m_uzTmpSpace [0]) - { - f_free( &m_puzName); - } - } - - FINLINE void reset( - F_Element * pParentElement, - F_Attribute ** ppAvailAttrs, - FLMUINT * puiNextPrefixNum) - { - m_uiNameChars = 0; - m_uiNamespaceChars = 0; - m_uiPrefixChars = 0; - m_pParentElement = pParentElement; - m_puiNextPrefixNum = puiNextPrefixNum; - m_ppAvailAttrs = ppAvailAttrs; - m_pNext = NULL; - m_uiIndentCount = 0; - m_bIsDocumentRoot = FALSE; - } - - FINLINE void setIndentCount( - FLMUINT uiIndentCount) - { - m_uiIndentCount = uiIndentCount; - } - - FINLINE void setDocumentRoot( - FLMBOOL bIsDocumentRoot) - { - m_bIsDocumentRoot = bIsDocumentRoot; - } - - RCODE allocAttr( - F_Attribute ** ppAttr); - - FINLINE void makeAttrAvail( - F_Attribute * pAttr) - { - pAttr->m_pNext = *m_ppAvailAttrs; - *m_ppAvailAttrs = pAttr; - } - - FINLINE void makeAllAttrsAvail( void) - { - if (m_pFirstAttr) - { - m_pLastAttr->m_pNext = *m_ppAvailAttrs; - *m_ppAvailAttrs = m_pFirstAttr; - m_pFirstAttr = NULL; - m_pLastAttr = NULL; - } - } - -// RCODE saveAttribute( -// IF_Db * pDb, -// IF_DOMNode * pNode); - - RCODE allocNameSpace( void); - -// RCODE setupElement( -// IF_Db * pDb, -// IF_DOMNode * pNode); - - RCODE addNamespaceDecl( - FLMUNICODE * puzPrefix, - FLMUINT uiPrefixChars, - FLMUNICODE * puzNamespace, - FLMUINT uiNamespaceChars, - F_Attribute ** ppAttr); - - void genPrefix( - FLMUNICODE * puzPrefix, - FLMUINT * puiPrefixChars); - - RCODE findPrefix( - FLMUNICODE * puzNamespace, - FLMUINT uiNamespaceChars, - FLMBOOL bForElement, - FLMUNICODE ** ppuzPrefix, - FLMUINT * puiPrefixChars); - - FINLINE RCODE setPrefix( void) - { - return( findPrefix( m_puzNamespace, m_uiNamespaceChars, TRUE, - &m_puzPrefix, &m_uiPrefixChars)); - } - - FINLINE F_Element * getParentElement( void) - { - return( m_pParentElement); - } - - RCODE outputElem( - IF_OStream * pOStream, - FLMBOOL bStartOfElement, - FLMBOOL bEndOfElement, - FLMBOOL bAddNewLine); - -// RCODE outputLocalData( -// IF_OStream * pOStream, -// IF_DOMNode * pDbNode, -// IF_Db * ifpDb, -// eExportFormatType eFormatType, -// FLMUINT uiIndentCount); - - FINLINE F_Element * getNext( void) - { - return( m_pNext); - } - - FINLINE void makeAvail( - F_Element ** ppAvailElements) - { - m_pNext = *ppAvailElements; - *ppAvailElements = this; - } - -private: - FLMUNICODE m_uzTmpSpace [100]; - FLMUINT m_uiTmpSpaceSize; - FLMUNICODE * m_puzName; - FLMUINT m_uiNameChars; - FLMUNICODE * m_puzNamespace; - FLMUINT m_uiNamespaceChars; - FLMUNICODE * m_puzPrefix; - FLMUINT m_uiPrefixChars; - F_Attribute * m_pFirstAttr; - F_Attribute * m_pLastAttr; - F_Element * m_pParentElement; - F_Element * m_pNext; - FLMUINT * m_puiNextPrefixNum; - F_Attribute ** m_ppAvailAttrs; - FLMBOOL m_bIsDocumentRoot; - FLMUINT m_uiIndentCount; - -friend class F_Attribute; -}; - -/***************************************************************************** -Desc: Allocate space to hold the name, namespace, and value for an attribute. -*****************************************************************************/ -RCODE F_Attribute::allocNameSpace( void) -{ - RCODE rc = NE_FLM_OK; - FLMUINT uiSpaceNeeded; - FLMUNICODE * puzTmp; - - uiSpaceNeeded = (m_uiNameChars + - m_uiNamespaceChars + - m_uiValueChars + 3) * sizeof( FLMUNICODE); - if (uiSpaceNeeded > m_uiTmpSpaceSize) - { - if (RC_BAD( rc = f_alloc( uiSpaceNeeded, &puzTmp))) - { - goto Exit; - } - if (m_puzName != &m_uzTmpSpace [0]) - { - f_free( &m_puzName); - } - m_puzName = puzTmp; - m_uiTmpSpaceSize = uiSpaceNeeded; - } - m_puzNamespace = &m_puzName [m_uiNameChars + 1]; - m_puzValue = &m_puzNamespace [m_uiNamespaceChars + 1]; - -Exit: - - return( rc); -} - -/***************************************************************************** -Desc: Setup an attribute with its namespace, etc. -*****************************************************************************/ -#if 0 -RCODE F_Attribute::setupAttribute( - IF_Db * pDb, - IF_DOMNode * pNode - ) -{ - RCODE rc = NE_FLM_OK; - - // Determine if the attribute is a namespace declaration - - if (RC_BAD( rc = pNode->isNamespaceDecl( pDb, &m_bIsNamespaceDecl))) - { - goto Exit; - } - - // Get the length of the name of the attribute - - if (RC_BAD( rc = pNode->getLocalName( pDb, (FLMUNICODE *)NULL, - 0, &m_uiNameChars))) - { - goto Exit; - } - - // If it is a namespace declaration, no need to get the namespace URI, - // we already know what it is, and we will output it with an xmlns prefix - // Otherwise, we need to get the namespace so we can determine a prefix, - // if any. If the namespace is the same namespace as the enclosing - // element, we do not need to output a prefix. - - if (!m_bIsNamespaceDecl) - { - - // Get the number of characters in the namespace of the attribute - - if (RC_BAD( rc = pNode->getNamespaceURI( pDb, (FLMUNICODE *)NULL, - 0, &m_uiNamespaceChars))) - { - goto Exit; - } - } - - // Get the number of characters in the attribute's value. - - if (RC_BAD( rc = pNode->getUnicodeChars( pDb, &m_uiValueChars))) - { - goto Exit; - } - - // Allocate space for the name, namespace, and value - - if (RC_BAD( rc = allocNameSpace())) - { - goto Exit; - } - - // Get the attribute name. - - if (RC_BAD( rc = pNode->getLocalName( pDb, m_puzName, - (m_uiNameChars + 1) * sizeof( FLMUNICODE), - &m_uiNameChars))) - { - goto Exit; - } - - // Get the namespace, if necessary - - if (m_uiNamespaceChars) - { - if (RC_BAD( rc = pNode->getNamespaceURI( pDb, m_puzNamespace, - (m_uiNamespaceChars + 1) * sizeof( FLMUNICODE), - &m_uiNamespaceChars))) - { - goto Exit; - } - } - - // Get the value, if any - - if (m_uiValueChars) - { - if (RC_BAD( rc = pNode->getUnicode( pDb, m_puzValue, - (m_uiValueChars + 1) * sizeof( FLMUNICODE), - 0, m_uiValueChars, &m_uiValueChars))) - { - goto Exit; - } - } - - // If it is a namespace declaration, the local name must either be - // "xmlns" or begin with "xmlns:" - - if (m_bIsNamespaceDecl) - { - - // Make sure name is "xmlns" or begins with "xmlns:" - - if (m_uiNameChars != 5 && m_uiNameChars <= 6) - { - rc = RC_SET_AND_ASSERT( NE_FLM_INVALID_NAMESPACE_DECL); - goto Exit; - } - - if (!isXMLNS( m_puzName)) - { - rc = RC_SET_AND_ASSERT( NE_FLM_INVALID_NAMESPACE_DECL); - goto Exit; - } - else if (m_uiNameChars == 5) - { - m_bDefaultNamespaceDecl = TRUE; - } - else if (m_puzName [5] != ':') - { - rc = RC_SET_AND_ASSERT( NE_FLM_INVALID_NAMESPACE_DECL); - goto Exit; - } - } - -Exit: - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Set the prefix for an attribute. -*****************************************************************************/ -#if 0 -RCODE F_Attribute::setPrefix( void) -{ - RCODE rc = NE_FLM_OK; - - // If this is a namespace declaration, there should be no prefix in the name. - - if (m_bIsNamespaceDecl) - { - flmAssert( !m_uiPrefixChars); - } - - // Only need to set a prefix on an attribute if it has a namespace - // Otherwise, leave it alone - no prefix. - - else if (m_uiNamespaceChars) - { - - - // See if we can find a namespace declaration in either - // this element's attributes, or any of its parent element - // attributes. - - if (RC_BAD( rc = m_pElement->findPrefix( m_puzNamespace, - m_uiNamespaceChars, FALSE, - &m_puzPrefix, &m_uiPrefixChars))) - { - goto Exit; - } - } - -Exit: - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Export a unicode string to the string buffer - as UTF8. -*****************************************************************************/ -#if 0 -FSTATIC RCODE exportUniValue( - IF_OStream * pOStream, - FLMUNICODE * puzStr, - FLMUINT uiStrChars, - FLMBOOL bEncodeSpecialChars, - FLMUINT uiIndentCount - ) -{ - RCODE rc = NE_FLM_OK; - FLMBYTE ucTmp [4]; - FLMUINT uiLen; - FLMUINT uiCharOffset = 0; - FLMUNICODE uzChar; - FLMBOOL bIndent = FALSE; - FLMUINT uiICount = 0; - - while ( *puzStr && uiCharOffset < uiStrChars) - { - uzChar = *puzStr; - - // Handle encoding of special characters - - if (bEncodeSpecialChars) - { - if (uzChar == '<') - { - if (RC_BAD( rc = pOStream->write( (void *)"<", 4))) - { - goto Exit; - } - } - else if (uzChar == '>') - { - if (RC_BAD( rc = pOStream->write( (void *)">", 4))) - { - goto Exit; - } - } - else if (uzChar == '&') - { - if (RC_BAD( rc = pOStream->write( (void *)"&", 5))) - { - goto Exit; - } - } - else if (uzChar == '\'') - { - if (RC_BAD( rc = pOStream->write( (void *)"'", 6))) - { - goto Exit; - } - } - else if (uzChar == '"') - { - if (RC_BAD( rc = pOStream->write( (void *)""", 6))) - { - goto Exit; - } - } - else - { - goto Normal_Encoding; - } - } - else - { - -Normal_Encoding: - - // Output the character as UTF8. - - if (uzChar <= 0x007F) - { - // New Line char found. Need to indent. - if( uzChar == ASCII_NEWLINE) - { - bIndent = TRUE; - } - ucTmp [0] = (FLMBYTE)uzChar; - uiLen = 1; - } - else if (*puzStr <= 0x07FF) - { - ucTmp [0] = (FLMBYTE)(0xC0 | (FLMBYTE)(uzChar >> 6)); - ucTmp [1] = (FLMBYTE)(0x80 | (FLMBYTE)(uzChar & 0x003F)); - uiLen = 2; - } - else - { - ucTmp [0] = (FLMBYTE)(0xE0 | (FLMBYTE)(uzChar >> 12)); - ucTmp [1] = (FLMBYTE)(0x80 | (FLMBYTE)((uzChar & 0x0FC0) >> 6)); - ucTmp [2] = (FLMBYTE)(0x80 | (FLMBYTE)(uzChar & 0x003F)); - uiLen = 3; - } - if (RC_BAD( rc = pOStream->write( (void *)&ucTmp[0], uiLen))) - { - goto Exit; - } - - if( bIndent && uiIndentCount) - { - for( uiICount = uiIndentCount; uiICount; uiICount--) - { - if (RC_BAD( rc = pOStream->write( (void *)"\t", 1))) - { - goto Exit; - } - } - bIndent = FALSE; - } - } - puzStr++; - uiCharOffset++; - } - -Exit: - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Output an attribute to the string buffer. -*****************************************************************************/ -#if 0 -RCODE F_Attribute::outputAttr( - IF_OStream * pOStream) -{ - RCODE rc = NE_FLM_OK; - - if (RC_BAD( rc = pOStream->write( (void *)" ", 1))) - { - goto Exit; - } - if (m_uiPrefixChars) - { - if (RC_BAD( rc = exportUniValue( pOStream, m_puzPrefix, m_uiPrefixChars, FALSE, 0))) - { - goto Exit; - } - if (RC_BAD( rc = pOStream->write( (void *)":", 1))) - { - goto Exit; - } - } - - if (RC_BAD( rc = exportUniValue( pOStream, m_puzName, m_uiNameChars, FALSE, 0))) - { - goto Exit; - } - - if (RC_BAD( rc = pOStream->write( (void *)"=\"", 2))) - { - goto Exit; - } - - if (RC_BAD( rc = exportUniValue( pOStream, m_puzValue, m_uiValueChars, TRUE, 0))) - { - goto Exit; - } - - if (RC_BAD( rc = pOStream->write( (void *)"\"", 1))) - { - goto Exit; - } - -Exit: - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Allocate a new attribute. -*****************************************************************************/ -#if 0 -RCODE F_Element::allocAttr( - F_Attribute ** ppAttr - ) -{ - RCODE rc = NE_FLM_OK; - - if ((*ppAttr = *m_ppAvailAttrs) != NULL) - { - *m_ppAvailAttrs = (*ppAttr)->m_pNext; - (*ppAttr)->reset( this); - } - else - { - if ((*ppAttr = f_new F_Attribute( this)) == NULL) - { - rc = RC_SET( NE_FLM_MEM); - goto Exit; - } - } - -Exit: - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Save an attribute in an element. Put at end of list. -*****************************************************************************/ -#if 0 -RCODE F_Element::saveAttribute( - IF_Db * pDb, - IF_DOMNode * pNode - ) -{ - RCODE rc = NE_FLM_OK; - F_Attribute * pAttr = NULL; - - if (RC_BAD( rc = allocAttr( &pAttr))) - { - goto Exit; - } - - // Set up the attribute - - if (RC_BAD( rc = pAttr->setupAttribute( pDb, pNode))) - { - goto Exit; - } - - // Put attribute at end of list of attributes. - - pAttr->m_pNext = NULL; - if (m_pLastAttr) - { - m_pLastAttr->m_pNext = pAttr; - } - else - { - m_pFirstAttr = pAttr; - } - m_pLastAttr = pAttr; - - // Set pAttr to NULL so it won't be made available at exit. - - pAttr = NULL; - -Exit: - - if (pAttr) - { - makeAttrAvail( pAttr); - } - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Allocate space for the element's name and namespace. -*****************************************************************************/ -#if 0 -RCODE F_Element::allocNameSpace( void) -{ - RCODE rc = NE_FLM_OK; - FLMUINT uiSpaceNeeded; - FLMUNICODE * puzTmp; - - uiSpaceNeeded = (m_uiNameChars + m_uiNamespaceChars + 2) * sizeof( FLMUNICODE); - - // Allocate space for the name and namespace - - if (uiSpaceNeeded > m_uiTmpSpaceSize) - { - - if (RC_BAD( rc = f_alloc( uiSpaceNeeded, &puzTmp))) - { - goto Exit; - } - if (m_puzName != &m_uzTmpSpace [0]) - { - f_free( &m_puzName); - } - m_puzName = puzTmp; - m_uiTmpSpaceSize = uiSpaceNeeded; - } - m_puzNamespace = &m_puzName [m_uiNameChars + 1]; - -Exit: - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Setup an element with its namespace, etc. -*****************************************************************************/ -#if 0 -RCODE F_Element::setupElement( - IF_Db * pDb, - IF_DOMNode * pNode - ) -{ - RCODE rc = NE_FLM_OK; - IF_DOMNode * pAttrNode = NULL; - F_Attribute * pAttr; - - // Get the length of the name of the element - - if (RC_BAD( rc = pNode->getLocalName( pDb, (FLMUNICODE *)NULL, - 0, &m_uiNameChars))) - { - goto Exit; - } - - // Get the number of characters in the namespace of the element - - if (RC_BAD( rc = pNode->getNamespaceURI( pDb, (FLMUNICODE *)NULL, - 0, &m_uiNamespaceChars))) - { - goto Exit; - } - - if (RC_BAD( rc = allocNameSpace())) - { - goto Exit; - } - - // Get the element name. - - if (RC_BAD( rc = pNode->getLocalName( pDb, m_puzName, - (m_uiNameChars + 1) * sizeof( FLMUNICODE), - &m_uiNameChars))) - { - goto Exit; - } - - // Get the namespace, if necessary - - if (m_uiNamespaceChars) - { - if (RC_BAD( rc = pNode->getNamespaceURI( pDb, m_puzNamespace, - (m_uiNamespaceChars + 1) * sizeof( FLMUNICODE), - &m_uiNamespaceChars))) - { - goto Exit; - } - } - - // See if the node has any attributes. - - for (;;) - { - rc = (RCODE)(pAttrNode - ? pAttrNode->getNextSibling( pDb, &pAttrNode) - : pNode->getFirstAttribute( pDb, &pAttrNode)); - if (RC_BAD( rc)) - { - if (rc == NE_FLM_DOM_NODE_NOT_FOUND) - { - rc = NE_FLM_OK; - break; - } - else - { - goto Exit; - } - } - if (RC_BAD( rc = saveAttribute( pDb, pAttrNode))) - { - goto Exit; - } - } - - // Get the prefix for the element - - if (RC_BAD( rc = setPrefix())) - { - goto Exit; - } - - // Set the prefix for every attribute - - pAttr = m_pFirstAttr; - while (pAttr) - { - if (RC_BAD( rc = pAttr->setPrefix())) - { - goto Exit; - } - pAttr = pAttr->m_pNext; - } - -Exit: - - if (pAttrNode) - { - pAttrNode->Release(); - } - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Add an attribute that is a namespace to an element. -*****************************************************************************/ -#if 0 -RCODE F_Element::addNamespaceDecl( - FLMUNICODE * puzPrefix, - FLMUINT uiPrefixChars, - FLMUNICODE * puzNamespace, - FLMUINT uiNamespaceChars, - F_Attribute ** ppAttr - ) -{ - RCODE rc = NE_FLM_OK; - F_Attribute * pAttr = NULL; - - // If uiPrefixChars is zero, we are being asked to create a default - // namespace. But that can only be output once in the element, - // so make sure it is not already declared. If it is, do nothing. - - if (!uiPrefixChars) - { - pAttr = m_pFirstAttr; - while (pAttr && !pAttr->m_bDefaultNamespaceDecl) - { - pAttr = pAttr->m_pNext; - } - if (pAttr) - { - goto Exit; - } - } - - if (RC_BAD( rc = allocAttr( &pAttr))) - { - goto Exit; - } - pAttr->m_bIsNamespaceDecl = TRUE; - - // name will be "xmlns:" or, in the case of no namespace, "xmlns" - - if (!uiPrefixChars) - { - - // "xmlns" - but make sure not already declared. - - pAttr->m_uiNameChars = 5; - pAttr->m_bDefaultNamespaceDecl = TRUE; - } - else - { - - // "xmlns:" - - pAttr->m_uiNameChars = uiPrefixChars + 6; - } - pAttr->m_uiNamespaceChars = 0; - pAttr->m_uiValueChars = uiNamespaceChars; - - if (RC_BAD( rc = pAttr->allocNameSpace())) - { - goto Exit; - } - - // Always output "xmlns" as the first part of the name - - f_memcpy( pAttr->m_puzName, gv_puzNamespaceDeclPrefix, 5 * sizeof( FLMUNICODE)); - if (uiPrefixChars) - { - pAttr->m_puzName [5] = ':'; - f_memcpy( &pAttr->m_puzName [6], puzPrefix, uiPrefixChars * sizeof( FLMUNICODE)); - pAttr->m_puzName [6 + uiPrefixChars] = 0; - } - else - { - pAttr->m_puzName [5] = 0; - } - if (uiNamespaceChars) - { - f_memcpy( pAttr->m_puzValue, puzNamespace, - uiNamespaceChars * sizeof( FLMUNICODE)); - } - pAttr->m_puzValue [pAttr->m_uiValueChars] = 0; - - // Put new namespace decl at front of list of attributes. - - if ((pAttr->m_pNext = m_pFirstAttr) == NULL) - { - m_pLastAttr = pAttr; - } - m_pFirstAttr = pAttr; - *ppAttr = pAttr; - - // Set pAttr to NULL so that it won't be made available at exit. - - pAttr = NULL; - -Exit: - - if (pAttr) - { - makeAttrAvail( pAttr); - } - return( rc); -} -#endif - -/***************************************************************************** -Desc: Generate a random prefix, ensure that it is not defined anywhere - in the path. -*****************************************************************************/ -#if 0 -void F_Element::genPrefix( - FLMUNICODE * puzPrefix, - FLMUINT * puiPrefixChars - ) -{ - FLMUINT uiTmp; - FLMUINT uiPrefixChars; - FLMUNICODE * puzTmp; - F_Attribute * pAttr; - F_Element * pElement; - - puzPrefix [0] = 'p'; - puzPrefix [1] = 'r'; - puzPrefix [2] = 'f'; - puzPrefix [3] = 'x'; - for (;;) - { - - // Append the number in reverse digit order - it really doesn't matter - // because we're just trying to generate a unique prefix number. - - puzTmp = &puzPrefix [4]; - uiPrefixChars = 4; - uiTmp = *m_puiNextPrefixNum; - do - { - *puzTmp++ = (FLMUNICODE)((uiTmp % 10) + '0'); - uiPrefixChars++; - uiTmp /= 10; - } while (uiTmp); - - // See if the prefix is defined. - - pAttr = m_pFirstAttr; - pElement = this; - while (pAttr) - { - if (pAttr->m_bIsNamespaceDecl && - pAttr->m_uiNameChars > 6 && - pAttr->m_uiNameChars - 6 == uiPrefixChars && - f_memcmp( puzPrefix, &pAttr->m_puzName [6], - uiPrefixChars * sizeof( FLMUNICODE)) == 0) - { - break; - } - if ((pAttr = pAttr->m_pNext) == NULL) - { - pElement = pElement->m_pParentElement; - while (pElement && !pElement->m_pFirstAttr) - { - pElement = pElement->m_pParentElement; - } - if (!pElement) - { - break; - } - pAttr = pElement->m_pFirstAttr; - } - } - - // If the prefix was not defined, we can use it. - - if (!pAttr) - { - break; - } - (*m_puiNextPrefixNum)++; - } - puzPrefix [uiPrefixChars] = 0; - *puiPrefixChars = uiPrefixChars; -} -#endif - -/***************************************************************************** -Desc: Find a prefix for a namespace -*****************************************************************************/ -#if 0 -RCODE F_Element::findPrefix( - FLMUNICODE * puzNamespace, - FLMUINT uiNamespaceChars, - FLMBOOL bForElement, - FLMUNICODE ** ppuzPrefix, - FLMUINT * puiPrefixChars) -{ - RCODE rc = NE_FLM_OK; - F_Attribute * pAttr = m_pFirstAttr; - F_Element * pElement = this; - FLMUNICODE uzPrefix [50]; - FLMUINT uiPrefixChars; - - for (;;) - { - if ( pAttr) - { - if (pAttr->m_bIsNamespaceDecl && - uiNamespaceChars == pAttr->m_uiValueChars && - (!uiNamespaceChars || - f_memcmp( puzNamespace, pAttr->m_puzValue, - uiNamespaceChars * sizeof( FLMUNICODE)) == 0)) - { - - // Don't set the prefix if it is the default namespace. - - if (!pAttr->m_bDefaultNamespaceDecl) - { - // Prefix comes after the "xmlns:" - - *ppuzPrefix = &pAttr->m_puzName [6]; - *puiPrefixChars = pAttr->m_uiNameChars - 6; - goto Exit; - } - - // Default namespace is only OK for elements, - // but not attributes. We don't want to count - // attributes as having been "found" if they matched - // the default namespace. This routine is only called - // for attributes if the attribute namepace is non-empty. - - else if (bForElement) - { - goto Exit; - } - } - pAttr = pAttr->m_pNext; - } - if ( !pAttr) - { - pElement = pElement->m_pParentElement; - while (pElement && !pElement->m_pFirstAttr) - { - pElement = pElement->m_pParentElement; - } - if (!pElement) - { - break; - } - pAttr = pElement->m_pFirstAttr; - } - } - - // If namespaces is empty, the only declaration that is legal is - // a default namespace declaration. - - if (!uiNamespaceChars) - { - if (RC_BAD( rc = addNamespaceDecl( NULL, 0, NULL, 0, &pAttr))) - { - goto Exit; - } - } - else - { - - // Manufacture a prefix that is not used in the hierarchy yet. - - genPrefix( uzPrefix, &uiPrefixChars); - if (RC_BAD( rc = addNamespaceDecl( uzPrefix, uiPrefixChars, puzNamespace, - uiNamespaceChars, &pAttr))) - { - goto Exit; - } - - *ppuzPrefix = &pAttr->m_puzName [6]; - *puiPrefixChars = pAttr->m_uiNameChars - 6; - } - -Exit: - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Output the element name, with its attributes - this marks the - beginning of the element. -*****************************************************************************/ -#if 0 -RCODE F_Element::outputElem( - IF_OStream * pOStream, - FLMBOOL bStartOfElement, - FLMBOOL bEndOfElement, - FLMBOOL bAddNewLine) -{ - RCODE rc = NE_FLM_OK; - F_Attribute * pAttr; - F_Attribute * pPrevAttr; - FLMUINT uiIndentCount = 0; - FLMBOOL bEndNode; - - bEndNode = ( m_bIsDocumentRoot && !bStartOfElement); - if( bAddNewLine && ( !m_bIsDocumentRoot || bEndNode)) - { - if (RC_BAD( rc = pOStream->write( (void *)"\n", 1))) - { - goto Exit; - } - for( uiIndentCount = 0; uiIndentCount < m_uiIndentCount; uiIndentCount++) - { - if (RC_BAD( rc = pOStream->write( (void *)"\t", 1))) - { - goto Exit; - } - } - } - - // Output the element name - if ( bStartOfElement) - { - - if (RC_BAD( rc = pOStream->write( (void *)"<", 1))) - { - goto Exit; - } - } - else - { - - if (RC_BAD( rc = pOStream->write( (void *)"write( (void *)":", 1))) - { - goto Exit; - } - } - - if (RC_BAD( rc = exportUniValue( pOStream, m_puzName, m_uiNameChars, FALSE, 0))) - { - goto Exit; - } - - if (bStartOfElement) - { - - // Output the attributes. As we go, remove any attributes that are - // not namespace declarations. They are not needed after this. - - pPrevAttr = NULL; - pAttr = m_pFirstAttr; - while (pAttr) - { - if (RC_BAD( rc = pAttr->outputAttr( pOStream))) - { - goto Exit; - } - - if (!pAttr->m_bIsNamespaceDecl) - { - if (pPrevAttr) - { - pPrevAttr->m_pNext = pAttr->m_pNext; - makeAttrAvail( pAttr); - pAttr = pPrevAttr->m_pNext; - } - else - { - m_pFirstAttr = pAttr->m_pNext; - makeAttrAvail( pAttr); - pAttr = m_pFirstAttr; - } - - // See if we deleted the last attribute in the list. - - if (!pAttr) - { - m_pLastAttr = pPrevAttr; - } - } - else - { - pPrevAttr = pAttr; - pAttr = pAttr->m_pNext; - } - } - } - - // Close out the element - if (RC_BAD( rc = (RCODE)(bStartOfElement && bEndOfElement - ? pOStream->write( (void *)"/>", 2) - : pOStream->write( (void *)">", 1)))) - { - goto Exit; - } - - if ( bAddNewLine && bEndNode) - { - if (RC_BAD( rc = pOStream->write( (void *)"\n", 1))) - { - goto Exit; - } - } - - -Exit: - - return( rc); -} -#endif - -/***************************************************************************** -Desc: Output Data that is contained on an element node. -*****************************************************************************/ -#if 0 -RCODE F_Element::outputLocalData( - IF_OStream * pOStream, - IF_DOMNode * pDbNode, - IF_Db * ifpDb, - eExportFormatType eFormatType, - FLMUINT uiIndentCount) -{ - RCODE rc = NE_FLM_OK; - FLMUNICODE uzTmpData [150]; - FLMUNICODE * puzData = &uzTmpData [0]; - FLMUINT uiDataBufSize = sizeof( uzTmpData); - FLMUINT uiChars; - - if (RC_BAD( rc = pDbNode->getUnicodeChars( ifpDb, &uiChars))) - { - goto Exit; - } - - - if (uiDataBufSize < (uiChars + 1) * sizeof( FLMUNICODE)) - { - FLMUNICODE * puzNew; - - if (RC_BAD( rc = f_alloc( (uiChars + 1) * sizeof( FLMUNICODE), - &puzNew))) - { - goto Exit; - } - if (puzData != &uzTmpData [0]) - { - f_free( &puzData); - } - puzData = puzNew; - uiDataBufSize = (uiChars + 1) * sizeof( FLMUNICODE); - } - if (RC_BAD( rc = pDbNode->getUnicode( ifpDb, puzData, - uiDataBufSize, 0, uiChars, &uiChars))) - { - goto Exit; - } - - // Output the value. - if (RC_BAD( rc = exportUniValue( pOStream, puzData, uiChars, TRUE, - eFormatType >= FLM_EXPORT_INDENT_DATA ? uiIndentCount : 0))) - { - goto Exit; - } - -Exit: - - return ( rc); -} -#endif - -/***************************************************************************** -Desc: Outputs a UTF8 stream of XML, starting at the specified node. Node and - all of its descendant nodes are output. -*****************************************************************************/ -#if 0 -RCODE XFLMAPI F_Db::exportXML( - IF_DOMNode * pStartNode, - IF_OStream * pOStream, - eExportFormatType eFormatType) -{ - RCODE rc = NE_FLM_OK; - F_Element * pAvailElements = NULL; - F_Element * pTmpElement; - F_Attribute * pAvailAttrs = NULL; - F_Attribute * pTmpAttr; - FLMUNICODE uzTmpData [150]; - FLMUNICODE * puzData = &uzTmpData [0]; - FLMUINT uiDataBufSize = sizeof( uzTmpData); - IF_DOMNode * pDbNode = NULL; - eDomNodeType ePrevNodeType; - F_Element * pCurrElement = NULL; - FLMUINT uiNextPrefixNum = 0; - FLMBOOL bStartOfDocument = TRUE; - FLMBOOL bShouldFormat = FALSE; - FLMBOOL bIsDataLocal = FALSE; - FLMUINT uiIndentCount = 0; - FLMUINT uiICount = 0; - - // This routine should only be called if the node type is element node. - - flmAssert( pStartNode->getNodeType() == ELEMENT_NODE); - - ePrevNodeType = ELEMENT_NODE; - pDbNode = pStartNode; - pDbNode->AddRef(); - - for (;;) - { - // Output the current node, depending on its type. - - if( pDbNode->getNodeType() == ELEMENT_NODE) - { - if (pAvailElements) - { - pTmpElement = pAvailElements; - pAvailElements = pAvailElements->getNext(); - pTmpElement->reset( pCurrElement, &pAvailAttrs, &uiNextPrefixNum); - } - else - { - if ((pTmpElement = f_new F_Element( pCurrElement, &pAvailAttrs, - &uiNextPrefixNum)) == NULL) - { - rc = RC_SET( NE_FLM_MEM); - goto Exit; - } - } - - pCurrElement = pTmpElement; - - if (RC_BAD( rc = pCurrElement->setupElement( (IF_Db *)this, pDbNode))) - { - goto Exit; - } - - if( eFormatType >= FLM_EXPORT_INDENT) - { - pCurrElement->setIndentCount(uiIndentCount); - } - - if( pDbNode == pStartNode) - { - pCurrElement->setDocumentRoot( TRUE); - } - - // Only want a New Line and tabs for Element if: - // 1) New Line format is indicated - // 2) Previous Element Was NOT Data - bShouldFormat = ( (eFormatType >= FLM_EXPORT_NEW_LINE) && - (ePrevNodeType != DATA_NODE)) - ? TRUE - : FALSE; - - if( RC_BAD( rc = pDbNode->isDataLocalToNode( (IF_Db *)this, - &bIsDataLocal))) - { - goto Exit; - } - - if( bIsDataLocal) - { - if( RC_BAD( rc = pCurrElement->outputElem( pOStream, - TRUE, FALSE, bShouldFormat))) - { - goto Exit; - } - - pCurrElement->outputLocalData( pOStream, - pDbNode, - (IF_Db *)this, - eFormatType, - uiIndentCount); - - } - - if( RC_OK( rc = pDbNode->getFirstChild( (IF_Db *)this, &pDbNode))) - { - if( !bIsDataLocal && RC_BAD( rc = pCurrElement->outputElem( - pOStream, TRUE, FALSE, bShouldFormat))) - { - goto Exit; - } - - bStartOfDocument = FALSE; - uiIndentCount++; - ePrevNodeType = ELEMENT_NODE; - continue; - } - - if( rc != NE_FLM_DOM_NODE_NOT_FOUND) - { - goto Exit; - } - - // Write out the "/>" for the element, because it had no - // child nodes. - - if( bIsDataLocal) - { - if( RC_BAD( rc = pCurrElement->outputElem( pOStream, - FALSE, TRUE, bShouldFormat))) - { - goto Exit; - } - } - else - { - if( RC_BAD( rc = pCurrElement->outputElem( pOStream, - TRUE, TRUE, bShouldFormat))) - { - goto Exit; - } - } - - // We are now done with this element - - ePrevNodeType = ELEMENT_NODE; - pTmpElement = pCurrElement; - pCurrElement = pCurrElement->getParentElement(); - pTmpElement->makeAvail( &pAvailElements); - - if( !pCurrElement) - { - break; - } - -Get_Element_Sibling: - - // See if we have a sibling. Go up tree until we find - // a node that has a sibling. - - for( ;;) - { - if( RC_OK( rc = pDbNode->getNextSibling( (IF_Db *)this, &pDbNode))) - { - break; - } - - if( rc != NE_FLM_DOM_NODE_NOT_FOUND) - { - goto Exit; - } - - // Need to close previous element - - if( uiIndentCount) - { - uiIndentCount--; - } - - if( RC_BAD( rc = pCurrElement->outputElem( pOStream, FALSE, TRUE, - eFormatType >= FLM_EXPORT_NEW_LINE - ? TRUE - : FALSE))) - { - goto Exit; - } - - if( RC_BAD( rc = pDbNode->getParentNode( (IF_Db *)this, &pDbNode))) - { - if( rc == NE_FLM_DOM_NODE_NOT_FOUND) - { - // There should be a parent node at this point! - - rc = RC_SET_AND_ASSERT( NE_FLM_DATA_ERROR); - } - - goto Exit; - } - - pTmpElement = pCurrElement; - pCurrElement = pCurrElement->getParentElement(); - pTmpElement->makeAvail( &pAvailElements); - - if( !pCurrElement) - { - pDbNode->Release(); - pDbNode = NULL; - goto Exit; - } - } - } - else - { - // Only output data, comment, and cdata nodes. - - if( pDbNode->getNodeType() == DATA_NODE || - pDbNode->getNodeType() == COMMENT_NODE || - pDbNode->getNodeType() == CDATA_SECTION_NODE) - { - FLMUINT uiChars; - - if( RC_BAD( rc = pDbNode->getUnicodeChars( (IF_Db *)this, - &uiChars))) - { - goto Exit; - } - - if( uiDataBufSize < (uiChars + 1) * sizeof( FLMUNICODE)) - { - FLMUNICODE * puzNew; - - if( RC_BAD( rc = f_alloc( (uiChars + 1) * sizeof( FLMUNICODE), - &puzNew))) - { - goto Exit; - } - - if( puzData != &uzTmpData [0]) - { - f_free( &puzData); - } - - puzData = puzNew; - uiDataBufSize = (uiChars + 1) * sizeof( FLMUNICODE); - } - - if( RC_BAD( rc = pDbNode->getUnicode( (IF_Db *)this, puzData, - uiDataBufSize, 0, uiChars, &uiChars))) - { - goto Exit; - } - - if( pDbNode->getNodeType() == DATA_NODE) - { - // Output the value - - if (RC_BAD( rc = exportUniValue( pOStream, puzData, uiChars, - TRUE, eFormatType >= FLM_EXPORT_INDENT_DATA - ? uiIndentCount - : 0))) - { - goto Exit; - } - - ePrevNodeType = DATA_NODE; - } - else if( pDbNode->getNodeType() == COMMENT_NODE) - { - //If Comment Node follows Data Node do not add new line - - if( eFormatType >= FLM_EXPORT_INDENT_DATA && - ePrevNodeType != DATA_NODE) - { - if (RC_BAD( rc = pOStream->write( (void *)"\n", 1))) - { - goto Exit; - } - - for( uiICount = 0; uiICount < uiIndentCount; uiICount++) - { - if (RC_BAD( rc = pOStream->write( (void *)"\t", 1))) - { - goto Exit; - } - } - } - - // Output the beginning of a comment - - if (RC_BAD( rc = pOStream->write( (void *)"", 3))) - { - goto Exit; - } - - ePrevNodeType = COMMENT_NODE; - } - else - { - // Output the beginning of a cdata section - - if( RC_BAD( rc = pOStream->write( (void *)"write( (void *)"]]>", 3))) - { - goto Exit; - } - - ePrevNodeType = CDATA_SECTION_NODE; - } - } - - // Have a data node, or comment node probably - // In any case, see if there are any sibling nodes. - // If not, go back to enclosing element node. - - if( RC_OK( rc = pDbNode->getNextSibling( (IF_Db *)this, &pDbNode))) - { - continue; - } - - if( rc != NE_FLM_DOM_NODE_NOT_FOUND) - { - goto Exit; - } - - // Go back up to enclosing element - - if( RC_BAD( rc = pDbNode->getParentNode( (IF_Db *)this, &pDbNode))) - { - // There better be a parent node or we have a corruption! - - if( rc == NE_FLM_DOM_NODE_NOT_FOUND) - { - rc = RC_SET( NE_FLM_DATA_ERROR); - } - - goto Exit; - } - - // Parent node better be an element - - if( pDbNode->getNodeType() != ELEMENT_NODE) - { - rc = RC_SET_AND_ASSERT( NE_FLM_DATA_ERROR); - goto Exit; - } - - // If we were traversing the attributes of an element, - // we need to now go back and get its child nodes. - - // Write out the for the element - - if( RC_BAD( rc = pCurrElement->outputElem( pOStream, - FALSE, TRUE, FALSE))) - { - goto Exit; - } - - // We are now done with this element - - if( uiIndentCount) - { - uiIndentCount--; - } - - ePrevNodeType = ELEMENT_NODE; - pTmpElement = pCurrElement; - pCurrElement = pCurrElement->getParentElement(); - pTmpElement->makeAvail( &pAvailElements); - - if( !pCurrElement) - { - break; - } - - goto Get_Element_Sibling; - } - } - -Exit: - - if( puzData != &uzTmpData [0]) - { - f_free( &puzData); - } - - while( pCurrElement) - { - pTmpElement = pCurrElement; - pCurrElement = pCurrElement->getParentElement(); - delete pTmpElement; - } - - while( pAvailElements) - { - pTmpElement = pAvailElements; - pAvailElements = pAvailElements->getNext(); - delete pTmpElement; - } - - while( pAvailAttrs) - { - pTmpAttr = pAvailAttrs; - pAvailAttrs = pAvailAttrs->getNext(); - delete pTmpAttr; - } - - if( pDbNode) - { - pDbNode->Release(); - } - - return( rc); -} -#endif