first commit

This commit is contained in:
murdle
2026-03-01 02:38:58 +02:00
commit 19250b9db4
19111 changed files with 4358159 additions and 0 deletions

View File

@@ -0,0 +1,968 @@
// 4J-PB -
// The ATG Framework is a common set of C++ class libraries that is used by the samples in the XDK, and was developed by the Advanced Technology Group (ATG).
// The ATG Framework offers a clean and consistent format for the samples. These classes define functions used by all the samples.
// The ATG Framework together with the samples demonstrates best practices and innovative techniques for Xbox 360. There are many useful sections of code in the samples.
// You are encouraged to incorporate this code into your titles.
//-------------------------------------------------------------------------------------
// AtgXmlParser.cpp
//
// Simple callback non-validating XML parser implementation.
//
// Xbox Advanced Technology Group.
// Copyright (C) Microsoft Corporation. All rights reserved.
//-------------------------------------------------------------------------------------
#include "stdafx.h"
#include "AtgXmlParser.h"
namespace ATG
{
//-------------------------------------------------------------------------------------
// Name: XMLParser::XMLParser
//-------------------------------------------------------------------------------------
XMLParser::XMLParser()
{
m_pWritePtr = m_pWriteBuf;
m_pReadPtr = m_pReadBuf;
m_pISAXCallback = NULL;
m_hFile = INVALID_HANDLE_VALUE;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::~XMLParser
//-------------------------------------------------------------------------------------
XMLParser::~XMLParser()
{
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::FillBuffer
// Desc: Reads a block from the current open file
//-------------------------------------------------------------------------------------
VOID XMLParser::FillBuffer()
{
DWORD NChars;
m_pReadPtr = m_pReadBuf;
if( m_hFile == NULL )
{
if( m_uInXMLBufferCharsLeft > XML_READ_BUFFER_SIZE )
NChars = XML_READ_BUFFER_SIZE;
else
NChars = m_uInXMLBufferCharsLeft;
CopyMemory( m_pReadBuf, m_pInXMLBuffer, NChars );
m_uInXMLBufferCharsLeft -= NChars;
m_pInXMLBuffer += NChars;
}
else
{
if( !ReadFile( m_hFile, m_pReadBuf, XML_READ_BUFFER_SIZE, &NChars, NULL ))
{
return;
}
}
m_dwCharsConsumed += NChars;
__int64 iProgress = m_dwCharsTotal ? (( (__int64)m_dwCharsConsumed * 1000 ) / (__int64)m_dwCharsTotal) : 0;
m_pISAXCallback->SetParseProgress( (DWORD)iProgress );
m_pReadBuf[ NChars ] = '\0';
m_pReadBuf[ NChars + 1] = '\0';
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::SkipNextAdvance
// Desc: Puts the last character read back on the input stream
//-------------------------------------------------------------------------------------
VOID XMLParser::SkipNextAdvance()
{
m_bSkipNextAdvance = TRUE;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::ConsumeSpace
// Desc: Skips spaces in the current stream
//-------------------------------------------------------------------------------------
HRESULT XMLParser::ConsumeSpace()
{
HRESULT hr;
// Skip spaces
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
while ( ( m_Ch == ' ' ) || ( m_Ch == '\t' ) ||
( m_Ch == '\n' ) || ( m_Ch == '\r' ) )
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
}
SkipNextAdvance();
return S_OK;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::ConvertEscape
// Desc: Copies and converts an escape sequence into m_pWriteBuf
//-------------------------------------------------------------------------------------
HRESULT XMLParser::ConvertEscape()
{
HRESULT hr;
WCHAR wVal = 0;
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
// all escape sequences start with &, so ignore the first character
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if ( m_Ch == '#' ) // character as hex or decimal
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if ( m_Ch == 'x' ) // hex number
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
while ( m_Ch != ';' )
{
wVal *= 16;
if ( ( m_Ch >= '0' ) && ( m_Ch <= '9' ) )
{
wVal += m_Ch - '0';
}
else if ( ( m_Ch >= 'a' ) && ( m_Ch <= 'f' ) )
{
wVal += m_Ch - 'a' + 10;
}
else if ( ( m_Ch >= 'A' ) && ( m_Ch <= 'F' ) )
{
wVal += m_Ch - 'A' + 10;
}
else
{
Error( E_INVALID_XML_SYNTAX, "Expected hex digit as part of &#x escape sequence" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
}
}
else // decimal number
{
while ( m_Ch != ';' )
{
wVal *= 10;
if ( ( m_Ch >= '0' ) && ( m_Ch <= '9' ) )
{
wVal += m_Ch - '0';
}
else
{
Error( E_INVALID_XML_SYNTAX, "Expected decimal digit as part of &# escape sequence" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
}
}
// copy character into the buffer
m_Ch = wVal;
return S_OK;
}
// must be an entity reference
WCHAR *pEntityRefVal = m_pWritePtr;
UINT EntityRefLen;
SkipNextAdvance();
if( FAILED( hr = AdvanceName() ) )
return hr;
EntityRefLen = (UINT)( m_pWritePtr - pEntityRefVal );
m_pWritePtr = pEntityRefVal;
if ( EntityRefLen == 0 )
{
Error( E_INVALID_XML_SYNTAX, "Expecting entity name after &" );
return E_INVALID_XML_SYNTAX;
}
if( !wcsncmp( pEntityRefVal, L"lt", EntityRefLen ) )
wVal = '<';
else if( !wcsncmp( pEntityRefVal, L"gt", EntityRefLen ) )
wVal = '>';
else if( !wcsncmp( pEntityRefVal, L"amp", EntityRefLen ) )
wVal = '&';
else if( !wcsncmp( pEntityRefVal, L"apos", EntityRefLen ) )
wVal = '\'';
else if( !wcsncmp( pEntityRefVal, L"quot", EntityRefLen ) )
wVal = '"';
else
{
Error( E_INVALID_XML_SYNTAX, "Unrecognized entity name after & - (should be lt, gt, amp, apos, or quot)" );
return E_INVALID_XML_SYNTAX; // return false if unrecognized token sequence
}
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != ';' )
{
Error( E_INVALID_XML_SYNTAX, "Expected terminating ; for entity reference" );
return E_INVALID_XML_SYNTAX; // malformed reference - needs terminating ;
}
m_Ch = wVal;
return S_OK;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::AdvanceAttrVal
// Desc: Copies an attribute value into m_pWrite buf, skipping surrounding quotes
//-------------------------------------------------------------------------------------
HRESULT XMLParser::AdvanceAttrVal()
{
HRESULT hr;
WCHAR wQuoteChar;
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( ( m_Ch != '"' ) && ( m_Ch != '\'' ) )
{
Error( E_INVALID_XML_SYNTAX, "Attribute values must be enclosed in quotes" );
return E_INVALID_XML_SYNTAX;
}
wQuoteChar = m_Ch;
for( ;; )
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
else if( m_Ch == wQuoteChar )
break;
else if( m_Ch == '&' )
{
SkipNextAdvance();
if( FAILED( hr = ConvertEscape() ) )
return hr;
}
else if( m_Ch == '<' )
{
Error( E_INVALID_XML_SYNTAX, "Illegal character '<' in element tag" );
return E_INVALID_XML_SYNTAX;
}
// copy character into the buffer
if( m_pWritePtr - m_pWriteBuf >= XML_WRITE_BUFFER_SIZE )
{
Error( E_INVALID_XML_SYNTAX, "Total element tag size may not be more than %d characters", XML_WRITE_BUFFER_SIZE );
return E_INVALID_XML_SYNTAX;
}
*m_pWritePtr = m_Ch;
m_pWritePtr++;
}
return S_OK;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::AdvanceName
// Desc: Copies a name into the m_pWriteBuf - returns TRUE on success, FALSE on failure
// Ignores leading whitespace. Currently does not support unicode names
//-------------------------------------------------------------------------------------
HRESULT XMLParser::AdvanceName()
{
HRESULT hr;
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( ( ( m_Ch < 'A' ) || ( m_Ch > 'Z' ) ) &&
( ( m_Ch < 'a' ) || ( m_Ch > 'z' ) ) &&
( m_Ch != '_' ) && ( m_Ch != ':' ) )
{
Error( E_INVALID_XML_SYNTAX, "Names must start with an alphabetic character or _ or :" );
return E_INVALID_XML_SYNTAX;
}
while( ( ( m_Ch >= 'A' ) && ( m_Ch <= 'Z' ) ) ||
( ( m_Ch >= 'a' ) && ( m_Ch <= 'z' ) ) ||
( ( m_Ch >= '0' ) && ( m_Ch <= '9' ) ) ||
( m_Ch == '_' ) || ( m_Ch == ':' ) ||
( m_Ch == '-' ) || ( m_Ch == '.' ) )
{
if( m_pWritePtr - m_pWriteBuf >= XML_WRITE_BUFFER_SIZE )
{
Error( E_INVALID_XML_SYNTAX, "Total element tag size may not be more than %d characters", XML_WRITE_BUFFER_SIZE );
return E_INVALID_XML_SYNTAX;
}
*m_pWritePtr = m_Ch;
m_pWritePtr++;
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
}
SkipNextAdvance();
return S_OK;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::AdvanceCharacter
// Desc: Copies the character at *m_pReadPtr to m_Ch
// handling difference in UTF16 / UTF8, and big/little endian
// and getting another chunk of the file if needed
// Returns S_OK if there are more characters, E_ABORT for no characters to read
//-------------------------------------------------------------------------------------
HRESULT XMLParser::AdvanceCharacter( BOOL bOkToFail )
{
if( m_bSkipNextAdvance )
{
m_bSkipNextAdvance = FALSE;
return S_OK;
}
// If we hit EOF in the middle of a character,
// it's ok-- we'll just have a corrupt last character
// (the buffer is padded with double NULLs )
if ( ( m_pReadPtr[0] == '\0' ) && ( m_pReadPtr[1] == '\0' ) )
{
// Read more from the file
FillBuffer();
// We are at EOF if it is still NULL
if ( ( m_pReadPtr[0] == '\0' ) && ( m_pReadPtr[1] == '\0' ) )
{
if( !bOkToFail )
{
Error( E_INVALID_XML_SYNTAX, "Unexpected EOF while parsing XML file" );
return E_INVALID_XML_SYNTAX;
}
else
{
return E_FAIL;
}
}
}
if( m_bUnicode == FALSE )
{
m_Ch = *((CHAR *)m_pReadPtr);
m_pReadPtr++;
}
else // if( m_bUnicode == TRUE )
{
m_Ch = *((WCHAR *)m_pReadPtr);
if( m_bReverseBytes )
{
m_Ch = ( m_Ch << 8 ) + ( m_Ch >> 8 );
}
m_pReadPtr += 2;
}
if( m_Ch == '\n' )
{
m_pISAXCallback->m_LineNum++;
m_pISAXCallback->m_LinePos = 0;
}
else if( m_Ch != '\r' )
m_pISAXCallback->m_LinePos++;
return S_OK;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::AdvanceElement
// Desc: Builds <element> data, calls callback
//-------------------------------------------------------------------------------------
HRESULT XMLParser::AdvanceElement()
{
HRESULT hr;
// write ptr at the beginning of the buffer
m_pWritePtr = m_pWriteBuf;
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
// if first character wasn't '<', we wouldn't be here
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch == '!' )
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if ( m_Ch == '-' )
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != '-' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '-' after '<!-'" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceComment() ) )
return hr;
return S_OK;
}
if( m_Ch != '[' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '<![CDATA['" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != 'C' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '<![CDATA['" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != 'D' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '<![CDATA['" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != 'A' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '<![CDATA['" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != 'T' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '<![CDATA['" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != 'A' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '<![CDATA['" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != '[' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '<![CDATA['" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = AdvanceCDATA() ) )
return hr;
}
else if( m_Ch == '/' )
{
WCHAR *pEntityRefVal = m_pWritePtr;
if( FAILED( hr = AdvanceName() ) )
return hr;
if( FAILED( m_pISAXCallback->ElementEnd( pEntityRefVal,
(UINT) ( m_pWritePtr - pEntityRefVal ) ) ) )
return E_ABORT;
if( FAILED( hr = ConsumeSpace() ) )
return hr;
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != '>' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '>' after name for closing entity reference" );
return E_INVALID_XML_SYNTAX;
}
}
else if( m_Ch == '?' )
{
// just skip any xml header tag since not really important after identifying character set
for( ;; )
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if ( m_Ch == '>' )
return S_OK;
}
}
else
{
XMLAttribute Attributes[ XML_MAX_ATTRIBUTES_PER_ELEMENT ];
UINT NumAttrs;
WCHAR *pEntityRefVal = m_pWritePtr;
UINT EntityRefLen;
NumAttrs = 0;
SkipNextAdvance();
// Entity tag
if( FAILED( hr = AdvanceName() ) )
return hr;
EntityRefLen = (UINT)( m_pWritePtr - pEntityRefVal );
if( FAILED( hr = ConsumeSpace() ) )
return hr;
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
// read attributes
while( ( m_Ch != '>' ) && ( m_Ch != '/' ) )
{
SkipNextAdvance();
if ( NumAttrs >= XML_MAX_ATTRIBUTES_PER_ELEMENT )
{
Error( E_INVALID_XML_SYNTAX, "Elements may not have more than %d attributes", XML_MAX_ATTRIBUTES_PER_ELEMENT );
return E_INVALID_XML_SYNTAX;
}
Attributes[ NumAttrs ].strName = m_pWritePtr;
// Attribute name
if( FAILED( hr = AdvanceName() ) )
return hr;
Attributes[ NumAttrs ].NameLen = (UINT)( m_pWritePtr - Attributes[ NumAttrs ].strName );
if( FAILED( hr = ConsumeSpace() ) )
return hr;
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != '=' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '=' character after attribute name" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( hr = ConsumeSpace() ) )
return hr;
Attributes[ NumAttrs ].strValue = m_pWritePtr;
if( FAILED( hr = AdvanceAttrVal() ) )
return hr;
Attributes[ NumAttrs ].ValueLen = (UINT)( m_pWritePtr -
Attributes[ NumAttrs ].strValue );
++NumAttrs;
if( FAILED( hr = ConsumeSpace() ) )
return hr;
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
}
if( m_Ch == '/' )
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if( m_Ch != '>' )
{
Error( E_INVALID_XML_SYNTAX, "Expecting '>' after '/' in element tag" );
return E_INVALID_XML_SYNTAX;
}
if( FAILED( m_pISAXCallback->ElementBegin( pEntityRefVal, EntityRefLen,
Attributes, NumAttrs ) ) )
return E_ABORT;
if( FAILED( m_pISAXCallback->ElementEnd( pEntityRefVal, EntityRefLen ) ) )
return E_ABORT;
}
else
{
if( FAILED( m_pISAXCallback->ElementBegin( pEntityRefVal, EntityRefLen,
Attributes, NumAttrs ) ) )
return E_ABORT;
}
}
return S_OK;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::AdvanceCDATA
// Desc: Read a CDATA section
//-------------------------------------------------------------------------------------
HRESULT XMLParser::AdvanceCDATA()
{
HRESULT hr;
WORD wStage = 0;
if( FAILED( m_pISAXCallback->CDATABegin() ) )
return E_ABORT;
for( ;; )
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
*m_pWritePtr = m_Ch;
m_pWritePtr++;
if( ( m_Ch == ']' ) && ( wStage == 0 ) )
wStage = 1;
else if( ( m_Ch == ']' ) && ( wStage == 1 ) )
wStage = 2;
else if( ( m_Ch == '>' ) && ( wStage == 2 ) )
{
m_pWritePtr -= 3;
break;
}
else
wStage = 0;
if( m_pWritePtr - m_pWriteBuf >= XML_WRITE_BUFFER_SIZE )
{
if( FAILED( m_pISAXCallback->CDATAData( m_pWriteBuf, (UINT)( m_pWritePtr - m_pWriteBuf ), TRUE ) ) )
return E_ABORT;
m_pWritePtr = m_pWriteBuf;
}
}
if( FAILED( m_pISAXCallback->CDATAData( m_pWriteBuf, (UINT)( m_pWritePtr - m_pWriteBuf ), FALSE ) ) )
return E_ABORT;
m_pWritePtr = m_pWriteBuf;
if( FAILED( m_pISAXCallback->CDATAEnd() ) )
return E_ABORT;
return S_OK;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::AdvanceComment
// Desk: Skips over a comment
//-------------------------------------------------------------------------------------
HRESULT XMLParser::AdvanceComment()
{
HRESULT hr;
WORD wStage;
wStage = 0;
for( ;; )
{
if( FAILED( hr = AdvanceCharacter() ) )
return hr;
if (( m_Ch == '-' ) && ( wStage == 0 ))
wStage = 1;
else if (( m_Ch == '-' ) && ( wStage == 1 ))
wStage = 2;
else if (( m_Ch == '>' ) && ( wStage == 2 ))
break;
else
wStage = 0;
}
return S_OK;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::RegisterSAXCallbackInterface
// Desc: Registers callback interface
//-------------------------------------------------------------------------------------
VOID XMLParser::RegisterSAXCallbackInterface( ISAXCallback *pISAXCallback )
{
m_pISAXCallback = pISAXCallback;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::GetSAXCallbackInterface
// Desc: Returns current callback interface
//-------------------------------------------------------------------------------------
ISAXCallback* XMLParser::GetSAXCallbackInterface()
{
return m_pISAXCallback;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::MainParseLoop
// Desc: Main Loop to Parse Data - source agnostic
//-------------------------------------------------------------------------------------
HRESULT XMLParser::MainParseLoop()
{
BOOL bWhiteSpaceOnly = TRUE;
HRESULT hr = S_OK;
if( FAILED( m_pISAXCallback->StartDocument() ) )
return E_ABORT;
m_pWritePtr = m_pWriteBuf;
FillBuffer();
if ( *((WCHAR *) m_pReadBuf ) == 0xFEFF )
{
m_bUnicode = TRUE;
m_bReverseBytes = FALSE;
m_pReadPtr += 2;
}
else if ( *((WCHAR *) m_pReadBuf ) == 0xFFFE )
{
m_bUnicode = TRUE;
m_bReverseBytes = TRUE;
m_pReadPtr += 2;
}
else if ( *((WCHAR *) m_pReadBuf ) == 0x003C )
{
m_bUnicode = TRUE;
m_bReverseBytes = FALSE;
}
else if ( *((WCHAR *) m_pReadBuf ) == 0x3C00 )
{
m_bUnicode = TRUE;
m_bReverseBytes = TRUE;
}
else if ( m_pReadBuf[ 0 ] == 0x3C )
{
m_bUnicode = FALSE;
m_bReverseBytes = FALSE;
}
else
{
Error( E_INVALID_XML_SYNTAX, "Unrecognized encoding (parser does not support UTF-8 language encodings)" );
return E_INVALID_XML_SYNTAX;
}
for( ;; )
{
if( FAILED( AdvanceCharacter( TRUE ) ) )
{
if ( ( (UINT) ( m_pWritePtr - m_pWriteBuf ) != 0 ) && ( !bWhiteSpaceOnly ) )
{
if( FAILED( m_pISAXCallback->ElementContent( m_pWriteBuf, (UINT)( m_pWritePtr - m_pWriteBuf ), FALSE ) ) )
return E_ABORT;
bWhiteSpaceOnly = TRUE;
}
if( FAILED( m_pISAXCallback->EndDocument() ) )
return E_ABORT;
return S_OK;
}
if( m_Ch == '<' )
{
if( ( (UINT) ( m_pWritePtr - m_pWriteBuf ) != 0 ) && ( !bWhiteSpaceOnly ) )
{
if( FAILED( m_pISAXCallback->ElementContent( m_pWriteBuf, (UINT)( m_pWritePtr - m_pWriteBuf ), FALSE ) ) )
return E_ABORT;
bWhiteSpaceOnly = TRUE;
}
SkipNextAdvance();
m_pWritePtr = m_pWriteBuf;
if( FAILED( hr = AdvanceElement() ) )
return hr;
m_pWritePtr = m_pWriteBuf;
}
else
{
if( m_Ch == '&' )
{
SkipNextAdvance();
if( FAILED( hr = ConvertEscape() ) )
return hr;
}
if( bWhiteSpaceOnly && ( m_Ch != ' ' ) && ( m_Ch != '\n' ) && ( m_Ch != '\r' ) &&
( m_Ch != '\t' ) )
{
bWhiteSpaceOnly = FALSE;
}
*m_pWritePtr = m_Ch;
m_pWritePtr++;
if( m_pWritePtr - m_pWriteBuf >= XML_WRITE_BUFFER_SIZE )
{
if( !bWhiteSpaceOnly )
{
if( FAILED( m_pISAXCallback->ElementContent( m_pWriteBuf,
( UINT ) ( m_pWritePtr - m_pWriteBuf ),
TRUE ) ) )
{
return E_ABORT;
}
}
m_pWritePtr = m_pWriteBuf;
bWhiteSpaceOnly = TRUE;
}
}
}
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::ParseXMLFile
// Desc: Builds element data
//-------------------------------------------------------------------------------------
HRESULT XMLParser::ParseXMLFile( CONST CHAR *strFilename )
{
HRESULT hr;
if( m_pISAXCallback == NULL )
return E_NOINTERFACE;
m_pISAXCallback->m_LineNum = 1;
m_pISAXCallback->m_LinePos = 0;
m_pISAXCallback->m_strFilename = strFilename; // save this off only while we parse the file
m_bSkipNextAdvance = FALSE;
m_pReadPtr = m_pReadBuf;
m_pReadBuf[ 0 ] = '\0';
m_pReadBuf[ 1 ] = '\0';
m_pInXMLBuffer = NULL;
m_uInXMLBufferCharsLeft = 0;
WCHAR wchFilename[ 64 ];
swprintf_s(wchFilename,64,L"%s",strFilename);
m_hFile = CreateFile( wchFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
if( m_hFile == INVALID_HANDLE_VALUE )
{
Error( E_COULD_NOT_OPEN_FILE, "Error opening file" );
hr = E_COULD_NOT_OPEN_FILE;
}
else
{
LARGE_INTEGER iFileSize;
GetFileSizeEx( m_hFile, &iFileSize );
m_dwCharsTotal = (DWORD)iFileSize.QuadPart;
m_dwCharsConsumed = 0;
hr = MainParseLoop();
}
// Close the file
if( m_hFile != INVALID_HANDLE_VALUE )
CloseHandle( m_hFile );
m_hFile = INVALID_HANDLE_VALUE;
// we no longer own strFilename, so un-set it
m_pISAXCallback->m_strFilename = NULL;
return hr;
}
//-------------------------------------------------------------------------------------
// Name: XMLParser::ParseXMLFile
// Desc: Builds element data
//-------------------------------------------------------------------------------------
HRESULT XMLParser::ParseXMLBuffer( CONST CHAR *strBuffer, UINT uBufferSize )
{
HRESULT hr;
if( m_pISAXCallback == NULL )
return E_NOINTERFACE;
m_pISAXCallback->m_LineNum = 1;
m_pISAXCallback->m_LinePos = 0;
m_pISAXCallback->m_strFilename = ""; // save this off only while we parse the file
m_bSkipNextAdvance = FALSE;
m_pReadPtr = m_pReadBuf;
m_pReadBuf[ 0 ] = '\0';
m_pReadBuf[ 1 ] = '\0';
m_hFile = NULL;
m_pInXMLBuffer = strBuffer;
m_uInXMLBufferCharsLeft = uBufferSize;
m_dwCharsTotal = uBufferSize;
m_dwCharsConsumed = 0;
hr = MainParseLoop();
// we no longer own strFilename, so un-set it
m_pISAXCallback->m_strFilename = NULL;
return hr;
}
//-------------------------------------------------------------------------------------
// XMLParser::Error()
// Logs an error through the callback interface
//-------------------------------------------------------------------------------------
#ifdef _Printf_format_string_ // VC++ 2008 and later support this annotation
VOID XMLParser::Error( HRESULT hErr, _In_z_ _Printf_format_string_ CONST CHAR* strFormat, ... )
#else
VOID XMLParser::Error( HRESULT hErr, CONST CHAR* strFormat, ... )
#endif
{
CONST INT MAX_OUTPUT_STR = 160;
CHAR strBuffer[ MAX_OUTPUT_STR ];
va_list pArglist;
va_start( pArglist, strFormat );
vsprintf( strBuffer, strFormat, pArglist );
m_pISAXCallback->Error( hErr, strBuffer );
va_end( pArglist );
}
} // namespace ATG

View File

@@ -0,0 +1,156 @@
// 4J-PB -
// The ATG Framework is a common set of C++ class libraries that is used by the samples in the XDK, and was developed by the Advanced Technology Group (ATG).
// The ATG Framework offers a clean and consistent format for the samples. These classes define functions used by all the samples.
// The ATG Framework together with the samples demonstrates best practices and innovative techniques for Xbox 360. There are many useful sections of code in the samples.
// You are encouraged to incorporate this code into your titles.
//-------------------------------------------------------------------------------------
// AtgXmlParser.h
//
// XMLParser and SAX interface declaration
//
// Xbox Advanced Technology Group
// Copyright (C) Microsoft Corporation. All rights reserved.
//-------------------------------------------------------------------------------------
#pragma once
#ifndef ATGXMLPARSER_H
#define ATGXMLPARSER_H
namespace ATG
{
//-----------------------------------------------------------------------------
// error returns from XMLParse
//-----------------------------------------------------------------------------
#define _ATGFAC 0x61B
#define E_COULD_NOT_OPEN_FILE MAKE_HRESULT(1, _ATGFAC, 0x0001 )
#define E_INVALID_XML_SYNTAX MAKE_HRESULT(1, _ATGFAC, 0x0002 )
CONST UINT XML_MAX_ATTRIBUTES_PER_ELEMENT = 32;
CONST UINT XML_MAX_NAME_LENGTH = 128;
CONST UINT XML_READ_BUFFER_SIZE = 2048;
CONST UINT XML_WRITE_BUFFER_SIZE = 2048;
// No tag can be longer than XML_WRITE_BUFFER_SIZE - an error will be returned if
// it is
//-------------------------------------------------------------------------------------
struct XMLAttribute
{
WCHAR* strName;
UINT NameLen;
WCHAR* strValue;
UINT ValueLen;
};
//-------------------------------------------------------------------------------------
class ISAXCallback
{
friend class XMLParser;
public:
ISAXCallback() {};
virtual ~ISAXCallback() {};
virtual HRESULT StartDocument() = 0;
virtual HRESULT EndDocument() = 0;
virtual HRESULT ElementBegin( CONST WCHAR* strName, UINT NameLen,
CONST XMLAttribute *pAttributes, UINT NumAttributes ) = 0;
virtual HRESULT ElementContent( CONST WCHAR *strData, UINT DataLen, BOOL More ) = 0;
virtual HRESULT ElementEnd( CONST WCHAR *strName, UINT NameLen ) = 0;
virtual HRESULT CDATABegin( ) = 0;
virtual HRESULT CDATAData( CONST WCHAR *strCDATA, UINT CDATALen, BOOL bMore ) = 0;
virtual HRESULT CDATAEnd( ) = 0;
virtual VOID Error( HRESULT hError, CONST CHAR *strMessage ) = 0;
virtual VOID SetParseProgress( DWORD dwProgress ) { }
const CHAR* GetFilename() { return m_strFilename; }
UINT GetLineNumber() { return m_LineNum; }
UINT GetLinePosition() { return m_LinePos; }
private:
CONST CHAR *m_strFilename;
UINT m_LineNum;
UINT m_LinePos;
};
//-------------------------------------------------------------------------------------
class XMLParser
{
public:
XMLParser();
~XMLParser();
// Register an interface inheiriting from ISAXCallback
VOID RegisterSAXCallbackInterface( ISAXCallback *pISAXCallback );
// Get the registered interface
ISAXCallback* GetSAXCallbackInterface();
// ParseXMLFile returns one of the following:
// E_COULD_NOT_OPEN_FILE - couldn't open the file
// E_INVALID_XML_SYNTAX - bad XML syntax according to this parser
// E_NOINTERFACE - RegisterSAXCallbackInterface not called
// E_ABORT - callback returned a fail code
// S_OK - file parsed and completed
HRESULT ParseXMLFile( CONST CHAR *strFilename );
// Parses from a buffer- if you pass a WCHAR buffer (and cast it), it will
// correctly detect it and use unicode instead. Return codes are the
// same as for ParseXMLFile
HRESULT ParseXMLBuffer( CONST CHAR* strBuffer, UINT uBufferSize );
private:
HRESULT MainParseLoop();
HRESULT AdvanceCharacter( BOOL bOkToFail = FALSE );
VOID SkipNextAdvance();
HRESULT ConsumeSpace();
HRESULT ConvertEscape();
HRESULT AdvanceElement();
HRESULT AdvanceName();
HRESULT AdvanceAttrVal();
HRESULT AdvanceCDATA();
HRESULT AdvanceComment();
VOID FillBuffer();
#ifdef _Printf_format_string_ // VC++ 2008 and later support this annotation
VOID Error( HRESULT hRet, _In_z_ _Printf_format_string_ CONST CHAR* strFormat, ... );
#else
VOID Error( HRESULT hRet, CONST CHAR* strFormat, ... );
#endif
ISAXCallback* m_pISAXCallback;
HANDLE m_hFile;
CONST CHAR* m_pInXMLBuffer;
UINT m_uInXMLBufferCharsLeft;
DWORD m_dwCharsTotal;
DWORD m_dwCharsConsumed;
BYTE m_pReadBuf[ XML_READ_BUFFER_SIZE + 2 ]; // room for a trailing NULL
WCHAR m_pWriteBuf[ XML_WRITE_BUFFER_SIZE ];
BYTE* m_pReadPtr;
WCHAR* m_pWritePtr; // write pointer within m_pBuf
BOOL m_bUnicode; // TRUE = 16-bits, FALSE = 8-bits
BOOL m_bReverseBytes; // TRUE = reverse bytes, FALSE = don't reverse
BOOL m_bSkipNextAdvance;
WCHAR m_Ch; // Current character being parsed
};
} // namespace ATG
#endif

View File

@@ -0,0 +1,337 @@
#pragma once
#ifndef XMLMOJANGCALLBACK_H
#define XMLMOJANGCALLBACK_H
// xml reading
using namespace ATG;
/*
class xmlMojangCallback : public ATG::ISAXCallback
{
public:
virtual HRESULT StartDocument() { return S_OK; };
virtual HRESULT EndDocument() { return S_OK; };
virtual HRESULT ElementBegin( CONST WCHAR* strName, UINT NameLen, CONST XMLAttribute *pAttributes, UINT NumAttributes )
{
WCHAR wTemp[35] = L"";
WCHAR wAttName[32] = L"";
WCHAR wNameXUID[32] = L"";
WCHAR wNameSkin[32] = L"";
WCHAR wNameCloak[32] = L"";
PlayerUID xuid=0LL;
if (NameLen >31)
return S_FALSE;
else
wcsncpy( wAttName, strName, NameLen);
if ( _wcsicmp(wAttName,L"root") == 0)
{
return S_OK;
}
else if ( _wcsicmp(wAttName,L"data") == 0)
{
for(UINT i = 0; i < NumAttributes; i++)
{
wcsncpy_s( wAttName, pAttributes[i].strName, pAttributes[i].NameLen);
if (_wcsicmp(wAttName,L"name")==0)
{
if (pAttributes[i].ValueLen <= 32)
wcsncpy_s( wNameXUID, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
else if (_wcsicmp(wAttName,L"xuid")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
ZeroMemory(wTemp,sizeof(WCHAR)*35);
wcsncpy_s( wTemp, pAttributes[i].strValue, pAttributes[i].ValueLen);
xuid=_wcstoui64(wTemp,NULL,10);
}
}
else if (_wcsicmp(wAttName,L"cape")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
wcsncpy_s( wNameCloak, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
}
else if (_wcsicmp(wAttName,L"skin")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
wcsncpy_s( wNameSkin, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
}
}
// if the xuid hasn't been defined, then we can't use the data
if(xuid!=0LL)
{
return CConsoleMinecraftApp::RegisterMojangData(wNameXUID , xuid, wNameSkin, wNameCloak );
}
else return S_FALSE;
}
else
{
return S_FALSE;
}
};
virtual HRESULT ElementContent( CONST WCHAR *strData, UINT DataLen, BOOL More ) { return S_OK; };
virtual HRESULT ElementEnd( CONST WCHAR *strName, UINT NameLen ){ return S_OK; };
virtual HRESULT CDATABegin( ) { return S_OK; };
virtual HRESULT CDATAData( CONST WCHAR *strCDATA, UINT CDATALen, BOOL bMore ){ return S_OK; };
virtual HRESULT CDATAEnd( ){ return S_OK; };
virtual VOID Error( HRESULT hError, CONST CHAR *strMessage ) { app.DebugPrintf("Error when Parsing xuids.XML\n"); };
};
*/
class xmlConfigCallback : public ATG::ISAXCallback
{
public:
virtual HRESULT StartDocument() { return S_OK; };
virtual HRESULT EndDocument() { return S_OK; };
virtual HRESULT ElementBegin( CONST WCHAR* strName, UINT NameLen, CONST XMLAttribute *pAttributes, UINT NumAttributes )
{
WCHAR wTemp[35] = L"";
WCHAR wType[32] = L"";
WCHAR wAttName[32] = L"";
WCHAR wValue[32] = L"";
int iValue=-1;
if (NameLen >31)
return S_FALSE;
else
wcsncpy_s( wAttName, strName, NameLen);
if ( _wcsicmp(wAttName,L"root") == 0)
{
return S_OK;
}
else if ( _wcsicmp(wAttName,L"data") == 0)
{
for(UINT i = 0; i < NumAttributes; i++)
{
wcsncpy_s( wAttName, pAttributes[i].strName, pAttributes[i].NameLen);
if (_wcsicmp(wAttName,L"Type")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
wcsncpy_s( wType, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
}
else if(_wcsicmp(wAttName,L"Value")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
wcsncpy_s( wValue, pAttributes[i].strValue, pAttributes[i].ValueLen);
#ifdef _XBOX
iValue=_wtoi(wValue);
#else
iValue=wcstol(wValue, NULL, 10);
#endif
}
}
}
// if the xuid hasn't been defined, then we can't use the data
if(iValue!=-1)
{
#ifdef _DEBUG
wprintf(L"Type - %s, Value - %d, ",wType, iValue);
#endif
return CConsoleMinecraftApp::RegisterConfigValues(wType, iValue );
}
else
{
return S_FALSE;
}
}
else
{
return S_FALSE;
}
}
virtual HRESULT ElementContent( CONST WCHAR *strData, UINT DataLen, BOOL More ) { return S_OK; };
virtual HRESULT ElementEnd( CONST WCHAR *strName, UINT NameLen ){ return S_OK; };
virtual HRESULT CDATABegin( ) { return S_OK; };
virtual HRESULT CDATAData( CONST WCHAR *strCDATA, UINT CDATALen, BOOL bMore ){ return S_OK; };
virtual HRESULT CDATAEnd( ){ return S_OK; };
virtual VOID Error( HRESULT hError, CONST CHAR *strMessage ) { app.DebugPrintf("Error when Parsing xuids.XML\n"); };
};
class xmlDLCInfoCallback : public ATG::ISAXCallback
{
public:
virtual HRESULT StartDocument() { return S_OK; };
virtual HRESULT EndDocument() { return S_OK; };
virtual HRESULT ElementBegin( CONST WCHAR* strName, UINT NameLen, CONST XMLAttribute *pAttributes, UINT NumAttributes )
{
WCHAR wTemp[35] = L"";
WCHAR wAttName[32] = L"";
WCHAR wNameBanner[32] = L"";
WCHAR wDataFile[32] = L"";
WCHAR wType[32] = L"";
WCHAR wFirstSkin[32] = L"";
WCHAR wConfig[32] = L"";
WCHAR wUID[64] = L"";
WCHAR wName[64] = L"";
unsigned int uiSortIndex=0L;
int iGender=0;
int iConfig=0;
if (NameLen >31)
return S_FALSE;
else
wcsncpy_s( wAttName, strName, NameLen);
if ( _wcsicmp(wAttName,L"root") == 0)
{
return S_OK;
}
else if ( _wcsicmp(wAttName,L"data") == 0)
{
for(UINT i = 0; i < NumAttributes; i++)
{
wcsncpy_s( wAttName, pAttributes[i].strName, pAttributes[i].NameLen);
if (_wcsicmp(wAttName,L"SortIndex")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
ZeroMemory(wTemp,sizeof(WCHAR)*35);
wcsncpy_s( wTemp, pAttributes[i].strValue, pAttributes[i].ValueLen);
uiSortIndex=wcstoul(wTemp,NULL,10);
}
}
else if (_wcsicmp(wAttName,L"Banner")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
wcsncpy_s( wNameBanner, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
}
else if (_wcsicmp(wAttName,L"Full")==0)
{
if (pAttributes[i].ValueLen <= 64)
{
ZeroMemory(wUID,sizeof(WCHAR)*64);
wcsncpy_s( wUID, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
}
else if (_wcsicmp(wAttName,L"Name")==0)
{
if (pAttributes[i].ValueLen <= 64)
{
ZeroMemory(wName,sizeof(WCHAR)*64);
wcsncpy_s( wName, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
}
else if (_wcsicmp(wAttName,L"FirstSkin")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
wcsncpy_s( wFirstSkin, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
}
else if (_wcsicmp(wAttName,L"Type")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
wcsncpy_s( wType, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
}
else if(_wcsicmp(wAttName,L"Config")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
wcsncpy_s( wConfig, pAttributes[i].strValue, pAttributes[i].ValueLen);
#ifdef _XBOX
iConfig=_wtoi(wConfig);
#else
iConfig=wcstol(wConfig, NULL, 10);
#endif
}
}
else if (_wcsicmp(wAttName,L"DataFile")==0)
{
if (pAttributes[i].ValueLen <= 32)
{
wcsncpy_s( wDataFile, pAttributes[i].strValue, pAttributes[i].ValueLen);
}
}
}
// if the xuid hasn't been defined, then we can't use the data
if(wUID[0]!=0)
{
#ifdef _DEBUG
wprintf(L"Type - %ls, Name - %ls, ",wType, wNameBanner);
#endif
eDLCContentType eDLCType=e_DLC_NotDefined;
if(wType[0]!=0)
{
if(wcscmp(wType,L"Skin")==0)
{
eDLCType=e_DLC_SkinPack;
}
else if(wcscmp(wType,L"MashUpPack")==0)
{
eDLCType=e_DLC_MashupPacks;
}
else if(wcscmp(wType,L"TexturePack")==0)
{
eDLCType=e_DLC_TexturePacks;
}
}
return CConsoleMinecraftApp::RegisterDLCData(eDLCType, wNameBanner , wUID, wName, wFirstSkin, iConfig, uiSortIndex );
}
else
{
return S_FALSE;
}
}
else
{
return S_FALSE;
}
};
virtual HRESULT ElementContent( CONST WCHAR *strData, UINT DataLen, BOOL More ) { return S_OK; };
virtual HRESULT ElementEnd( CONST WCHAR *strName, UINT NameLen ){ return S_OK; };
virtual HRESULT CDATABegin( ) { return S_OK; };
virtual HRESULT CDATAData( CONST WCHAR *strCDATA, UINT CDATALen, BOOL bMore ){ return S_OK; };
virtual HRESULT CDATAEnd( ){ return S_OK; };
virtual VOID Error( HRESULT hError, CONST CHAR *strMessage ) { app.DebugPrintf("Error when Parsing DLC.XML\n"); };
};
#endif