// Token: 0x06001EC9 RID: 7881 RVA: 0x00093BE4 File Offset: 0x00091DE4 internal BamlRecord CloneRecord(BamlRecord record) { BamlRecordType recordType = record.RecordType; BamlRecord bamlRecord; if (recordType != BamlRecordType.ElementStart) { if (recordType != BamlRecordType.PropertyCustom) { bamlRecord = this.AllocateRecord(record.RecordType); } else if (record is BamlPropertyCustomWriteInfoRecord) { bamlRecord = new BamlPropertyCustomWriteInfoRecord(); } else { bamlRecord = new BamlPropertyCustomRecord(); } } else if (record is BamlNamedElementStartRecord) { bamlRecord = new BamlNamedElementStartRecord(); } else { bamlRecord = new BamlElementStartRecord(); } record.Copy(bamlRecord); return(bamlRecord); }
// Token: 0x0600237C RID: 9084 RVA: 0x000AD4B8 File Offset: 0x000AB6B8 internal override object GetDictionaryKey(BamlRecord startRecord, ParserContext parserContext) { object obj = null; int num = 0; BamlRecord bamlRecord = startRecord; short num2 = 0; while (bamlRecord != null) { if (bamlRecord.RecordType == BamlRecordType.ElementStart) { BamlElementStartRecord bamlElementStartRecord = bamlRecord as BamlElementStartRecord; if (++num != 1) { break; } num2 = bamlElementStartRecord.TypeId; } else if (bamlRecord.RecordType == BamlRecordType.Property && num == 1) { BamlPropertyRecord bamlPropertyRecord = bamlRecord as BamlPropertyRecord; short num3; string a; BamlAttributeUsage bamlAttributeUsage; parserContext.MapTable.GetAttributeInfoFromId(bamlPropertyRecord.AttributeId, out num3, out a, out bamlAttributeUsage); if (num3 == num2) { if (a == "TargetType") { obj = parserContext.XamlTypeMapper.GetDictionaryKey(bamlPropertyRecord.Value, parserContext); } else if (a == "DataType") { object dictionaryKey = parserContext.XamlTypeMapper.GetDictionaryKey(bamlPropertyRecord.Value, parserContext); Exception ex = TemplateKey.ValidateDataType(dictionaryKey, null); if (ex != null) { this.ThrowException("TemplateBadDictionaryKey", parserContext.LineNumber, parserContext.LinePosition, ex); } obj = new DataTemplateKey(dictionaryKey); } } } else if (bamlRecord.RecordType == BamlRecordType.PropertyComplexStart || bamlRecord.RecordType == BamlRecordType.PropertyIListStart || bamlRecord.RecordType == BamlRecordType.ElementEnd) { break; } bamlRecord = bamlRecord.Next; } if (obj == null) { this.ThrowException("StyleNoDictionaryKey", parserContext.LineNumber, parserContext.LinePosition, null); } return(obj); }
// Token: 0x06002379 RID: 9081 RVA: 0x000AD358 File Offset: 0x000AB558 internal override object GetDictionaryKey(BamlRecord startRecord, ParserContext parserContext) { Type result = Style.DefaultTargetType; bool flag = false; object obj = null; int num = 0; BamlRecord bamlRecord = startRecord; short ownerTypeId = 0; while (bamlRecord != null) { if (bamlRecord.RecordType == BamlRecordType.ElementStart) { BamlElementStartRecord bamlElementStartRecord = bamlRecord as BamlElementStartRecord; if (++num == 1) { ownerTypeId = bamlElementStartRecord.TypeId; } else if (num == 2) { result = parserContext.MapTable.GetTypeFromId(bamlElementStartRecord.TypeId); flag = true; break; } } else if (bamlRecord.RecordType == BamlRecordType.Property && num == 1) { BamlPropertyRecord bamlPropertyRecord = bamlRecord as BamlPropertyRecord; if (parserContext.MapTable.DoesAttributeMatch(bamlPropertyRecord.AttributeId, ownerTypeId, "TargetType")) { obj = parserContext.XamlTypeMapper.GetDictionaryKey(bamlPropertyRecord.Value, parserContext); } } else if (bamlRecord.RecordType == BamlRecordType.PropertyComplexStart || bamlRecord.RecordType == BamlRecordType.PropertyIListStart) { break; } bamlRecord = bamlRecord.Next; } if (obj == null) { if (!flag) { this.ThrowException("StyleNoDictionaryKey", parserContext.LineNumber, parserContext.LinePosition); } return(result); } return(obj); }
// Determine the element type for a baml start record, and either create a new // element or mark it for delay creation later. Update the ReaderFlags to // indicate the type of element created. private void GetElementAndFlags( BamlElementStartRecord bamlElementStartRecord, out object element, out ReaderFlags flags, out Type delayCreatedType, out short delayCreatedTypeId) { short typeId = bamlElementStartRecord.TypeId; Type elementType = MapTable.GetTypeFromId(typeId); element = null; delayCreatedType = null; delayCreatedTypeId = 0; flags = ReaderFlags.Unknown; if (null != elementType) { if (bamlElementStartRecord.CreateUsingTypeConverter || typeof(MarkupExtension).IsAssignableFrom(elementType)) { // CreateUsingTypeConverter means we've decided // (in XamlRecordReader) that we do not wish to // create an instance at this time, go to the delay- // creation state. // MarkupExtensions will be created later after we have // parsed the constructor parameters. delayCreatedType = elementType; delayCreatedTypeId = typeId; } else { // Create an instance of the object specified by the // BeginElement, throw if the creation fails. element = CreateInstanceFromType(elementType, typeId, false); if (element == null) { ThrowException(SRID.ParserNoElementCreate2, elementType.FullName); } } flags = GetFlagsFromType(elementType); } }
// Read the start of an element. This involves creating a new object, and storing it // for later addition to the tree or setting as a property. // Return true if a serializer has been spun off to parse the next element, or // false if it was handled by the BamlRecordReader itself. If a serializer has // been spun off, then the end record that matches this start record will NOT // get to this instance of the BamlRecordReader. //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 protected virtual bool ReadElementStartRecord(BamlElementStartRecord bamlElementRecord) { // Check if the type of this element has a serializer associated with it. If so then // we have to create a serializer and pass off processing to it. Otherwise, continue // with default processing. bool hasSerializer = MapTable.HasSerializerForTypeId(bamlElementRecord.TypeId); if (hasSerializer) { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, EventTrace.Event.WClientParseRdrCrInstBegin); try { BamlTypeInfoRecord typeInfo = MapTable.GetTypeInfoFromId(bamlElementRecord.TypeId); XamlSerializer serializer = CreateSerializer((BamlTypeInfoWithSerializerRecord)typeInfo); if (ParserContext.RootElement == null) { ParserContext.RootElement = _rootElement; } if (ParserContext.StyleConnector == null) { ParserContext.StyleConnector = _rootElement as IStyleConnector; } // PreParsedIndex is updated by Serializer after its TreeBuilder.Parse. serializer.ConvertBamlToObject(this, bamlElementRecord, ParserContext); } finally { EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Level.Verbose, EventTrace.Event.WClientParseRdrCrInstEnd); } return true; } BaseReadElementStartRecord(bamlElementRecord); return false; }
// Read the start of an element. This involves creating a new object, and storing it // for later addition to the tree or setting as a property. The base method does // not check for a serializer. //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 internal void BaseReadElementStartRecord( BamlElementStartRecord bamlElementRecord) { object element = null; Type delayCreatedType = null; short delayCreatedTypeId = 0; ReaderFlags flags = ReaderFlags.Unknown; ReaderContextStackData currentContext = CurrentContext; if (_bamlAsForest && currentContext == null) { Debug.Assert(_rootElement != null); element = _rootElement; flags = GetFlagsFromType(element.GetType()); } else { if (null != currentContext && (ReaderFlags.PropertyComplexClr == currentContext.ContextType || ReaderFlags.PropertyComplexDP == currentContext.ContextType) && null == currentContext.ExpectedType) { string propName = GetPropNameFrom(currentContext.ObjectData); ThrowException(SRID.ParserNoComplexMulti, propName); } // If this is the very top element as indicated by there not being a // parent context, then we have to add this element to the rootlist // by calling SetPropertyValueToParent. For all other cases we don't want to // call this here since we may be building a subtree bottom up and want // to defer addition of elements. This fixes bug 943189 - Async parsing broken if (null == ParentContext) { SetPropertyValueToParent(true); } // Get an instance of the element, if it is to be created now. Also set // the flags to indicate what the element is and how to treat it. GetElementAndFlags(bamlElementRecord, out element, out flags, out delayCreatedType, out delayCreatedTypeId); } Stream bamlStream = BamlStream; if (!_bamlAsForest && currentContext == null && element != null && bamlStream != null && !(bamlStream is ReaderStream) && StreamPosition == StreamLength) { // We are here because the root element was loaded from this baml stream // and not passed to us as is the case with the app loader\navigation engine, // and we are already at the end of the stream while processing this start // element record which would be the case when we have an element that has already // been instantiated by an inner LoadBaml call for that element with the same // Uri\ResourceLocator. So in this case we need to simulate a DocumentEnd to // cleanup properly and add to the RootList so that the caller of the outer // LoadBaml can access the element created by the inner LoadBaml. Debug.Assert(null == ParentContext); ReadDocumentEndRecord(); if (RootList.Count == 0) { RootList.Add(element); } // Set a flag to prevent the TreeBuilder from clobbering the // XamlTypeMapper's xmlns hashtable on the root element as this // would have already been set by the inner Baml loading Context. IsRootAlreadyLoaded = true; } else { // If we have a real element at this point, instead of some object that will be // delay created later, check for various interfaces that are called upon // element creation. if (element != null) { // If this is an element start record that carries its name also, then register the name now also. string elementName = null; if (bamlElementRecord is BamlNamedElementStartRecord) { BamlNamedElementStartRecord bamlNamedElementStartRecord = bamlElementRecord as BamlNamedElementStartRecord; elementName = bamlNamedElementStartRecord.RuntimeName; } ElementInitialize(element, elementName); } // Remember the object that was just created. It will be added when // the end tag is reached. CheckForTreeAdd(ref flags, currentContext); PushContext(flags, element, delayCreatedType, delayCreatedTypeId, bamlElementRecord.CreateUsingTypeConverter); // Add just constructed element to the tree if it is a UIElement. This // builds the tree in a top-down fashion for objects that make up the majority // of the logical tree. Other objects, such as Freezables, are added bottom-up // to aid in having all properties set prior to adding them to the tree. // See PS workitem #19080 if (BuildTopDown && element != null && ((element is UIElement) || (element is ContentElement) || (element is UIElement3D))) { SetPropertyValueToParent(true); } else if (CurrentContext.CheckFlag(ReaderFlags.IDictionary)) { // AddElement to Tree checks this, but if that wasn't called, then we need // to check for an explicit tag after a dictionary property. bool isMarkupExtension = false; if (CheckExplicitCollectionTag(ref isMarkupExtension)) { // if the tag is an explicit element under a collection property, we're done CurrentContext.MarkAddedToTree(); // ResourceDictionary objects must be loaded top-down if (element is ResourceDictionary) { SetCollectionPropertyValue(ParentContext); } } } } }