// Parses the entire contents of an XNB file. void ContentReader::ReadXnb() { // Read the XNB header. uint32_t endPosition = ReadHeader(); ReadTypeManifest(); uint32_t sharedResourceCount = Read7BitEncodedInt(); // Read the primary asset data. Log.WriteLine("Asset:"); ReadObject(); // Read any shared resource instances. for (uint32_t i = 0 ; i < sharedResourceCount; i++) { Log.WriteLine("Shared resource %d:", i); ReadObject(); } // Make sure we read the amount of data that the file header said we should. if (FilePosition() != endPosition) { throw app_exception("End position does not match XNB header: unexpected amount of data was read."); } }
// Reads the manifest of what types are contained in this XNB file. void ContentReader::ReadTypeManifest() { Log.WriteLine("Type readers:"); Log.Indent(); // How many type readers does this .xnb use? uint32_t typeReaderCount = Read7BitEncodedInt(); typeReaders.clear(); for (uint32_t i = 0; i < typeReaderCount; i++) { // Read the type reader metadata. wstring readerName = ReadString(); int32_t readerVersion = ReadInt32(); Log.WriteLine("%S (version %d)", readerName.c_str(), readerVersion); // Look up and store this type reader implementation class. TypeReader* reader = typeReaderManager->GetByReaderName(readerName); typeReaders.push_back(reader); } // Initialize the readers in a separate pass after they are all registered, in case there are // circular dependencies between them (eg. an array of classes which themselves contain arrays). for (vector<TypeReader*>::iterator iter = typeReaders.begin(); iter != typeReaders.end(); iter++) { TypeReader* reader = *iter; reader->Initialize(typeReaderManager); } Log.Unindent(); }
// Reads a shared resource ID, which indexes into the table of shared object instances that come after the primary asset. void ContentReader::ReadSharedResource() { uint32_t resourceId = Read7BitEncodedInt(); if (resourceId) { Log.WriteLine("shared resource #%u", resourceId - 1); } else { Log.WriteLine("null"); } }
// Reads the typeId from the start of a polymorphic object, and looks up the appropriate TypeReader implementation. TypeReader* ContentReader::ReadTypeId() { uint32_t typeId = Read7BitEncodedInt(); if (typeId > 0) { // Look up the reader for this type of object. typeId--; if (typeId >= typeReaders.size()) { throw app_exception("Invalid XNB file: typeId is out of range."); } return typeReaders[typeId]; } else { // A zero typeId indicates a null object. return NULL; } }
// public string ReadString() [instance] :351 uString* BinaryReader::ReadString() { return ::g::Uno::Runtime::Implementation::TextEncodingImpl::DecodeUtf8(ReadBytes(Read7BitEncodedInt())); }