Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / MS / Internal / IO / Packaging / CompoundFile / ContainerUtilities.cs / 1305600 / ContainerUtilities.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // Common container-related operations that can be shared among internal // components. // // History: // ??/??/2002: ? : Initial implementation // 03/10/2003: RogerCh: Added the path array <-> path string conversion. // 05/29/2003: RogerCh: Ported to WCP tree. // 11/21/2003: Sarjanas: Added a method to apply predefined fragments to a // stream. // //----------------------------------------------------------------------------- using System; using System.Collections; // for IList using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Text; // for StringBuilder using System.Diagnostics; // for Debug.Assert #if PBTCOMPILER using MS.Utility; // For SR.cs using MS.Internal.PresentationBuildTasks; #else using System.Windows; using MS.Internal.WindowsBase; #endif namespace MS.Internal.IO.Packaging.CompoundFile { ////// ContainerUtilities /// static internal class ContainerUtilities { static private readonly Int32 _int16Size = SecurityHelper.SizeOf(typeof(Int16)); static private readonly Int32 _int32Size = SecurityHelper.SizeOf(typeof(Int32)); static private readonly byte[] _paddingBuf = new byte[4]; // for writing DWORD padding #if !PBTCOMPILER static private readonly Int32 _int64Size = SecurityHelper.SizeOf(typeof(Int64)); /// Used by ConvertBackSlashPathToStringArrayPath and /// ConvertStringArrayPathToBackSlashPath to separate path elements. static readonly internal char PathSeparator = '\\'; static private readonly char[] _PathSeparatorArray = new char[] { PathSeparator }; static readonly internal string PathSeparatorAsString = new string(ContainerUtilities.PathSeparator, 1); static private readonly CaseInsensitiveOrdinalStringComparer _stringCaseInsensitiveComparer = new CaseInsensitiveOrdinalStringComparer(); #endif ////// Byte size of Int16 Type /// static internal Int32 Int16Size { get { return _int16Size; } } #if !PBTCOMPILER ////// Byte size of Int32 Type /// static internal Int32 Int32Size { get { return _int32Size; } } ////// Byte size of Int64 Type /// static internal Int32 Int64Size { get { return _int64Size; } } static internal CaseInsensitiveOrdinalStringComparer StringCaseInsensitiveComparer { get { return _stringCaseInsensitiveComparer; } } #endif //The length should be verified by the caller to be non-negative internal static int CalculateDWordPadBytesLength(int length) { Debug.Assert(length >= 0, "The length cannot be negative. Caller must verify this"); int padLen = length & 3; if (padLen > 0) { padLen = 4 - padLen; } return (padLen); } ////// Write out a string via a BinaryWriter. Prefixed with int32 length in /// bytes and padded at the end to the next 32-bit (DWORD) boundary /// /// BinaryWriter configured for Unicode characters /// String to write out to BinaryWriter ///Number of bytes written including Prefixed int32 length, Unicode string, /// and padding ///If writer==null, it will return the number of bytes it will take /// to write it out; If outputString==null, it will write out 0 as length and /// an empty string; After this operation, the current position of BinaryWriter /// will be changed internal static int WriteByteLengthPrefixedDWordPaddedUnicodeString(BinaryWriter writer, String outputString) { checked { Int32 strByteLen = 0; if (outputString != null) { strByteLen = outputString.Length * 2; } if (writer != null) { // Write length, in bytes, of the unicode string writer.Write(strByteLen); if (strByteLen != 0) { // Write the Unicode characters writer.Write(outputString.ToCharArray()); } } if (strByteLen != 0) { int padLength = CalculateDWordPadBytesLength(strByteLen); if (padLength != 0) { strByteLen += padLength; if (writer != null) { writer.Write(_paddingBuf, 0, padLength); } } } strByteLen += _int32Size; // Size of the string length written at the beginning of this method return strByteLen; } } #if !PBTCOMPILER ////// Read a string whose length is specified by the first four bytes as a /// int32 and whose end is padded to the next 32-bit (DWORD) boundary. /// /// A BinaryReader initialized for Unicode characters ///Unicode string without padding; After this operation, the current /// position of BinaryWriter will be changed internal static String ReadByteLengthPrefixedDWordPaddedUnicodeString(BinaryReader reader) { int bytesRead; return ReadByteLengthPrefixedDWordPaddedUnicodeString(reader, out bytesRead); } ////// Read a string whose length is specified by the first four bytes as a /// int32 and whose end is padded to the next 32-bit (DWORD) boundary. /// /// A BinaryReader initialized for Unicode characters /// Total bytes read including prefixed length and padding ///Unicode string without padding ///If the string length is 0, it returns an empty string; After this operation, /// the current position of BinaryWriter will be changed internal static String ReadByteLengthPrefixedDWordPaddedUnicodeString(BinaryReader reader, out int bytesRead) { checked { bytesRead = 0; CheckAgainstNull(reader, "reader"); bytesRead = reader.ReadInt32(); // Length of the string in bytes String inString = null; if (bytesRead > 0) { try { if (reader.BaseStream.Length < bytesRead / 2) { #if !PBTCOMPILER throw new FileFormatException(SR.Get(SRID.InvalidStringFormat)); #else throw new SerializationException(SR.Get(SRID.InvalidStringFormat)); #endif } } catch (NotSupportedException) { // if the stream does not support the Length operator, it will throw a NotSupportedException. } inString = new String(reader.ReadChars(bytesRead / 2)); // Make sure the length of string read matches the length specified if (inString.Length != (bytesRead / 2)) { #if !PBTCOMPILER throw new FileFormatException(SR.Get(SRID.InvalidStringFormat)); #else throw new SerializationException(SR.Get(SRID.InvalidStringFormat)); #endif } } else if (bytesRead == 0) { inString = String.Empty; } else { #if !PBTCOMPILER throw new FileFormatException(SR.Get(SRID.InvalidStringFormat)); #else throw new SerializationException(SR.Get(SRID.InvalidStringFormat)); #endif } // skip the padding int padLength = CalculateDWordPadBytesLength(bytesRead); if (padLength > 0) { byte[] padding; padding = reader.ReadBytes(padLength); // Make sure the string is padded with the correct number of bytes if (padding.Length != padLength) { #if !PBTCOMPILER throw new FileFormatException(SR.Get(SRID.InvalidStringFormat)); #else throw new SerializationException(SR.Get(SRID.InvalidStringFormat)); #endif } bytesRead += padLength; } bytesRead += _int32Size; //// Size of the string length read at the beginning of this method return inString; } } #endif ////// Subset of CheckStringAgainstNullAndEmpty - and just checks against null reference. /// static internal void CheckAgainstNull(object paramRef, string testStringIdentifier) { if (paramRef == null) throw new ArgumentNullException(testStringIdentifier); } #if !PBTCOMPILER ////// Interprets a single string by treating it as a set of names /// delimited by a special character. The character is the backslash, /// serving the same role it has served since the original MS-DOS. /// The individual names are extracted from this string and /// returned as an array of string names. /// /// string "images\button.jpg" -> string [] { "images", "button.jpg" } /// /// /// /// String path to be converted /// ////// The elements of the path as a string array /// ////// Mirror counterpart of ConvertStringArrayPathToBackSlashPath /// // In theory, parsing strings should be done with regular expressions. // In practice, the RegEx class is too heavyweight for this application. // IMPORTANT: When updating this, make sure the counterpart is similarly // updated. static internal string[] ConvertBackSlashPathToStringArrayPath(string backSlashPath) { // A null string will get a null array if ((null == backSlashPath) || (0 == backSlashPath.Length)) return new string[0]; // Reject leading/trailing whitespace if (Char.IsWhiteSpace(backSlashPath[0]) || Char.IsWhiteSpace(backSlashPath[backSlashPath.Length - 1])) { throw new ArgumentException(SR.Get(SRID.MalformedCompoundFilePath)); } // Build the array string[] splitArray = backSlashPath.Split(_PathSeparatorArray); // Look for empty strings in the array foreach (string arrayElement in splitArray) { if (0 == arrayElement.Length) throw new ArgumentException( SR.Get(SRID.PathHasEmptyElement), "backSlashPath"); } // No empty strings, this array should be fine. return splitArray; } ////// Concatenates the names in an array of strings into a backslash- /// delimited string. /// /// string[] { "images", "button.jpg" } -> string "images\button.jpg" /// /// /// /// String array of names /// ////// Concatenated path with all the names in the given array /// ////// Mirror counterpart to ConvertBackSlashPathToStringArrayPath /// // IMPORTANT: When updating this, make sure the counterpart is similarly // updated. static internal string ConvertStringArrayPathToBackSlashPath(IList arrayPath) { // Null array gets a null string if ((null == arrayPath) || (1 > arrayPath.Count)) return String.Empty; // Length of one gets that element returned if (1 == arrayPath.Count) return (string)arrayPath[0]; // More than one - OK it's time to build something. CheckStringForEmbeddedPathSeparator((string)arrayPath[0], "Path array element"); StringBuilder pathBuilder = new StringBuilder((string)arrayPath[0]); for (int counter = 1; counter < arrayPath.Count; counter++) { CheckStringForEmbeddedPathSeparator((String)arrayPath[counter], "Path array element"); pathBuilder.Append(PathSeparator); pathBuilder.Append((String)arrayPath[counter]); } return pathBuilder.ToString(); } ////// Convert to path when storage array and stream name are separate /// /// storage collection (strings) /// stream name static internal string ConvertStringArrayPathToBackSlashPath(IList storages, string streamName) { string result = ConvertStringArrayPathToBackSlashPath(storages); if (result.Length > 0) return result + PathSeparator + streamName; else return streamName; } ////// Utility function to check a string (presumably an input to the /// caller function) against null, then against empty. Throwing an /// exception if either is true. /// /// /// The string to be tested /// /// /// A label for the test string to be used in the exception message. /// ////// No return value /// ////// /// CheckStringAgainstNullAndEmpty( fooName, "The name parameter "); /// /// may get: /// /// ArgumentNullException "The name parameter cannot be a null string" /// or /// ArgumentException "The name parameter cannot be an empty string" /// /// static internal void CheckStringAgainstNullAndEmpty(string testString, string testStringIdentifier) { if (testString == null) throw new ArgumentNullException(testStringIdentifier); if (testString.Length == 0) throw new ArgumentException(SR.Get(SRID.StringEmpty), testStringIdentifier); } ////// Checks if the given string fits within the range of reserved /// names and throws an ArgumentException if it does. /// The 0x01 through 0x1F characters, serving as the first character of the stream/storage name, /// are reserved for use by OLE. This is a compound file restriction. /// static internal void CheckStringAgainstReservedName(string nameString, string nameStringIdentifier) { if (IsReservedName(nameString)) throw new ArgumentException( SR.Get(SRID.StringCanNotBeReservedName, nameStringIdentifier)); } ////// A certain subset of compound file storage and stream names are /// reserved for use be OLE. These are names that start with a character in the /// range 0x01 to 0x1F. (1-31) /// This is a compound file restriction /// static internal bool IsReservedName(string nameString) { CheckStringAgainstNullAndEmpty(nameString, "nameString"); return (nameString[0] >= '\x0001' && nameString[0] <= '\x001F'); } ////// Checks for embedded delimiter in the string (as well as Null and Empty) /// /// string to test /// message for exception static internal void CheckStringForEmbeddedPathSeparator(string testString, string testStringIdentifier) { CheckStringAgainstNullAndEmpty(testString, testStringIdentifier); if (testString.IndexOf(PathSeparator) != -1) throw new ArgumentException( SR.Get(SRID.NameCanNotHaveDelimiter, testStringIdentifier, PathSeparator), "testString"); } #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RegexFCD.cs
- XmlSchemaGroupRef.cs
- DataTableReader.cs
- SystemColors.cs
- AddingNewEventArgs.cs
- TextStore.cs
- XmlSchemaChoice.cs
- _HelperAsyncResults.cs
- ButtonChrome.cs
- DocumentPageHost.cs
- TriggerActionCollection.cs
- SqlProvider.cs
- DataBindingHandlerAttribute.cs
- StrokeNodeOperations.cs
- LineProperties.cs
- QueryOutputWriter.cs
- DesignTimeParseData.cs
- WeakEventTable.cs
- ResXBuildProvider.cs
- codemethodreferenceexpression.cs
- OLEDB_Enum.cs
- ParameterCollectionEditor.cs
- ToolStripSystemRenderer.cs
- FileUpload.cs
- EmbossBitmapEffect.cs
- SQLRoleProvider.cs
- MessageSmuggler.cs
- UnsafeCollabNativeMethods.cs
- InvalidOperationException.cs
- TreeChangeInfo.cs
- RequestTimeoutManager.cs
- InternalConfigSettingsFactory.cs
- SchemaSetCompiler.cs
- DummyDataSource.cs
- StorageScalarPropertyMapping.cs
- StrokeCollection2.cs
- PartialCachingAttribute.cs
- DuplicateMessageDetector.cs
- SqlUdtInfo.cs
- DuplexClientBase.cs
- NumberFormatInfo.cs
- ObjectComplexPropertyMapping.cs
- LabelInfo.cs
- AsyncPostBackTrigger.cs
- EndpointAddressMessageFilterTable.cs
- NonVisualControlAttribute.cs
- TemplateBindingExtension.cs
- MultipleViewPatternIdentifiers.cs
- PathNode.cs
- XmlSchemaSimpleTypeList.cs
- NullReferenceException.cs
- TextBoxRenderer.cs
- Shape.cs
- NavigatorOutput.cs
- ImageInfo.cs
- Point3D.cs
- BehaviorEditorPart.cs
- CodeNamespaceImportCollection.cs
- SamlAttributeStatement.cs
- SystemEvents.cs
- DesignerActionPanel.cs
- IndexingContentUnit.cs
- ValueOfAction.cs
- FixedDocumentSequencePaginator.cs
- UpdateRecord.cs
- IntranetCredentialPolicy.cs
- Trace.cs
- DummyDataSource.cs
- WebBrowser.cs
- Pair.cs
- SequentialWorkflowRootDesigner.cs
- IndentedWriter.cs
- AsymmetricKeyExchangeDeformatter.cs
- OciEnlistContext.cs
- RequestUriProcessor.cs
- IntSecurity.cs
- SimpleBitVector32.cs
- ListSourceHelper.cs
- ConstraintStruct.cs
- AttributeProviderAttribute.cs
- XmlAnyAttributeAttribute.cs
- DataSetSchema.cs
- Stream.cs
- EventListener.cs
- ExpressionVisitorHelpers.cs
- TypeForwardedToAttribute.cs
- PasswordPropertyTextAttribute.cs
- DataKeyArray.cs
- TimerExtension.cs
- ValidationRuleCollection.cs
- Models.cs
- TextRangeAdaptor.cs
- Point3DAnimation.cs
- SqlComparer.cs
- RuleSettingsCollection.cs
- BaseValidator.cs
- Geometry.cs
- ServiceProviders.cs
- KnownTypeDataContractResolver.cs
- Screen.cs