Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Base / MS / Internal / IO / Packaging / CompoundFile / ContainerUtilities.cs / 1 / 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: [....]: Added the path array <-> path string conversion.
// 05/29/2003: [....]: Ported to WCP tree.
// 11/21/2003: [....]: 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
- NetSectionGroup.cs
- ImageButton.cs
- ObjectAnimationUsingKeyFrames.cs
- ConfigViewGenerator.cs
- SqlCachedBuffer.cs
- SettingsBase.cs
- PasswordBox.cs
- TagMapInfo.cs
- BaseServiceProvider.cs
- ClientConfigurationSystem.cs
- OleDbCommandBuilder.cs
- RepeatInfo.cs
- TargetConverter.cs
- DateTimeConverter.cs
- Stack.cs
- EncoderReplacementFallback.cs
- TreeIterator.cs
- BooleanFunctions.cs
- DbProviderConfigurationHandler.cs
- InputLanguageProfileNotifySink.cs
- WinEventHandler.cs
- DataBoundControlParameterTarget.cs
- UnsafeNativeMethods.cs
- MethodAccessException.cs
- StringFreezingAttribute.cs
- ImageSource.cs
- StackOverflowException.cs
- UrlMappingCollection.cs
- ItemChangedEventArgs.cs
- ResumeStoryboard.cs
- SmtpException.cs
- ListViewEditEventArgs.cs
- KerberosReceiverSecurityToken.cs
- GetPageCompletedEventArgs.cs
- CodeGotoStatement.cs
- TagPrefixCollection.cs
- FontCacheUtil.cs
- Imaging.cs
- SiteMapSection.cs
- RSAPKCS1SignatureDeformatter.cs
- SerTrace.cs
- Source.cs
- CubicEase.cs
- DrawingVisual.cs
- OutputCacheProfile.cs
- CompletionCallbackWrapper.cs
- ErrorsHelper.cs
- SymmetricAlgorithm.cs
- PersistChildrenAttribute.cs
- FormatStringEditor.cs
- CompModSwitches.cs
- CompilerScopeManager.cs
- CqlBlock.cs
- ApplicationId.cs
- SimpleFileLog.cs
- HtmlInputText.cs
- JournalEntryListConverter.cs
- log.cs
- FormsAuthenticationEventArgs.cs
- ToolStripDropDownClosingEventArgs.cs
- Vector3DAnimationBase.cs
- CacheMemory.cs
- ContentDisposition.cs
- XPathNavigatorKeyComparer.cs
- HttpCacheVary.cs
- TextTreeRootTextBlock.cs
- AccessDataSource.cs
- EdmItemError.cs
- VoiceInfo.cs
- WpfGeneratedKnownProperties.cs
- EndpointConfigContainer.cs
- StdValidatorsAndConverters.cs
- CodeNamespaceImportCollection.cs
- ServiceEndpointAssociationProvider.cs
- FactoryRecord.cs
- DesignParameter.cs
- BindingCompleteEventArgs.cs
- ApplicationSettingsBase.cs
- NaturalLanguageHyphenator.cs
- DocumentOrderComparer.cs
- FullTextLine.cs
- PersonalizationEntry.cs
- MouseActionConverter.cs
- AmbiguousMatchException.cs
- DataGridViewTopRowAccessibleObject.cs
- SwitchElementsCollection.cs
- DataPager.cs
- CodeCompileUnit.cs
- ScriptResourceInfo.cs
- ReachPageContentSerializer.cs
- DebugInfoGenerator.cs
- DesignerRegionCollection.cs
- TextDecorationLocationValidation.cs
- MemoryMappedView.cs
- FixedSOMImage.cs
- DataTable.cs
- JpegBitmapEncoder.cs
- DomNameTable.cs
- WindowsFormsSynchronizationContext.cs
- KnownColorTable.cs