コード例 #1
0
        public VCSubfragment(BinaryReader reader, VCFragment parentFragment, CTFLanguage language, long baseAddress)
        {
            // see DIOpenCBF_FragValHandle
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            ulong bitflags = reader.ReadUInt16();

            Name_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            if (parentFragment.CCFHandle == 5)
            {
                // fragment should be parsed as PBSGetDumpAsStringFn, though internally we perceive this as the same
            }
            Dump                     = CaesarReader.ReadBitflagDumpWithReader(ref bitflags, reader, parentFragment.VarcodeDumpSize, baseAddress);
            Description_CTF          = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            QualifierUsuallyDisabled = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
            Unk3                     = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Unk4                     = CaesarReader.ReadBitflagInt16(ref bitflags, reader, -1);
            SupplementKey            = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
            NameCTFResolved          = language.GetString(Description_CTF);

            //int subfragmentIdk2 = reader.ReadInt32();
            //int subfragmentName = reader.ReadInt32();
            //int subfragmentIdkIncremented = reader.ReadInt32();
            //Console.WriteLine($"Subfragment: {subfragmentIdk1:X} {subfragmentIdk2:X} {language.GetString(subfragmentName)} {subfragmentIdkIncremented:X}");
            //PrintDebug();
        }
コード例 #2
0
 public void PrintDebug()
 {
     Console.WriteLine($"{nameof(Qualifier)} : {Qualifier}");
     Console.WriteLine($"{nameof(BitPosition)} : {BitPosition}");
     Console.WriteLine($"{nameof(ModeConfig)} : 0x{ModeConfig:X}");
     Console.WriteLine($"Mode H : 0x{ModeConfig & 0xFF0:X}, L : 0x{ModeConfig & 0xF:X}");
     Console.WriteLine($"{nameof(SizeInBits)} : 0x{SizeInBits:X}");
     Console.WriteLine($"{nameof(Name_CTF)} : {Name_CTF}");
     Console.WriteLine($"{nameof(Name_CTF)} : {Language.GetString(Name_CTF)}");
     Console.WriteLine($"{nameof(Unk1)} : {Unk1}");
     Console.WriteLine($"{nameof(Unk2)} : {Unk2}");
     Console.WriteLine($"{nameof(AlternativeBitWidth)} : {AlternativeBitWidth}");
     Console.WriteLine($"{nameof(IITOffset)} : {IITOffset}");
     Console.WriteLine($"{nameof(InfoPoolIndex)} : {InfoPoolIndex}");
     Console.WriteLine($"{nameof(PresPoolIndex)} : {PresPoolIndex}");
     Console.WriteLine($"{nameof(Field1E)} : {Field1E}");
     Console.WriteLine($"{nameof(SystemParam)} : {SystemParam}");
     // Console.WriteLine($"{nameof(noIdea_T)} : {language.GetString(noIdea_T)}");
     Console.WriteLine($"{nameof(Dump)} : {BitUtility.BytesToHex(Dump)}");
     Console.WriteLine("---------------");
 }
