|
|
#include "nt.h"
#include "ntdef.h"
#include "ntrtl.h"
#include "nturtl.h"
#include "fci.h"
#include "stdio.h"
#include "sxs-rtl.h"
#include "fasterxml.h"
#include "skiplist.h"
#include "namespacemanager.h"
#include "xmlstructure.h"
#ifdef INVALID_HANDLE_VALUE
#undef INVALID_HANDLE_VALUE
#endif
#include "windows.h"
#include "stdlib.h"
NTSTATUS FASTCALL MyAllocator(SIZE_T cb, PVOID* pvOutput, PVOID pvAllocContext) { ASSERT(pvAllocContext == NULL); *pvOutput = RtlAllocateHeap(RtlProcessHeap(), 0, cb); return *pvOutput ? STATUS_SUCCESS : STATUS_NO_MEMORY; }
NTSTATUS FASTCALL MyFreer(PVOID pv, PVOID pvAllocContext) { ASSERT(pvAllocContext == NULL); return RtlFreeHeap(RtlProcessHeap(), 0, pv) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; }
EXTERN_C RTL_ALLOCATOR g_DefaultAllocator = {MyAllocator, MyFreer, NULL};
void GetFormattedStateName( XML_TOKENIZATION_SPECIFIC_STATE State, CHAR *rgszBuffer, SIZE_T cchBuffer ) { CHAR *pszSpecific = NULL; SIZE_T cchSpecific = 0;
#define STRINGIFY(str, sz, cch) case str: sz = #str; cch = NUMBER_OF(#str) - 1; break
switch(State) { STRINGIFY(XTSS_ERRONEOUS, pszSpecific, cchSpecific);
STRINGIFY(XTSS_ELEMENT_OPEN, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_NAME, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_CLOSE, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_CLOSE_EMPTY, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_NAME, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_EQUALS, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_OPEN, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_CLOSE, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_VALUE, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_WHITESPACE, pszSpecific, cchSpecific);
STRINGIFY(XTSS_ELEMENT_XMLNS, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_XMLNS_DEFAULT, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_XMLNS_ALIAS, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_XMLNS_COLON, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_XMLNS_EQUALS, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_XMLNS_VALUE_OPEN, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_XMLNS_VALUE_CLOSE, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_XMLNS_VALUE, pszSpecific, cchSpecific);
STRINGIFY(XTSS_ELEMENT_NAME_NS_PREFIX, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_NAME_NS_COLON, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_NAME_NS_PREFIX, pszSpecific, cchSpecific); STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_NAME_NS_COLON, pszSpecific, cchSpecific);
STRINGIFY(XTSS_ENDELEMENT_OPEN, pszSpecific, cchSpecific); STRINGIFY(XTSS_ENDELEMENT_NAME, pszSpecific, cchSpecific); STRINGIFY(XTSS_ENDELEMENT_WHITESPACE, pszSpecific, cchSpecific); STRINGIFY(XTSS_ENDELEMENT_CLOSE, pszSpecific, cchSpecific);
STRINGIFY(XTSS_XMLDECL_OPEN, pszSpecific, cchSpecific); STRINGIFY(XTSS_XMLDECL_CLOSE, pszSpecific, cchSpecific); STRINGIFY(XTSS_XMLDECL_WHITESPACE, pszSpecific, cchSpecific); STRINGIFY(XTSS_XMLDECL_VALUE, pszSpecific, cchSpecific); STRINGIFY(XTSS_XMLDECL_VALUE_OPEN, pszSpecific, cchSpecific); STRINGIFY(XTSS_XMLDECL_VALUE_CLOSE, pszSpecific, cchSpecific); STRINGIFY(XTSS_XMLDECL_EQUALS, pszSpecific, cchSpecific); STRINGIFY(XTSS_XMLDECL_ENCODING, pszSpecific, cchSpecific); STRINGIFY(XTSS_XMLDECL_STANDALONE, pszSpecific, cchSpecific); STRINGIFY(XTSS_XMLDECL_VERSION, pszSpecific, cchSpecific);
STRINGIFY(XTSS_PI_OPEN, pszSpecific, cchSpecific); STRINGIFY(XTSS_PI_CLOSE, pszSpecific, cchSpecific); STRINGIFY(XTSS_PI_TARGET, pszSpecific, cchSpecific); STRINGIFY(XTSS_PI_VALUE, pszSpecific, cchSpecific); STRINGIFY(XTSS_PI_WHITESPACE, pszSpecific, cchSpecific);
STRINGIFY(XTSS_CDATA_OPEN, pszSpecific, cchSpecific); STRINGIFY(XTSS_CDATA_CDATA, pszSpecific, cchSpecific); STRINGIFY(XTSS_CDATA_CLOSE, pszSpecific, cchSpecific);
STRINGIFY(XTSS_COMMENT_OPEN, pszSpecific, cchSpecific); STRINGIFY(XTSS_COMMENT_COMMENTARY, pszSpecific, cchSpecific); STRINGIFY(XTSS_COMMENT_CLOSE, pszSpecific, cchSpecific);
STRINGIFY(XTSS_STREAM_START, pszSpecific, cchSpecific); STRINGIFY(XTSS_STREAM_END, pszSpecific, cchSpecific); STRINGIFY(XTSS_STREAM_HYPERSPACE, pszSpecific, cchSpecific);
default: pszSpecific = "bad specific state"; cchSpecific = strlen(pszSpecific); break; }
_snprintf(rgszBuffer, cchBuffer, "%s", pszSpecific); }
void DisplayToken(PXML_TOKEN pToken, FILE* pFile) { static char Formatter[4096]; SIZE_T i;
GetFormattedStateName(pToken->State, Formatter, NUMBER_OF(Formatter)); fprintf(pFile, "%s, %d {%.*s}\n", Formatter, pToken->Run.cbData, pToken->Run.cbData, pToken->Run.pvData); }
NTSTATUS DisplayLogicalThing( PXMLDOC_THING pThing, PRTL_GROWING_LIST pAttributeList ) { printf("Extent {0x%p, %d} (depth %d):\n", pThing->TotalExtent.pvData, pThing->TotalExtent.cbData, pThing->ulDocumentDepth);
switch (pThing->ulThingType) { case XMLDOC_THING_HYPERSPACE: { printf("\tHyperspace: {%.*s}\n", pThing->Hyperspace.cbData, pThing->Hyperspace.pvData); } break;
case XMLDOC_THING_ELEMENT: { PXMLDOC_ATTRIBUTE pAttribute = NULL; ULONG ul = 0; NTSTATUS status;
printf("\tElement {%.*s:%.*s} %d attributes %s\n", pThing->Element.NsPrefix.cbData, pThing->Element.NsPrefix.pvData, pThing->Element.Name.cbData, pThing->Element.Name.pvData, pThing->Element.ulAttributeCount, (pThing->Element.fElementEmpty ? "(empty)" : ""));
for (ul = 0; ul < pThing->Element.ulAttributeCount; ul++) {
status = RtlIndexIntoGrowingList( pAttributeList, ul, (PVOID*)&pAttribute, FALSE);
if (NT_SUCCESS(status)) { printf("\t\tAttribute {%.*s:%.*s}={%.*s}\n", pAttribute->NsPrefix.cbData, pAttribute->NsPrefix.pvData, pAttribute->Name.cbData, pAttribute->Name.pvData, pAttribute->Value.cbData, pAttribute->Value.pvData); } else { printf("\t\t(Can't get attribute, error 0x%08lx)\n", status); }
} } break;
case XMLDOC_THING_XMLDECL: { PXMLDOC_XMLDECL pDecl = &pThing->XmlDecl; printf("\tXML Declaration: encoding {%.*s} version {%.*s} standalone {%.*s}\n", pDecl->Encoding.cbData, pDecl->Encoding.pvData, pDecl->Version.cbData, pDecl->Version.pvData, pDecl->Standalone.cbData, pDecl->Standalone.pvData); } break;
case XMLDOC_THING_END_ELEMENT: { PXMLDOC_ENDELEMENT pElement = &pThing->EndElement;
printf("\tClosing element {%.*s:%.*s} for tag {%.*s:%.*s}\n", pElement->NsPrefix.cbData, pElement->NsPrefix.pvData, pElement->Name.cbData, pElement->Name.pvData, pElement->OpeningElement.NsPrefix.cbData, pElement->OpeningElement.NsPrefix.pvData, pElement->OpeningElement.Name.cbData, pElement->OpeningElement.Name.pvData); } break;
case XMLDOC_THING_END_OF_STREAM: printf("End of stream\n"); break;
case XMLDOC_THING_ERROR: { PXMLDOC_ERROR pError = &pThing->Error;
printf("\tError in XML (or parser) found at {%.*s}, code %08lx\n", pError->BadExtent.cbData, pError->BadExtent.pvData, pError->Code); } break; }
return STATUS_SUCCESS; }
BOOL s_fDisplay = FALSE;
NTSTATUS RunThroughFile( PVOID pvData, SIZE_T cbData ) { XML_LOGICAL_STATE MasterParseState; XMLDOC_THING DocumentPiece; RTL_GROWING_LIST AttributeList; NTSTATUS status; LARGE_INTEGER liStart, liEnd;
QueryPerformanceCounter(&liStart);
status = RtlInitializeGrowingList( &AttributeList, sizeof(XMLDOC_ATTRIBUTE), 20, NULL, 0, &g_DefaultAllocator);
if (!NT_SUCCESS(status)) { return status; }
status = RtlXmlInitializeNextLogicalThing( &MasterParseState, pvData, cbData, &g_DefaultAllocator);
while (NT_SUCCESS(status)) {
status = RtlXmlNextLogicalThing( &MasterParseState, NULL, &DocumentPiece, &AttributeList);
if (!NT_SUCCESS(status)) { break; }
if (s_fDisplay) DisplayLogicalThing(&DocumentPiece, &AttributeList);
if ((DocumentPiece.ulThingType == XMLDOC_THING_ERROR) || (DocumentPiece.ulThingType == XMLDOC_THING_END_OF_STREAM)) { break; }
}
QueryPerformanceCounter(&liEnd);
liEnd.QuadPart -= liStart.QuadPart; QueryPerformanceFrequency(&liStart);
printf("%I64d ticks, %f seconds\n", liEnd.QuadPart, (double)liEnd.QuadPart / (double)liStart.QuadPart);
if (DocumentPiece.ulThingType == XMLDOC_THING_END_OF_STREAM) {
if (DocumentPiece.ulDocumentDepth == 0) { printf("Completed input stream\n"); } else { printf("EOF before end of stream, %d elements on stack.\n", DocumentPiece.ulDocumentDepth); } } else { printf("Error found in stream processing at %.*s, byte offset %d.\n", DocumentPiece.TotalExtent.cbData, DocumentPiece.TotalExtent.pvData, (PBYTE)DocumentPiece.TotalExtent.pvData - (PBYTE)pvData ); }
return status; }
NTSTATUS TimeFileRun( PVOID pvFileData, SIZE_T dwFileSize, PLARGE_INTEGER pliTickCount, double* pdblSecondCount) { XML_LOGICAL_STATE State; XML_TOKEN Token; LARGE_INTEGER liStartTime, liEndTime; SIZE_T ulEncodingBytes; NTSTATUS success;
//
// Start up the parser
//
success = RtlXmlInitializeTokenization(&State.ParseState, pvFileData, dwFileSize, NULL, NULL, NULL); if (!NT_SUCCESS(success)) { printf("Initialization failure\n"); }
State.ulElementStackDepth = 0; success = RtlInitializeGrowingList( &State.ElementStack, sizeof(XMLDOC_THING), 40, State.InlineElements, sizeof(State.InlineElements), &g_DefaultAllocator);
if (!NT_SUCCESS(success)) { printf("Unable to create element stack"); return success; }
//
// Let's determine the encoding
//
success = RtlXmlDetermineStreamEncoding(&State.ParseState, &ulEncodingBytes, &State.EncodingMarker); if (!NT_SUCCESS(success)) { printf("Unable to determine the encoding type\n"); }
//
// Advance cursor past encoding bytes if necessary
//
State.ParseState.RawTokenState.pvCursor = ((PBYTE)State.ParseState.RawTokenState.pvCursor) + ulEncodingBytes;
QueryPerformanceCounter(&liStartTime); do {
if (NT_SUCCESS(success = RtlXmlNextToken(&State.ParseState, &Token, TRUE))) {
//
// Was there an error in this token?
//
if (s_fDisplay) DisplayToken(&Token, stdout);
if (Token.fError) { printf("(Which was considered an error)\n"); break; }
} } while (NT_SUCCESS(success) && !Token.fError && (Token.State != XTSS_STREAM_END));
QueryPerformanceCounter(&liEndTime); pliTickCount->QuadPart = liEndTime.QuadPart - liStartTime.QuadPart; QueryPerformanceFrequency(&liStartTime);
*pdblSecondCount = (double)pliTickCount->QuadPart / liStartTime.QuadPart;
return success; }
DWORD WARMUP_COUNT = 3; DWORD REAL_COUNT = 5;
int __cdecl wmain(int argc, WCHAR* argv[]) { NTSTATUS success = STATUS_SUCCESS; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hFileMapping = INVALID_HANDLE_VALUE; PVOID pvFileData = NULL; DWORD dwFileSize = 0; BOOL fFirstElementFound = FALSE; LARGE_INTEGER liTickCount, liTotalTicks; double dblSeconds, dblTotalSeconds; PCWSTR pcwszFileName = NULL; DWORD dw = 0;
BOOL fJustRun = FALSE; int i;
for (i = 1; i < argc; i++) { if (lstrcmpiW(L"-file", argv[i]) == 0) { pcwszFileName = argv[++i]; } else if (lstrcmpiW(L"-warmup", argv[i]) == 0) { WARMUP_COUNT = _wtoi(argv[++i]); } else if (lstrcmpiW(L"-real", argv[i]) == 0) { REAL_COUNT = _wtoi(argv[++i]); } else if (lstrcmpiW(L"-display", argv[i]) == 0) { s_fDisplay = TRUE; } }
if (pcwszFileName == NULL) { wprintf(L"Must specify at least '-file somefile'\r\n"); return -1; }
hFile = CreateFileW( pcwszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { printf("Can't open file %ls\n", pcwszFileName); return -1; }
dwFileSize = GetFileSize(hFile, NULL);
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL); if ((hFileMapping == NULL) || (hFileMapping == INVALID_HANDLE_VALUE)) { CloseHandle(hFile); wprintf(L"Can't create file mapping of %ls, lasterror %d\n", pcwszFileName, GetLastError()); return -1; }
pvFileData = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, dwFileSize); if (pvFileData == NULL) { CloseHandle(hFile); CloseHandle(hFileMapping); wprintf(L"Can't create mapped view of file %ls\n", pcwszFileName); return -1; }
for (dw = 0; dw < WARMUP_COUNT; dw++) { wprintf(L"Warmup cycle %d\n", dw); success = TimeFileRun(pvFileData, dwFileSize, &liTickCount, &dblSeconds); wprintf(L"%I64d ticks, %f seconds\n", liTickCount.QuadPart, dblSeconds); }
wprintf(L"This one counts:\n");
liTotalTicks.QuadPart = 0; dblTotalSeconds = 0.0;
for (dw = 0; dw < REAL_COUNT; dw++) { success = TimeFileRun(pvFileData, dwFileSize, &liTickCount, &dblSeconds); dblTotalSeconds += dblSeconds; liTotalTicks.QuadPart += liTickCount.QuadPart; wprintf(L"."); }
wprintf(L"\n");
if (REAL_COUNT == 0) { wprintf(L"No real runs, can't calculate time.\n"); } else { wprintf(L"%d runs: %I64d total ticks, %I64d average, %f total seconds, %f average\n", REAL_COUNT, liTotalTicks.QuadPart, liTotalTicks.QuadPart / REAL_COUNT, dblTotalSeconds, dblTotalSeconds / REAL_COUNT); } success = RunThroughFile(pvFileData, dwFileSize);
CloseHandle(hFile); CloseHandle(hFileMapping); UnmapViewOfFile(pvFileData);
return success; success = RtlInstallAssembly(0, argv[1]); }
|