/// <summary> /// Deserialize from the given stream /// </summary> /// <param name="reader">the BinaryReader to deserialize from with the seek pointer at the beginning of the container reference</param> /// <param name="bytesRead">bytes consumed from the stream</param> /// <remarks> /// Side effect of change the stream pointer /// </remarks> /// <exception cref="FileFormatException">Throws a FileFormatException if any formatting errors are encountered</exception> internal static CompoundFileReference Load(BinaryReader reader, out int bytesRead) { ContainerUtilities.CheckAgainstNull(reader, "reader"); bytesRead = 0; // running count of how much we've read - sanity check // create the TypeMap // reconstitute ourselves from the given BinaryReader // in this version, the next Int32 is the number of entries Int32 entryCount = reader.ReadInt32(); bytesRead += ContainerUtilities.Int32Size; // EntryCount of zero indicates the root storage. if (entryCount < 0) { throw new FileFormatException( SR.Get(SRID.CFRCorrupt)); } // need a temp collection because we don't know what we're dealing with until a non-storage component // type is encountered StringCollection storageList = null; String streamName = null; // loop through the entries - accumulating strings until we know what kind of object // we ultimately need int byteLength; // reusable while (entryCount > 0) { // first Int32 tells us what kind of component this entry represents RefComponentType refType = (RefComponentType)reader.ReadInt32(); bytesRead += ContainerUtilities.Int32Size; switch (refType) { case RefComponentType.Storage: { if (streamName != null) { throw new FileFormatException( SR.Get(SRID.CFRCorruptStgFollowStm)); } if (storageList == null) { storageList = new StringCollection(); } String str = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength); bytesRead += byteLength; storageList.Add(str); } break; case RefComponentType.Stream: { if (streamName != null) { throw new FileFormatException( SR.Get(SRID.CFRCorruptMultiStream)); } streamName = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out byteLength); bytesRead += byteLength; } break; // we don't handle these types yet default: throw new FileFormatException( SR.Get(SRID.UnknownReferenceComponentType)); } --entryCount; } CompoundFileReference newRef = null; // stream or storage? if (streamName == null) { newRef = new CompoundFileStorageReference( ContainerUtilities.ConvertStringArrayPathToBackSlashPath(storageList)); } else { newRef = new CompoundFileStreamReference( ContainerUtilities.ConvertStringArrayPathToBackSlashPath(storageList, streamName)); } return(newRef); }
//------------------------------------------------------ // // Public Events // //------------------------------------------------------ // None //------------------------------------------------------ // // Internal Constructors // //------------------------------------------------------ // None //------------------------------------------------------ // // Internal Properties // //------------------------------------------------------ // None //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #if !PBTCOMPILER /// <summary> /// Constructor for FormatVersion with information read from the given BinaryReader /// </summary> /// <param name="reader">BinaryReader where version information is read from</param> /// <param name="bytesRead">number of bytes read including padding</param> /// <returns>FormatVersion object</returns> /// <remarks> /// This operation will change the stream pointer. This function is preferred over the /// LoadFromStream as it doesn't leave around Undisposed BinaryReader, which /// LoadFromStream will /// </remarks> private static FormatVersion LoadFromBinaryReader(BinaryReader reader, out Int32 bytesRead) { checked { if (reader == null) { throw new ArgumentNullException("reader"); } FormatVersion ver = new FormatVersion(); bytesRead = 0; // Initialize the number of bytes read // ************** // feature ID // ************** Int32 strBytes; ver._featureIdentifier = ContainerUtilities.ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out strBytes); bytesRead += strBytes; Int16 major; Int16 minor; // **************** // Reader Version // **************** major = reader.ReadInt16(); // Major number bytesRead += ContainerUtilities.Int16Size; minor = reader.ReadInt16(); // Minor number bytesRead += ContainerUtilities.Int16Size; ver.ReaderVersion = new VersionPair(major, minor); // ***************** // Updater Version // ***************** major = reader.ReadInt16(); // Major number bytesRead += ContainerUtilities.Int16Size; minor = reader.ReadInt16(); // Minor number bytesRead += ContainerUtilities.Int16Size; ver.UpdaterVersion = new VersionPair(major, minor); // **************** // Writer Version // **************** major = reader.ReadInt16(); // Major number bytesRead += ContainerUtilities.Int16Size; minor = reader.ReadInt16(); // Minor number bytesRead += ContainerUtilities.Int16Size; ver.WriterVersion = new VersionPair(major, minor); return(ver); } }