コード例 #3
0
        public ECU(BinaryReader reader, CTFLanguage language, CFFHeader header, long baseAddress, CaesarContainer parentContainer)
        {
            ParentContainer = parentContainer;
            BaseAddress     = baseAddress;
            // Read 32+16 bits
            ulong ecuBitFlags = reader.ReadUInt32();
            // after exhausting the 32 bits, load these additional 16 bits
            ulong ecuBitFlagsExtended = reader.ReadUInt16();

            // Console.WriteLine($"ECU bitflags: {ecuBitFlags:X}");

            // advancing forward to ecuBase + 10
            int ecuHdrIdk1 = reader.ReadInt32(); // no idea

            // Console.WriteLine($"Skipping: {ecuHdrIdk1:X8}");

            Qualifier            = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);
            EcuName_CTF          = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader, -1);
            EcuDescription_CTF   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader, -1);
            EcuXmlVersion        = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);
            InterfaceBlockCount  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            InterfaceTableOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            SubinterfacesCount   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            SubinterfacesOffset  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            EcuClassName         = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);
            UnkStr7 = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);
            UnkStr8 = CaesarReader.ReadBitflagStringWithReader(ref ecuBitFlags, reader, BaseAddress);

            int dataBufferOffsetRelativeToFile = header.StringPoolSize + StubHeader.StubHeaderSize + header.CffHeaderSize + 4;

            // Console.WriteLine($"{nameof(dataBufferOffsetRelativeToFile)} : 0x{dataBufferOffsetRelativeToFile:X}");

            IgnitionRequired   = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);
            Unk2               = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);
            UnkBlockCount      = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);
            UnkBlockOffset     = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            EcuSgmlSource      = CaesarReader.ReadBitflagInt16(ref ecuBitFlags, reader);
            Unk6RelativeOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            EcuVariant_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            EcuVariant_EntryCount  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            EcuVariant_EntrySize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            EcuVariant_BlockSize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            DiagJob_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            DiagJob_EntryCount  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            DiagJob_EntrySize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            DiagJob_BlockSize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Dtc_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            Dtc_EntryCount  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Dtc_EntrySize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Dtc_BlockSize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Env_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            Env_EntryCount  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Env_EntrySize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            // bitflags will be exhausted at this point, load the extended bitflags
            ecuBitFlags = ecuBitFlagsExtended;

            Env_BlockSize = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            VcDomain_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            VcDomain_EntryCount  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            VcDomain_EntrySize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            VcDomain_BlockSize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Presentations_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            Presentations_EntryCount  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Presentations_EntrySize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Presentations_BlockSize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Info_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            Info_EntryCount  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Info_EntrySize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Info_BlockSize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Unk_BlockOffset = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader) + dataBufferOffsetRelativeToFile;
            Unk_EntryCount  = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Unk_EntrySize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);
            Unk_BlockSize   = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            Unk39 = CaesarReader.ReadBitflagInt32(ref ecuBitFlags, reader);

            // read ecu's supported interfaces and subtypes

            // try to read interface block from the interface buffer table
            // this address is relative to the definitions block
            long interfaceTableAddress = BaseAddress + InterfaceTableOffset;

            // Console.WriteLine($"Interface table address: {interfaceTableAddress:X}, given offset: {interfaceTableOffset:X}");

            ECUInterfaces = new List <ECUInterface>();
            for (int interfaceBufferIndex = 0; interfaceBufferIndex < InterfaceBlockCount; interfaceBufferIndex++)
            {
                // Console.WriteLine($"Parsing interface {interfaceBufferIndex + 1}/{interfaceBlockCount}");

                // find our interface block offset
                reader.BaseStream.Seek(interfaceTableAddress + (interfaceBufferIndex * 4), SeekOrigin.Begin);
                // seek to the actual block (ambiguity: is this relative to the interface table or the current array?)
                int interfaceBlockOffset = reader.ReadInt32();

                long ecuInterfaceBaseAddress = interfaceTableAddress + interfaceBlockOffset;

                ECUInterface ecuInterface = new ECUInterface(reader, ecuInterfaceBaseAddress);
                ECUInterfaces.Add(ecuInterface);
            }

            // try to read interface subtype block from the interface buffer table
            // this address is relative to the definitions block
            ECUInterfaceSubtypes = new List <ECUInterfaceSubtype>();
            long ctTableAddress = BaseAddress + SubinterfacesOffset;

            // Console.WriteLine($"Interface subtype table address: {ctTableAddress:X}, given offset: {ecuChildTypesOffset:X}");
            for (int ctBufferIndex = 0; ctBufferIndex < SubinterfacesCount; ctBufferIndex++)
            {
                // Console.WriteLine($"Parsing interface subtype {ctBufferIndex + 1}/{ecuNumberOfEcuChildTypes}");
                // find our ct block offset
                reader.BaseStream.Seek(ctTableAddress + (ctBufferIndex * 4), SeekOrigin.Begin);
                // seek to the actual block (ambiguity: is this relative to the ct table or the current array?)
                int  actualBlockOffset = reader.ReadInt32();
                long ctBaseAddress     = ctTableAddress + actualBlockOffset;

                ECUInterfaceSubtype ecuInterfaceSubtype = new ECUInterfaceSubtype(reader, ctBaseAddress, ctBufferIndex);
                ECUInterfaceSubtypes.Add(ecuInterfaceSubtype);
            }

            CreateDiagServices(reader, language);
            CreateEcuVariants(reader, language);
            CreatePresentations(reader, language);
            ECUDescriptionTranslated = language.GetString(EcuDescription_CTF);
        }
