// Token: 0x06002007 RID: 8199 RVA: 0x00095B00 File Offset: 0x00093D00 internal override void Copy(BamlRecord record) { base.Copy(record); BamlDeferableContentStartRecord bamlDeferableContentStartRecord = (BamlDeferableContentStartRecord)record; bamlDeferableContentStartRecord._contentSize = this._contentSize; bamlDeferableContentStartRecord._contentSizePosition = this._contentSizePosition; bamlDeferableContentStartRecord._valuesBuffer = this._valuesBuffer; }
internal void BaseReadDeferableContentStart( BamlDeferableContentStartRecord bamlRecord, out ArrayList defKeyList, out List<object[]> staticResourceValuesList) { // Check for DefAttributeKeys and create a key table, if some are // present. Peek ahead in the stream looking for IBamlDictionaryKey types // and just process those without touching anything else. // NOTE: The typical shell theme file is roughly 450 bytes per value, so presize // the arraylist to be optimal for these scenarios. defKeyList = new ArrayList(Math.Max (5, (int)(bamlRecord.ContentSize/400))); staticResourceValuesList = new List<object[]>(defKeyList.Capacity); ArrayList staticResources = new ArrayList(); BamlRecordType nextType = GetNextRecordType(); while (nextType == BamlRecordType.DefAttributeKeyString || nextType == BamlRecordType.DefAttributeKeyType || nextType == BamlRecordType.KeyElementStart) { BamlRecord keyRecord = GetNextRecord(); IBamlDictionaryKey dictionaryKeyRecord = keyRecord as IBamlDictionaryKey; if (nextType == BamlRecordType.KeyElementStart) { // Read forward until we get a KeyElementEnd, at which point // we should have the key object on the reader stack. Use // that to set the key object in the Key Element Start record. ReadKeyElementStartRecord((BamlKeyElementStartRecord)keyRecord); defKeyList.Add(keyRecord); BamlRecord nestedBamlRecord; bool moreData = true; while (moreData && null != (nestedBamlRecord = GetNextRecord())) { if (nestedBamlRecord is BamlKeyElementEndRecord) { object keyObject = GetCurrentObjectData(); MarkupExtension me = keyObject as MarkupExtension; if (me != null) { keyObject = ProvideValueFromMarkupExtension(me, GetParentObjectData(), null); } dictionaryKeyRecord.KeyObject = keyObject; PopContext(); moreData = false; } else { moreData = ReadRecord(nestedBamlRecord); } } } else { BamlDefAttributeKeyStringRecord stringKeyRecord = keyRecord as BamlDefAttributeKeyStringRecord; if (stringKeyRecord != null) { // Get the value string from the string table, and cache it in the // record. stringKeyRecord.Value = MapTable.GetStringFromStringId( stringKeyRecord.ValueId); dictionaryKeyRecord.KeyObject = XamlTypeMapper.GetDictionaryKey(stringKeyRecord.Value, ParserContext); defKeyList.Add(stringKeyRecord); } else { BamlDefAttributeKeyTypeRecord typeKeyRecord = keyRecord as BamlDefAttributeKeyTypeRecord; if (typeKeyRecord != null) { dictionaryKeyRecord.KeyObject = MapTable.GetTypeFromId( typeKeyRecord.TypeId); defKeyList.Add(typeKeyRecord); } else { // Enum.ToString(culture) is [Obsolete] #pragma warning disable 0618 ThrowException(SRID.ParserUnexpInBAML, keyRecord.RecordType.ToString(CultureInfo.CurrentCulture)); #pragma warning restore 0618 } } } // Check for StaticResources belonging to this key and create a table, if present. // Peek ahead in the stream looking for StaticResource[Start/End] types // and just process those without touching anything else. nextType = GetNextRecordType(); // If this dictionary is a top level deferred section then // its front loaded section contains StaticResourceRecords if (!ParserContext.InDeferredSection) { // Example: // // <ResourceDictionary> // < ... {StaticResource res1} ... /> // </ResourceDictionary> while (nextType == BamlRecordType.StaticResourceStart || nextType == BamlRecordType.OptimizedStaticResource) { BamlRecord srRecord = GetNextRecord(); if (nextType == BamlRecordType.StaticResourceStart) { // Read forward until we get a StaticResourceEnd, at which point // we should have the StaticResourceExtension object on the reader stack. BamlStaticResourceStartRecord startRecord = (BamlStaticResourceStartRecord)srRecord; BaseReadElementStartRecord(startRecord); BamlRecord nestedBamlRecord; bool moreData = true; while (moreData && null != (nestedBamlRecord = GetNextRecord())) { if (nestedBamlRecord.RecordType == BamlRecordType.StaticResourceEnd) { StaticResourceExtension staticResource = (StaticResourceExtension)GetCurrentObjectData(); staticResources.Add(staticResource); PopContext(); moreData = false; } else { moreData = ReadRecord(nestedBamlRecord); } } } else { StaticResourceExtension staticResource = (StaticResourceExtension)GetExtensionValue((IOptimizedMarkupExtension)srRecord, null); staticResources.Add(staticResource); } nextType = GetNextRecordType(); } } else { // Example: // // <Button> // <Button.Template> // <ControlTemplate> // <StackPanel ... {StaticResource res1} ... > // <StackPanel.Resources> // < ... {StaticResource res2} ... /> // </StackPanel.Resources> // </StackPanel> // </ControlTemplate> // </Button.Template> // </Button> // If this dictionary is nested within another deferred section such as a template // content then its front loaded section will have StaticResourceId records that // index into the pre-fetched values on the template. object[] staticResourceValues = ParserContext.StaticResourcesStack[ParserContext.StaticResourcesStack.Count-1]; while (nextType == BamlRecordType.StaticResourceId) { BamlStaticResourceIdRecord bamlStaticResourceIdRecord = (BamlStaticResourceIdRecord)GetNextRecord(); // Find the StaticResourceValue for the given Id Debug.Assert(staticResourceValues != null, "Must have a list of StaticResourceValues for lookup"); DeferredResourceReference prefetchedValue = (DeferredResourceReference)staticResourceValues[bamlStaticResourceIdRecord.StaticResourceId]; staticResources.Add(new StaticResourceHolder(prefetchedValue.Key, prefetchedValue)); // Peek at next record type nextType = GetNextRecordType(); } } // Set the StaticResources collection on the DictionaryKeyRecord staticResourceValuesList.Add(staticResources.ToArray()); staticResources.Clear(); nextType = GetNextRecordType(); } }
// The start of a block of deferable content has been reached. There should // be a ResourceDictionary above us in the reader stack, so call it // with the stream and position information for the deferable block. Then // skip over the deferable block after parsing the key table and continue. internal virtual void ReadDeferableContentStart( BamlDeferableContentStartRecord bamlRecord) { ResourceDictionary dictionary = GetDictionaryFromContext(CurrentContext, true /*toInsert*/) as ResourceDictionary; if (dictionary != null) { // At present we DO NOT SUPPORT having deferable content in an async // stream, since we don't have a good way to defer the load of this block // of records. Stream stream = BinaryReader.BaseStream; long startPosition = stream.Position; long bytesAvailable = stream.Length - startPosition; if (bytesAvailable < bamlRecord.ContentSize) { ThrowException(SRID.ParserDeferContentAsync); } // Read through all the key records and the static resource records ArrayList defKeyList; List<object[]> staticResourceValuesList; BaseReadDeferableContentStart(bamlRecord, out defKeyList, out staticResourceValuesList); // If we don't own the stream, someone might close it when the parse is complete, // so copy the defer load contents into a buffer. If we own the // stream, then we'll assume the owner will keep it open. long endOfKeysPosition = stream.Position; Int32 valuesSize = (Int32)(bamlRecord.ContentSize - endOfKeysPosition + startPosition); if (!ParserContext.OwnsBamlStream) { byte[] buffer = new byte[valuesSize]; if (valuesSize > 0) { MS.Internal.IO.Packaging.PackagingUtilities.ReliableRead( BinaryReader, buffer, 0, valuesSize); } throw new NotImplementedException(); //dictionary.SetDeferableContent(buffer, // ParserContext, _rootElement, defKeyList, staticResourceValuesList); } else { throw new NotImplementedException(); //dictionary.SetDeferableContent(_bamlStream, // endOfKeysPosition, valuesSize, // ParserContext, _rootElement, defKeyList, staticResourceValuesList); //_bamlStream.Seek(valuesSize, SeekOrigin.Current); } } }