/// <summary> /// Read the version information that specifies the minimum versions of the /// DataSpaceManager software that can read, write, or update the data space /// information in this file. /// </summary> /// <param name="dataSpaceStorage"></param> /// <exception cref="FileFormatException"> /// If the format version information in the stream is corrupt. /// </exception> private void ReadDataSpaceVersionInformation(StorageInfo dataSpaceStorage) { if (_fileFormatVersion == null) { if (dataSpaceStorage.StreamExists( DataSpaceVersionName )) { StreamInfo versionStreamInfo = dataSpaceStorage.GetStreamInfo( DataSpaceVersionName ); using (Stream versionStream = versionStreamInfo.GetStream(FileMode.Open)) { _fileFormatVersion = FormatVersion.LoadFromStream(versionStream); // Transform Identifier: we preserve casing, but do case-insensitive comparison //Case-insensitive comparison. As per recommendations, we convert both strings //to Upper case and then compare with StringComparison.Ordinal if (!((IEqualityComparer) CU.StringCaseInsensitiveComparer).Equals(_fileFormatVersion.FeatureIdentifier, DataSpaceVersionIdentifier)) { throw new FileFormatException( SR.Get(SRID.InvalidTransformFeatureName, _fileFormatVersion.FeatureIdentifier, DataSpaceVersionIdentifier)); } // If we ever write this version number out again, we will want to record // the fact that it was done by the current version of the Dataspace software. _fileFormatVersion.WriterVersion = DataSpaceCurrentWriterVersion; } } } }
/// <summary> /// Write the data space mapping table to underlying storage. /// </summary> void WriteDataSpaceMap() { ThrowIfIncorrectUpdaterVersion(); StorageInfo dataSpaceStorage = new StorageInfo( _associatedStorage, DataSpaceStorageName ); StreamInfo dataSpaceMapStreamInfo = new StreamInfo ( dataSpaceStorage, DataSpaceMapTableName ); if( 0 < _dataSpaceMap.Count ) { // Write versioning information StreamInfo versionStreamInfo = null; if (dataSpaceStorage.StreamExists( DataSpaceVersionName ) ) versionStreamInfo = dataSpaceStorage.GetStreamInfo( DataSpaceVersionName ); else versionStreamInfo = dataSpaceStorage.CreateStream( DataSpaceVersionName ); Stream versionStream = versionStreamInfo.GetStream(); _fileFormatVersion.SaveToStream(versionStream); versionStream.Close(); // Create stream for write, overwrite any existing using(Stream dataSpaceMapStream = dataSpaceMapStreamInfo.GetStream(FileMode.Create)) { using(BinaryWriter dataSpaceMapWriter = new BinaryWriter( dataSpaceMapStream, System.Text.Encoding.Unicode )) { // Write header // header length = our known size + preserved array size dataSpaceMapWriter.Write( checked ((Int32) (KnownBytesInMapTableHeader + _mapTableHeaderPreservation.Length))); // number of entries dataSpaceMapWriter.Write( _dataSpaceMap.Count ); // anything else we've preserved dataSpaceMapWriter.Write( _mapTableHeaderPreservation ); // Loop to write entries foreach( CompoundFileReference o in _dataSpaceMap.Keys ) { // determine the entry length string label = (string)_dataSpaceMap[o]; int entryLength = CompoundFileReference.Save(o, null); checked { entryLength += CU.WriteByteLengthPrefixedDWordPaddedUnicodeString(null, label); } // length of entryLength itself checked { entryLength += 4; } // write out the entry length dataSpaceMapWriter.Write((Int32) entryLength); // Write out reference CompoundFileReference.Save( o, dataSpaceMapWriter); // Write out dataspace label CU.WriteByteLengthPrefixedDWordPaddedUnicodeString( dataSpaceMapWriter, label); } } } } else { // data space map is empty, remove existing stream if there. if ( dataSpaceStorage.StreamExists( DataSpaceMapTableName ) ) dataSpaceStorage.DeleteStream( DataSpaceMapTableName ); } }