コード例 #4
0
        public VCDomain(BinaryReader reader, ECU parentEcu, CTFLanguage language, int variantCodingDomainEntry)
        {
            ParentECU = parentEcu;

            byte[] variantCodingPool = parentEcu.ReadVarcodingPool(reader);
            using (BinaryReader poolReader = new BinaryReader(new MemoryStream(variantCodingPool)))
            {
                poolReader.BaseStream.Seek(variantCodingDomainEntry * parentEcu.VcDomain_EntrySize, SeekOrigin.Begin);
                int  entryOffset     = poolReader.ReadInt32();
                int  entrySize       = poolReader.ReadInt32();
                uint entryCrc        = poolReader.ReadUInt32();
                long vcdBlockAddress = entryOffset + parentEcu.VcDomain_BlockOffset;

                // Console.WriteLine($"VCD Entry @ 0x{entryOffset:X} with size 0x{entrySize:X} and CRC {entryCrc:X8}, abs addr {vcdBlockAddress:X8}");

                long baseAddress = vcdBlockAddress;
                reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
                ulong bitflags = reader.ReadUInt16();

                Qualifier           = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
                Name_CTF            = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
                Description_CTF     = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
                ReadServiceName     = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
                WriteServiceName    = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
                FragmentCount       = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
                FragmentTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader) + (int)baseAddress; // demoting long (warning)
                DumpSize            = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
                DefaultStringCount  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
                StringTableOffset   = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
                Unk1 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);

                // PrintDebug();

                VCFragments = new List <VCFragment>();
                for (int fragmentIndex = 0; fragmentIndex < FragmentCount; fragmentIndex++)
                {
                    VCFragment fragment = new VCFragment(reader, this, FragmentTableOffset, fragmentIndex, language);
                    VCFragments.Add(fragment);
                }
                // ValidateFragmentCoverage();

                if (DefaultStringCount > 0)
                {
                    DefaultData = new List <Tuple <string, byte[]> >();
                    long stringTableBaseAddress = StringTableOffset + baseAddress;
                    // this could almost be a class of its own but there isn't a distinct name to it
                    for (int stringTableIndex = 0; stringTableIndex < DefaultStringCount; stringTableIndex++)
                    {
                        reader.BaseStream.Seek(stringTableBaseAddress + (4 * stringTableIndex), SeekOrigin.Begin);
                        int  offset            = reader.ReadInt32();
                        long stringBaseAddress = stringTableBaseAddress + offset;
                        reader.BaseStream.Seek(stringBaseAddress, SeekOrigin.Begin);
                        ulong  strBitflags         = reader.ReadUInt16();
                        int    nameUsuallyAbsent_T = CaesarReader.ReadBitflagInt32(ref strBitflags, reader, -1);
                        int    offsetToBlob        = CaesarReader.ReadBitflagInt32(ref strBitflags, reader);
                        int    blobSize            = CaesarReader.ReadBitflagInt32(ref strBitflags, reader);
                        int    valueType_T         = CaesarReader.ReadBitflagInt32(ref strBitflags, reader, -1);
                        string noIdeaStr1          = CaesarReader.ReadBitflagStringWithReader(ref strBitflags, reader, stringBaseAddress);
                        int    noIdea2_T           = CaesarReader.ReadBitflagInt32(ref strBitflags, reader, -1);
                        int    noIdea3             = CaesarReader.ReadBitflagInt16(ref strBitflags, reader);
                        string noIdeaStr2          = CaesarReader.ReadBitflagStringWithReader(ref strBitflags, reader, stringBaseAddress);
                        byte[] blob = new byte[] { };
                        if (blobSize > 0)
                        {
                            long blobFileAddress = stringBaseAddress + offsetToBlob;
                            reader.BaseStream.Seek(blobFileAddress, SeekOrigin.Begin);
                            blob = reader.ReadBytes(blobSize);
                            // memcpy
                        }

                        string valueType = language.GetString(valueType_T);
                        DefaultData.Add(new Tuple <string, byte[]>(valueType, blob));
                        //Console.WriteLine($"Blob: {BitUtility.BytesToHex(blob)} @ {valueType}");
                        //Console.WriteLine($"String base address: 0x{stringBaseAddress:X}");
                    }
                }
            }
        }
コード例 #5
0
ファイル: DTC.cs プロジェクト: gibsonk1980/CaesarSuite
 public void PrintDebug()
 {
     Console.WriteLine($"DTC: {Qualifier}: {Language.GetString(Description_CTF)} : {Language.GetString(Reference_CTF)}");
 }
コード例 #6
0
        public string InterpretData(byte[] inBytes, DiagPreparation inPreparation, bool describe = true)
        {
            // might be relevant: DMPrepareSingleDatum, DMPresentSingleDatum

            bool isDebugBuild = false;

#if DEBUG
            isDebugBuild = true;
#endif

            string descriptionPrefix = describe ? $"{DescriptionString}: " : "";
            byte[] workingBytes      = inBytes.Skip(inPreparation.BitPosition / 8).Take(TypeLength_1A).ToArray();

            bool isEnumType = (EnumType_1E == 0) && ((Type_1C == 1) || (ScaleCountMaybe > 1));

            // hack: sometimes hybrid types (regularly parsed as an scaled value if within bounds) are misinterpreted as pure enums
            // this is a temporary fix for kilometerstand until there's a better way to ascertain its type
            // this also won't work on other similar cases without a unit string e.g. error instance counter (Häufigkeitszähler)
            if (DisplayedUnitString == "km")
            {
                isEnumType = false;
            }

            if (workingBytes.Length != TypeLength_1A)
            {
                return($"InBytes [{BitUtility.BytesToHex(workingBytes)}] length mismatch (expecting {TypeLength_1A})");
            }

            // handle booleans first since they're the edge case where they can cross byte boundaries
            if (inPreparation.SizeInBits == 1)
            {
                int  bytesToSkip  = (int)(inPreparation.BitPosition / 8);
                int  bitsToSkip   = inPreparation.BitPosition % 8;
                byte selectedByte = inBytes[bytesToSkip];

                int selectedBit = (selectedByte >> bitsToSkip) & 1;
                if (isEnumType && (Scales.Count > selectedBit))
                {
                    return($"{descriptionPrefix}{Language.GetString(Scales[selectedBit].EnumDescription)} {DisplayedUnitString}");
                }
                else
                {
                    return($"{descriptionPrefix}{selectedBit} {DisplayedUnitString}");
                }
            }

            // everything else should be aligned to byte boundaries
            if (inPreparation.BitPosition % 8 != 0)
            {
                return("BitOffset was outside byte boundary (skipped)");
            }
            int dataType             = GetDataType();
            int rawIntInterpretation = 0;

            string humanReadableType = $"UnhandledType:{dataType}";
            string parsedValue       = BitUtility.BytesToHex(workingBytes, true);
            if ((dataType == 6 || (dataType == 20)))
            {
                // parse as a regular int (BE)

                for (int i = 0; i < workingBytes.Length; i++)
                {
                    rawIntInterpretation <<= 8;
                    rawIntInterpretation  |= workingBytes[i];
                }

                humanReadableType = "IntegerType";

                parsedValue = rawIntInterpretation.ToString();
                if (dataType == 20)
                {
                    humanReadableType = "ScaledType";

                    double valueToScale = rawIntInterpretation;

                    // if there's only one scale, use it as-is
                    // if there's more than one, use the first scale as an interim solution;
                    // the results of stacking scales does not make sense
                    // there might be a better, non-hardcoded (0) solution to this, and perhaps with a sig-fig specifier

                    valueToScale *= Scales[0].MultiplyFactor;
                    valueToScale += Scales[0].AddConstOffset;

                    parsedValue = valueToScale.ToString("0.000000");
                }
            }
            else if (dataType == 18)
            {
                humanReadableType = "HexdumpType";
            }
            else if (dataType == 17)
            {
                humanReadableType = "StringType";
                parsedValue       = Encoding.UTF8.GetString(workingBytes);
            }

            if (isEnumType)
            {
                // discovered by @VladLupashevskyi in https://github.com/jglim/CaesarSuite/issues/27
                // if an enum is specified, the inclusive upper bound and lower bound will be defined in the scale object

                bool useNewInterpretation = false;
                foreach (Scale scale in Scales)
                {
                    if ((scale.EnumUpBound > 0) || (scale.EnumLowBound > 0))
                    {
                        useNewInterpretation = true;
                        break;
                    }
                }

                if (useNewInterpretation)
                {
                    foreach (Scale scale in Scales)
                    {
                        if ((rawIntInterpretation >= scale.EnumLowBound) && (rawIntInterpretation <= scale.EnumUpBound))
                        {
                            return($"{descriptionPrefix}{Language.GetString(scale.EnumDescription)} {DisplayedUnitString}");
                        }
                    }
                }
                else
                {
                    // original implementation, probably incorrect
                    if (rawIntInterpretation < Scales.Count)
                    {
                        return($"{descriptionPrefix}{Language.GetString(Scales[rawIntInterpretation].EnumDescription)} {DisplayedUnitString}");
                    }
                }
                return($"{descriptionPrefix}(Enum not found) {DisplayedUnitString}");
                // this bit below for troubleshooting problematic presentations

                /*
                 * if (rawIntInterpretation < Scales.Count)
                 * {
                 *  return $"{descriptionPrefix}{Language.GetString(Scales[rawIntInterpretation].EnumDescription)} {DisplayedUnitString}";
                 * }
                 * else
                 * {
                 *  // seems like an enum-like value broke
                 *  return $"{descriptionPrefix}{Language.GetString(Scales[0].EnumDescription)} {DisplayedUnitString} [!]";
                 * }
                 */
            }
            else
            {
                if (isDebugBuild)
                {
                    return($"{descriptionPrefix}{parsedValue} {DisplayedUnitString} ({humanReadableType})");
                }
                else
                {
                    return($"{descriptionPrefix}{parsedValue} {DisplayedUnitString}");
                }
            }
        }
コード例 #7
0
 public string GetDescription()
 {
     return(Language.GetString(Description_CTF));
 }
コード例 #8
0
        // 0x05 [6,   4,4,4,4,  4,4,4,4,  4,4,4,4,  2,2,2,4,      4,4,4,4,   4,4,4,4,   4,4,1,1,  1,1,1,4,     4,4,2,4,   4,4],

        public DiagPresentation(BinaryReader reader, long baseAddress, int presentationsIndex, CTFLanguage language)
        {
            BaseAddress       = baseAddress;
            PresentationIndex = presentationsIndex;

            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);
            ulong bitflags = reader.ReadUInt32();

            ulong extendedBitflags = reader.ReadUInt16(); // skip 2 bytes

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, BaseAddress);

            Description_CTF  = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            ScaleTableOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            ScaleCountMaybe  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            unk5 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            unk6 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unk7 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unk8 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            unk9 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unka = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unkb = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unkc = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            unkd = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            unke = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            unkf = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            DisplayedUnit_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);

            unk11 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unk12 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unk13 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unk14 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);

            unk15            = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Description2_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            unk17            = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            unk18            = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            unk19         = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            TypeLength_1a = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            unk1b         = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1);
            Type_1c       = CaesarReader.ReadBitflagInt8(ref bitflags, reader, -1);

            unk1d = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
            unk1e = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
            unk1f = CaesarReader.ReadBitflagInt8(ref bitflags, reader);
            unk20 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            bitflags = extendedBitflags;

            unk21 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unk22 = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            unk23 = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            unk24 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            unk25 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            unk26 = CaesarReader.ReadBitflagInt32(ref bitflags, reader);


            DescriptionString   = language.GetString(Description_CTF);
            DisplayedUnitString = language.GetString(DisplayedUnit_CTF);
            DescriptionString2  = language.GetString(Description2_CTF);


            long scaleTableBase = BaseAddress + ScaleTableOffset;

            Scales = new List <Scale>();
            for (int i = 0; i < ScaleCountMaybe; i++)
            {
                reader.BaseStream.Seek(scaleTableBase + (i * 4), SeekOrigin.Begin);
                int entryRelativeOffset = reader.ReadInt32();

                Scale scale = new Scale(reader, scaleTableBase + entryRelativeOffset);
                Scales.Add(scale);
            }
        }
