private void populatePartials() { foreach (var instance in instances) { var dataRoot = instance.Value.data; AStruct partialToProcess = dataRoot; while (partialToProcess != null) { instance.Value.addPartial(partialToProcess.name, partialToProcess); partialToProcess = partialToProcess.fields.ContainsKey("$") ? partialToProcess.fields["$"].castTo <AStruct>() : null; } } }
private static AStruct flatten(AStruct what, FlattenSharedState fss) { if (what.fields.ContainsKey("$")) { var flattened = new AStruct(); flattened.name = what.name; flattened.correspondingDaiFields = what.correspondingDaiFields; doFlatten(what, flattened, fss); return(flattened); } else { return(what); } }
private static void doFlatten(AStruct toProcess, AStruct toAdd, FlattenSharedState fss) { foreach (var field in toProcess.fields) { if (field.Key.Equals("$")) { doFlatten(field.Value.castTo <AStruct>(), toAdd, fss); } else { AValue val; var ftype = field.Value.Type; if (ftype == ValueTypes.STRUCT) { val = flatten(field.Value.castTo <AStruct>(), fss); } else if (ftype == ValueTypes.ARRAY) { val = flatten(field.Value.castTo <AArray>(), fss); } else { val = field.Value; } string key; if (toAdd.fields.ContainsKey(field.Key)) { key = $"{field.Key}_{fss.nonUniquesCounter++}"; } else { key = field.Key; } toAdd.fields.Add(key, val); } } }
public AValue get(string fieldName, bool searchAncestors = true) { bool shouldStop = false; AStruct toSearch = this; while (!shouldStop) { if (toSearch.fields.ContainsKey(fieldName)) { return(toSearch.fields[fieldName]); } else if (toSearch.fields.ContainsKey("$")) { toSearch = toSearch.fields["$"].castTo <AStruct>(); } else { shouldStop = true; } } return(null); }
private static AValue convert(DAIField field, ConverterContext ctx) { AValue result; if (field.ValueType == DAIFieldType.DAI_Complex) { var value = field.GetComplexValue(); if (value == null) { result = new ASimpleValue("{null}"); } else { var astruct = new AStruct(); astruct.name = value.GetName(); foreach (var childField in value.Fields) { AValue convertedChild = convert(childField, ctx); var childFieldName = childField.Descriptor.FieldName; astruct.fields.Add(childFieldName, convertedChild); astruct.correspondingDaiFields.Add(childFieldName, childField); } result = astruct; } } else if (field.ValueType == DAIFieldType.DAI_Array) { var value = field.GetArrayValue(); var aarray = new AArray(); foreach (var memberField in value.Fields) { AValue convertedMember = convert(memberField, ctx); aarray.elements.Add(convertedMember); aarray.correspondingDaiFields.Add(memberField); } result = aarray; } else if (field.ValueType == DAIFieldType.DAI_Guid) { var guid = ctx.file.GetDaiGuidFieldValue(field); if (guid.instanceGuid.Equals("null")) { result = new ANullRef(); } else { if (guid.external) { var aexref = new AExRef(guid.fileGuid, guid.instanceGuid); ctx.extRefs.Add(new Tuple <AExRef, string>(aexref, ctx.instanceGuid)); result = aexref; } else { var ainref = new AIntRef(guid.instanceGuid); ctx.intReferences.Add(new Tuple <AIntRef, string>(ainref, ctx.instanceGuid)); result = ainref; } } } else { String strValue; switch (field.ValueType) { case DAIFieldType.DAI_String: strValue = field.GetStringValue(); break; case DAIFieldType.DAI_Enum: strValue = field.GetEnumValue(); break; case DAIFieldType.DAI_Int: strValue = field.GetIntValue().ToString(); break; case DAIFieldType.DAI_UInt: strValue = field.GetUIntValue().ToString(); break; case DAIFieldType.DAI_Double: case DAIFieldType.DAI_Float: strValue = field.GetFloatValue().ToString(); break; case DAIFieldType.DAI_Short: strValue = field.GetShortValue().ToString(); break; case DAIFieldType.DAI_UShort: strValue = field.GetUShortValue().ToString(); break; case DAIFieldType.DAI_Byte: case DAIFieldType.DAI_UByte: strValue = field.GetByteValue().ToString(); break; case DAIFieldType.DAI_Long: strValue = field.GetLongValue().ToString(); break; case DAIFieldType.DAI_LongLong: strValue = "LL " + DAIEbx.GuidToString(field.GetLongLongValue()); break; case DAIFieldType.DAI_Bool: strValue = field.GetBoolValue().ToString(); break; default: throw new ArgumentOutOfRangeException(); } result = new ASimpleValue(strValue, tryUnhash(strValue)); } return(result); }
public static EbxDataContainers fromDAIEbx(DAIEbx file, Action <string> statusConsumer, bool resolveExternalRefs = true) { Dictionary <String, DataContainer> instances = new Dictionary <string, DataContainer>(); var ctx = new ConverterContext(); ctx.file = file; statusConsumer("Converting instances..."); foreach (var instance in file.Instances) { var instanceGuid = DAIEbx.GuidToString(instance.Key); statusConsumer($"Converting {instanceGuid}..."); ctx.instanceGuid = instanceGuid; var rootFakeField = wrapWithFakeField(instance.Value); AValue convertedTreeRoot = convert(rootFakeField, ctx); Debug.Assert(convertedTreeRoot.Type == ValueTypes.STRUCT); AStruct treeRoot = (AStruct)convertedTreeRoot; instances.Add(instanceGuid, new DataContainer(instanceGuid, treeRoot)); } statusConsumer("Processing IntRefs..."); foreach (var refEntry in ctx.intReferences) { var refObj = refEntry.Item1; var targetGuid = refObj.instanceGuid; if (instances.ContainsKey(targetGuid)) { var target = instances[targetGuid]; target.internalRefCount += 1; refObj.refStatus = RefStatus.RESOLVED_SUCCESS; } else { refObj.refStatus = RefStatus.RESOLVED_FAILURE; } var refObjTreeRootGuid = refEntry.Item2; instances[refObjTreeRootGuid].addIntRef(targetGuid); } if (resolveExternalRefs) { statusConsumer("Processing ExRefs..."); using (var dbconn = Database.GetConnection()) { dbconn.Open(); using (var dbtrans = dbconn.BeginTransaction()) { int processedCount = 0; foreach (var exRefEntry in ctx.extRefs) { var exref = exRefEntry.Item1; var sqlCmdText = $"select name, type from ebx where guid = \"{exref.fileGuid}\""; using (var reader = new SQLiteCommand(sqlCmdText, dbconn).ExecuteReader()) { if (!reader.HasRows) { exref.refStatus = RefStatus.RESOLVED_FAILURE; } else { reader.Read(); var values = new object[2]; reader.GetValues(values); exref.refName = (string)values[0]; exref.refType = (string)values[1]; exref.refStatus = RefStatus.RESOLVED_SUCCESS; } } processedCount += 1; statusConsumer($"Processed ExtRefs: {processedCount}/{ctx.extRefs.Count}"); } dbtrans.Commit(); } } } statusConsumer("Populating partials..."); var fileGuid = DAIEbx.GuidToString(file.FileGuid); var edc = new EbxDataContainers(fileGuid, instances, file); edc.populatePartials(); statusConsumer("DAIEbx -> EbxDataContainers done."); return(edc); }