예제 #1
0
        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;
                }
            }
        }
예제 #2
0
 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);
     }
 }
예제 #3
0
        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);
                }
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }