/// <summary> /// Central place to set a transform definition, centralizing the /// call to the name manager. /// </summary> private void SetTransformDefinition( string transformLabel, TransformInstance definition ) { _transformDefinitions[ transformLabel ] = definition; }
/// <summary> /// Define a data transform object with the given object identification and /// labeled with the given name. /// </summary> /// <param name="transformClassName">Transform identification string</param> /// <param name="newTransformLabel">Label to use for new transform</param> internal void DefineTransform(string transformClassName, string newTransformLabel ) { CheckDisposedStatus(); // Check to see if transform name is obviously invalid CU.CheckStringAgainstNullAndEmpty( transformClassName, "Transform identifier name" ); // Check to see if transform name is valid CU.CheckStringAgainstNullAndEmpty( newTransformLabel, "Transform label" ); // Given transform name must not be a reserved string CU.CheckStringAgainstReservedName( newTransformLabel, "Transform label" ); // Can't re-use an existing transform name if( TransformLabelIsDefined( newTransformLabel ) ) throw new ArgumentException( SR.Get(SRID.TransformLabelInUse)); // Create class the transform object will use to communicate to us TransformEnvironment transformEnvironment = new TransformEnvironment( this, newTransformLabel ); // Create a TransformInstance object to represent this transform instance. TransformInstance newTransform = new TransformInstance( TransformIdentifierTypes_PredefinedTransformName, transformClassName, null, transformEnvironment ); SetTransformDefinition( newTransformLabel, newTransform ); // Create the transform object IDataTransform transformObject = InstantiateDataTransformObject( TransformIdentifierTypes_PredefinedTransformName, transformClassName, transformEnvironment ); newTransform.transformReference = transformObject; // If transform is not ready out-of-the-box, do an initialization run. // Note: Transform is not required to be "ready" after this. This is // done for those transforms that need initialization work up-front. if( ! transformObject.IsReady ) { CallTransformInitializers( new TransformInitializationEventArgs( transformObject, null, null, newTransformLabel) ); } _dirtyFlag = true; return; }
/// <summary> /// Read all transform definitions in one chunk /// </summary> // void ReadTransformDefinitions() { ThrowIfIncorrectReaderVersion(); StorageInfo dataSpaceStorage = new StorageInfo( _associatedStorage, DataSpaceStorageName ); StorageInfo transformDefinitionsStorage = new StorageInfo( dataSpaceStorage, TransformDefinitions ); if( transformDefinitionsStorage.Exists ) { // Read transform definitions from file foreach( StorageInfo transformStorage in transformDefinitionsStorage.GetSubStorages() ) { // Read from primary stream StreamInfo transformPrimary = new StreamInfo( transformStorage, TransformPrimaryInfo ); using(Stream transformDefinition = transformPrimary.GetStream(FileMode.Open)) { using(BinaryReader definitionReader = new BinaryReader( transformDefinition, System.Text.Encoding.Unicode )) { int headerLength = definitionReader.ReadInt32(); // We don't actually do anything with HeaderLen at the moment int transformType = definitionReader.ReadInt32(); if (headerLength < 0) throw new FileFormatException(SR.Get(SRID.CorruptedData)); // Create a TransformInstance class using name from file TransformInstance transformInstance = new TransformInstance(transformType, CU.ReadByteLengthPrefixedDWordPaddedUnicodeString( definitionReader ) ); int extraDataSize = checked ((int) (headerLength - transformDefinition.Position)); if (extraDataSize < 0) throw new FileFormatException(SR.Get(SRID.CorruptedData)); if (extraDataSize > 0) { if (extraDataSize > AllowedExtraDataMaximumSize) throw new FileFormatException(SR.Get(SRID.CorruptedData)); // Preserve the fields we don't know about. byte[] extraData = definitionReader.ReadBytes(extraDataSize); if (extraData.Length != extraDataSize) throw new FileFormatException(SR.Get(SRID.CorruptedData)); transformInstance.ExtraData = extraData; } if( transformDefinition.Length > transformDefinition.Position ) { // We have additional data in the primary instance data stream int instanceDataSize = checked ((int)(transformDefinition.Length - transformDefinition.Position)); byte[] instanceData = new byte[instanceDataSize]; PackagingUtilities.ReliableRead(transformDefinition, instanceData, 0, instanceDataSize); //build memory stream on the byte[] , and allow writes only if // FileAccess is Write or ReadWrite MemoryStream instanceDataStream; if (_associatedStorage.OpenAccess == FileAccess.Read) { // NOTE: Building MemoryStream directly on top of // instanceData byte array because we want it to be // NOT resizable and NOT writable. instanceDataStream = new MemoryStream(instanceData, false /* Not writable */); } else { // Copy additional data into a memory stream // NOTE: Not building MemoryStream directly on top of // instanceData byte array because we want it to be // resizable. instanceDataStream = new MemoryStream(); instanceDataStream.Write( instanceData, 0, instanceDataSize ); } instanceDataStream.Seek( 0, SeekOrigin.Begin ); // Dirty state should be tracked after the original data is read in from the disk into the memory stream transformInstance.transformPrimaryStream = new DirtyStateTrackingStream(instanceDataStream); } transformInstance.transformStorage = transformStorage; SetTransformDefinition( transformStorage.Name, transformInstance ); } } } } }