コード例 #9
0
        public string InterpretData(byte[] inBytes, DiagPreparation inPreparation, bool describe = true)
        {
            // might be relevant: DMPrepareSingleDatum, DMPresentSingleDatum

            bool isDebugBuild = false;

#if DEBUG
            isDebugBuild = true;
#endif

            string descriptionPrefix = describe ? $"{DescriptionString}: " : "";
            byte[] workingBytes      = inBytes.Skip(inPreparation.BitPosition / 8).Take(TypeLength_1A).ToArray();

            bool isEnumType = (EnumType_1E == 0) && ((Type_1C == 1) || (ScaleCountMaybe > 1));

            if (workingBytes.Length != TypeLength_1A)
            {
                return($"InBytes [{BitUtility.BytesToHex(workingBytes)}] length mismatch (expecting {TypeLength_1A})");
            }

            // handle booleans first since they're the edge case where they can cross byte boundaries
            if (inPreparation.SizeInBits == 1)
            {
                int  bytesToSkip  = (int)(inPreparation.BitPosition / 8);
                int  bitsToSkip   = inPreparation.BitPosition % 8;
                byte selectedByte = inBytes[bytesToSkip];

                int selectedBit = (selectedByte >> bitsToSkip) & 1;
                if (isEnumType && (Scales.Count > selectedBit))
                {
                    return($"{descriptionPrefix}{Language.GetString(Scales[selectedBit].EnumDescription)} {DisplayedUnitString}");
                }
                else
                {
                    return($"{descriptionPrefix}{selectedBit} {DisplayedUnitString}");
                }
            }

            // everything else should be aligned to byte boundaries
            if (inPreparation.BitPosition % 8 != 0)
            {
                return("BitOffset was outside byte boundary (skipped)");
            }
            int dataType             = GetDataType();
            int rawIntInterpretation = 0;

            string humanReadableType = $"UnhandledType:{dataType}";
            string parsedValue       = BitUtility.BytesToHex(workingBytes, true);
            if ((dataType == 6 || (dataType == 20)))
            {
                // parse as a regular int (BE)

                for (int i = 0; i < workingBytes.Length; i++)
                {
                    rawIntInterpretation <<= 8;
                    rawIntInterpretation  |= workingBytes[i];
                }

                humanReadableType = "IntegerType";

                parsedValue = rawIntInterpretation.ToString();
                if (dataType == 20)
                {
                    humanReadableType = "ScaledType";

                    double valueToScale = rawIntInterpretation;

                    // if there's only one scale, use it as-is
                    // if there's more than one, use the first scale as an interim solution;
                    // the results of stacking scales does not make sense
                    // there might be a better, non-hardcoded (0) solution to this, and perhaps with a sig-fig specifier

                    valueToScale *= Scales[0].MultiplyFactor;
                    valueToScale += Scales[0].AddConstOffset;

                    parsedValue = valueToScale.ToString("0.000000");
                }
            }
            else if (dataType == 18)
            {
                humanReadableType = "HexdumpType";
            }
            else if (dataType == 17)
            {
                humanReadableType = "StringType";
                parsedValue       = Encoding.UTF8.GetString(workingBytes);
            }

            if (isEnumType && (rawIntInterpretation < Scales.Count))
            {
                return($"{descriptionPrefix}{Language.GetString(Scales[rawIntInterpretation].EnumDescription)} {DisplayedUnitString}");
                // this bit below for troubleshooting problematic presentations

                /*
                 * if (rawIntInterpretation < Scales.Count)
                 * {
                 *  return $"{descriptionPrefix}{Language.GetString(Scales[rawIntInterpretation].EnumDescription)} {DisplayedUnitString}";
                 * }
                 * else
                 * {
                 *  // seems like an enum-like value broke
                 *  return $"{descriptionPrefix}{Language.GetString(Scales[0].EnumDescription)} {DisplayedUnitString} [!]";
                 * }
                 */
            }
            else
            {
                if (isDebugBuild)
                {
                    return($"{descriptionPrefix}{parsedValue} {DisplayedUnitString} ({humanReadableType})");
                }
                else
                {
                    return($"{descriptionPrefix}{parsedValue} {DisplayedUnitString}");
                }
            }
        }