private ABCTraitInfo[] _readTraitInfo(int count) { const ABCTraitFlags validTraitAttrs = ABCTraitFlags.ATTR_Final | ABCTraitFlags.ATTR_Metadata | ABCTraitFlags.ATTR_Override; if (count == 0) { return(Array.Empty <ABCTraitInfo>()); } var traits = new ABCTraitInfo[count]; for (int i = 0; i < traits.Length; i++) { ABCMultiname traitName = m_abcFile.resolveMultiname(_readU30()); if (traitName.kind != ABCConstKind.QName) { throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NOT_QNAME); } QName traitQualifiedName = new QName( m_abcFile.resolveNamespace(traitName.namespaceIndex), m_abcFile.resolveString(traitName.localNameIndex) ); if (traitQualifiedName.ns.kind == NamespaceKind.ANY || traitQualifiedName.localName == null) { throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NULL); } ABCTraitFlags flags = (ABCTraitFlags)_readU8(); if ((flags & ~ABCTraitFlags.KIND_MASK & ~validTraitAttrs) != 0) { throw ErrorHelper.createError(ErrorCode.INVALID_TRAIT_KIND, (int)flags); } ABCTraitFlags kind = flags & ABCTraitFlags.KIND_MASK; ABCTraitInfo traitInfo; if (kind == ABCTraitFlags.Slot || kind == ABCTraitFlags.Const) { int slotId = _readU30(); ABCMultiname typeName = m_abcFile.resolveMultiname(_readU30()); ASAny defaultVal = ASAny.undefined; int defaultValIndex = _readU30(); if (defaultValIndex != 0) { defaultVal = m_abcFile.resolveConstant((ABCConstKind)_readU8(), defaultValIndex); } traitInfo = new ABCTraitInfo(traitQualifiedName, flags, slotId, typeName, defaultValIndex != 0, defaultVal); } else if (kind == ABCTraitFlags.Class) { int slotId = _readU30(); ABCClassInfo classInfo = m_abcFile.resolveClassInfo(_readU30()); traitInfo = new ABCTraitInfo(traitQualifiedName, flags, slotId, classInfo); } else if (kind >= ABCTraitFlags.Method && kind <= ABCTraitFlags.Function) { int slotOrDispId = _readU30(); ABCMethodInfo methodInfo = m_abcFile.resolveMethodInfo(_readU30()); traitInfo = new ABCTraitInfo(traitQualifiedName, flags, slotOrDispId, methodInfo); } else { throw ErrorHelper.createError(ErrorCode.INVALID_TRAIT_KIND, (int)flags); } if ((flags & ABCTraitFlags.ATTR_Metadata) != 0) { int metadataCount = _readU30(); if (metadataCount != 0) { MetadataTag[] metadata = new MetadataTag[metadataCount]; for (int j = 0; j < metadata.Length; j++) { metadata[j] = m_abcFile.resolveMetadata(_readU30()); } traitInfo.setMetadata(new MetadataTagCollection(metadata)); } } traits[i] = traitInfo; } return(traits); }
private void _readClassInfo() { const ABCClassFlags validClassFlags = ABCClassFlags.ClassFinal | ABCClassFlags.ClassSealed | ABCClassFlags.ClassInterface | ABCClassFlags.ClassProtectedNs; int classCount = _readU30(); var classInfoArr = new ABCClassInfo[classCount]; // Since a class can refer to another via a class trait in its instance_info // or static_info traits, we must create all ABCClassInfo instances upfront. for (int i = 0; i < classInfoArr.Length; i++) { classInfoArr[i] = new ABCClassInfo(i); } m_abcFile.setClassInfo(classInfoArr); // Read instance_info for (int i = 0; i < classInfoArr.Length; i++) { ABCMultiname className = m_abcFile.resolveMultiname(_readU30()); if (className.kind != ABCConstKind.QName) { throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NOT_QNAME); } QName classQualifiedName = new QName( m_abcFile.resolveNamespace(className.namespaceIndex), m_abcFile.resolveString(className.localNameIndex) ); if (classQualifiedName.ns.kind == NamespaceKind.ANY || classQualifiedName.localName == null) { throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_CLASS_TRAIT_NAME_NULL); } ABCMultiname parentName = m_abcFile.resolveMultiname(_readU30()); var flags = (ABCClassFlags)_readU8(); if ((flags & ~validClassFlags) != 0) { throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_INVALID_INSTANCE_INFO_FLAGS); } const ABCClassFlags finalOrInterface = ABCClassFlags.ClassFinal | ABCClassFlags.ClassInterface; if ((flags & finalOrInterface) == finalOrInterface) { // ClassFinal and ClassInterface cannot be used together throw ErrorHelper.createError(ErrorCode.MARIANA__ABC_INVALID_INSTANCE_INFO_FLAGS); } Namespace protectedNS = default(Namespace); if ((flags & ABCClassFlags.ClassProtectedNs) != 0) { protectedNS = m_abcFile.resolveNamespace(_readU30()); } int interfaceCount = _readU30(); ABCMultiname[] interfaceNames = Array.Empty <ABCMultiname>(); if (interfaceCount != 0) { interfaceNames = new ABCMultiname[interfaceCount]; for (int j = 0; j < interfaceNames.Length; j++) { interfaceNames[j] = m_abcFile.resolveMultiname(_readU30()); } } ABCMethodInfo instanceInit = m_abcFile.resolveMethodInfo(_readU30()); ABCTraitInfo[] traits = _readTraitInfo(_readU30()); classInfoArr[i].init(classQualifiedName, parentName, interfaceNames, protectedNS, flags); classInfoArr[i].initInstanceInfo(instanceInit, traits); } // Read class_info for (int i = 0; i < classCount; i++) { ABCMethodInfo staticInit = m_abcFile.resolveMethodInfo(_readU30()); ABCTraitInfo[] traits = _readTraitInfo(_readU30()); classInfoArr[i].initStaticInfo(staticInit, traits); } }