コード例 #1
0
            /// <summary>
            /// Deserialise an API call from JSON
            /// </summary>
            /// <param name="apiArr">The serialised call data</param>
            /// <param name="trace">The trace the call belongs to</param>
            /// <param name="apiObj">The resulting API object</param>
            /// <returns></returns>
            public static bool TryDeserialise(JArray apiArr, TraceRecord trace, out APICALL?apiObj)
            {
                apiObj = null;

                if (apiArr[0].Type is not JTokenType.Date)
                {
                    return(false);
                }
                DateTime graphConstructed = apiArr[0].ToObject <DateTime>();

                ProtoGraph?graph = trace.GetProtoGraphByTime(graphConstructed);

                if (graph is null)
                {
                    return(false);
                }

                apiObj = new APICALL(graph)
                {
                    Node    = graph.NodeList[apiArr[1].ToObject <int>()],
                    Index   = apiArr[2].ToObject <int>(),
                    Repeats = apiArr[3].ToObject <ulong>(),
                    UniqID  = apiArr[4].ToObject <uint>()
                };

                if (apiArr[5] is not null)
                {
                    if (!DeserialiseEffects(apiArr[5], apiObj))
                    {
                        return(false);
                    }
                }

                return(true);
            }
コード例 #2
0
            /// <summary>
            /// Deserialise a timeline event from JSON
            /// </summary>
            /// <param name="jsnReader">A JsonReader for the trace file</param>
            /// <param name="serializer">A JsonSerializer</param>
            /// <param name="trace">The trace assocated with the timeline event</param>
            public TIMELINE_EVENT(JsonReader jsnReader, JsonSerializer serializer, TraceRecord trace) : base(eLogFilterBaseType.TimeLine)
            {
                jsnReader.Read();
                JArray?itemMeta = serializer.Deserialize <JArray>(jsnReader);

                if (itemMeta is null || itemMeta.Count != 3)
                {
                    return;
                }

                _eventType = itemMeta[0].ToObject <eTimelineEvent>();
                JToken idTok  = itemMeta[1];
                JToken pIdTok = itemMeta[2];


                //_item = item;
                switch (_eventType)
                {
                case eTimelineEvent.ProcessStart:
                case eTimelineEvent.ProcessEnd:
                    SetIDs(ID: idTok.ToObject <ulong>(), parentID: pIdTok.ToObject <ulong>());
                    _item  = trace.GetTraceByID(ID) !;
                    Inited = true;
                    break;

                case eTimelineEvent.ThreadStart:
                case eTimelineEvent.ThreadEnd:
                    Debug.Assert(trace.ParentTrace == null || idTok.ToObject <ulong>() == trace.ParentTrace.PID);
                    SetIDs(ID: idTok.ToObject <ulong>());
                    _item  = trace.GetProtoGraphByTID(ID) !;
                    Inited = true;
                    break;

                case eTimelineEvent.APICall:

                    jsnReader.Read();
                    JArray?apiArr = serializer.Deserialize <JArray>(jsnReader);
                    if (apiArr is null)
                    {
                        Logging.RecordError("No APICALL data in timeline api event");
                        return;
                    }
                    if (!APICALL.TryDeserialise(apiArr, trace, out APICALL? apiObj) || apiObj is null)
                    {
                        Logging.RecordError("Bad APICALL data in timeline api event");
                        return;
                    }

                    SetIDs(ID: idTok.ToObject <ulong>(), parentID: pIdTok.ToObject <ulong>());
                    _item  = apiObj;
                    Inited = true;
                    break;

                default:
                    Debug.Assert(false, "Bad timeline event");
                    break;
                }
            }
コード例 #3
0
            /// <summary>
            /// Serialise the timeline event to JSON
            /// </summary>
            public void Serialise(Newtonsoft.Json.JsonWriter writer, Newtonsoft.Json.JsonSerializer serializer)
            {
                Debug.Assert(_item is not null);
                JArray meta = new JArray
                {
                    TimelineEventType,
                    ID,
                    Parent
                };

                meta.WriteTo(writer);

                if (TimelineEventType == eTimelineEvent.APICall)
                {
                    APICALL apic = (Logging.APICALL)_item;
                    apic.Serialise(writer, serializer);
                }
            }
コード例 #4
0
            /// <summary>
            /// Implementing effects as derived classes means safe deserialisation is quite clunky
            /// </summary>
            /// <param name="deTok">JToken of the APICALL details</param>
            /// <param name="apiObj">APICALL being deserialised</param>
            /// <returns>success</returns>
            private static bool DeserialiseEffects(JToken deTok, APICALL apiObj)
            {
                try
                {
                    JObject?deJObj = deTok.ToObject <JObject>();
                    if (deJObj is null)
                    {
                        return(false);
                    }

                    apiObj.APIDetails = deTok.ToObject <APIDetailsWin.API_ENTRY>();
                    if (apiObj.APIDetails is not null &&
                        deJObj.TryGetValue("Effects", out JToken? effTok) &&
                        apiObj.APIDetails.Value.Effects is not null &&
                        effTok.Type is JTokenType.Array)
                    {
                        JArray?effArray = effTok.ToObject <JArray>();
                        for (int effecti = 0; effecti < effArray?.Count; effecti++)
                        {
                            JToken  effItem   = effArray[effecti];
                            JObject?effectObj = effItem.ToObject <JObject>();
                            if (effectObj is null)
                            {
                                return(false);
                            }

                            if (effectObj.TryGetValue("TypeName", out JToken? nameTok) && nameTok is not null)
                            {
                                switch (nameTok.ToString())
                                {
                                case "Link":
                                    {
                                        JToken?entityIdx = effectObj["EntityIndex"];
                                        JToken?refIdx    = effectObj["ReferenceIndex"];
                                        if (entityIdx is null || refIdx is null)
                                        {
                                            return(false);
                                        }

                                        int entityIndex    = entityIdx.ToObject <int>();
                                        int referenceIndex = refIdx.ToObject <int>();
                                        APIDetailsWin.LinkReferenceEffect linkEff = new APIDetailsWin.LinkReferenceEffect(entityIndex, referenceIndex);

                                        apiObj.APIDetails.Value.Effects[effecti] = linkEff;
                                        break;
                                    }

                                case "Use":
                                {
                                    JToken?refIdx = effectObj["ReferenceIndex"];
                                    if (refIdx is null)
                                    {
                                        return(false);
                                    }

                                    apiObj.APIDetails.Value.Effects[effecti] = new APIDetailsWin.UseReferenceEffect(refIdx.ToObject <int>());
                                    break;
                                }

                                case "Destroy":
                                {
                                    JToken?refIdx = effectObj["ReferenceIndex"];
                                    if (refIdx is null)
                                    {
                                        return(false);
                                    }

                                    apiObj.APIDetails.Value.Effects[effecti] = new APIDetailsWin.DestroyReferenceEffect(refIdx.ToObject <int>());
                                    break;
                                }
                                }
                            }
                        }
                    }
                    return(true);
                }
                catch (Exception e)
                {
                    Logging.RecordException($"Failed to load API call details: {e.Message}", e);
                    return(false);
                }
            }