/// <summary> /// Initializes a new instance of the <see cref="PdbSymbolField"/> class. /// </summary> /// <param name="parentType">The parent type.</param> /// <param name="data">Data symbol type record.</param> public PdbSymbolField(PdbGlobalScope parentType, DataSymbol data) : base(parentType) { Name = data.Name; LocationType = DIA.LocationType.Static; DataKind = DIA.DataKind.StaticMember; Type = parentType.PdbModule.GetSymbol(data.Type); Size = Type.Size; }
private static DataArray NamedArray(string name, DataArray siblings) { var array = new DataArray(); array.AddNode(DataSymbol.Symbol(name)); foreach (var n in siblings.Children) { array.AddNode(n); } return(array); }
public static DataArray MakeMoggDta(DataArray array) { var moggDta = new DataArray(); var trackArray = new DataArray(); trackArray.AddNode(DataSymbol.Symbol("tracks")); var trackSubArray = trackArray.AddNode(new DataArray()); foreach (var child in array.Array("song").Array("tracks").Array(1).Children) { if (child is DataArray a && a.Children[1] is DataArray b && b.Count > 0) { trackSubArray.AddNode(child); } } var totalTracks = array.Array("song").Array("pans").Array(1).Children.Count; // Get the last track number. This is based on the assumption that the tracks are in order // We have to filter out empty track arrays because GHtoRB(?) does stuff like (keys ()) instead // of leaving out the keys array entirely var lastTrack = ((trackSubArray.Children .Where(x => x is DataArray dx ? dx.Array(1).Children.Count > 0 : false) .Last() as DataArray) .Array(1).Children.Last() as DataAtom).Int; var crowdChannel = array.Array("song").Array("crowd_channels")?.Int(1); if (crowdChannel != null) { if (crowdChannel == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (crowdChannel == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } trackSubArray.AddNode(DTX.FromDtaString($"crowd ({crowdChannel} {crowdChannel + 1})")); } else { if (totalTracks == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (totalTracks == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } } moggDta.AddNode(trackArray); moggDta.AddNode(array.Array("song").Array("pans")); moggDta.AddNode(array.Array("song").Array("vols")); return(moggDta); }
private static DataArray NamedItem(string name, DataNode value) { if (value is DataArray da) { return(NamedArray(name, da)); } var array = new DataArray(); array.AddNode(DataSymbol.Symbol(name)); array.AddNode(value); return(array); }
private void Serialize(string filename) { var data = new DataArray(); data.AddNode(DataSymbol.Symbol("points")); foreach (var p in points) { data.AddNode(p.p.Serialize()); } using (var writer = new System.IO.StreamWriter(filename)) { writer.Write(data.ToString()); } }
/// <summary> /// Reads symbol record from symbol references for the specified index. /// </summary> /// <param name="index">Index of the symbol record.</param> private SymbolRecord GetSymbol(int index) { // Since DictionaryCache is allowing only single thread to call this function, we don't need to lock reader here. SymbolReference reference = references[index]; Reader.Position = reference.DataOffset; switch (reference.Kind) { case SymbolRecordKind.S_GPROC32: case SymbolRecordKind.S_LPROC32: case SymbolRecordKind.S_GPROC32_ID: case SymbolRecordKind.S_LPROC32_ID: case SymbolRecordKind.S_LPROC32_DPC: case SymbolRecordKind.S_LPROC32_DPC_ID: return(ProcedureSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_PUB32: return(Public32Symbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_CONSTANT: case SymbolRecordKind.S_MANCONSTANT: return(ConstantSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_LDATA32: case SymbolRecordKind.S_GDATA32: case SymbolRecordKind.S_LMANDATA: case SymbolRecordKind.S_GMANDATA: return(DataSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_PROCREF: case SymbolRecordKind.S_LPROCREF: return(ProcedureReferenceSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_UDT: case SymbolRecordKind.S_COBOLUDT: return(UdtSymbol.Read(Reader, reference.Kind)); case SymbolRecordKind.S_LTHREAD32: case SymbolRecordKind.S_GTHREAD32: return(ThreadLocalDataSymbol.Read(Reader, reference.Kind)); default: throw new NotImplementedException(); } }
public static DataArray MakeMoggDta(DataArray array) { var moggDta = new DataArray(); var trackArray = new DataArray(); trackArray.AddNode(DataSymbol.Symbol("tracks")); var trackSubArray = trackArray.AddNode(new DataArray()); foreach (var child in array.Array("song").Array("tracks").Array(1).Children) { trackSubArray.AddNode(child); } var totalTracks = array.Array("song").Array("pans").Array(1).Children.Count; var lastTrack = ((trackSubArray.Children.Last() as DataArray) .Array(1).Children.Last() as DataAtom).Int; var crowdChannel = array.Array("song").Array("crowd_channels")?.Int(1); if (crowdChannel != null) { if (crowdChannel == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (crowdChannel == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } trackSubArray.AddNode(DTX.FromDtaString($"crowd ({crowdChannel} {crowdChannel + 1})")); } else { if (totalTracks == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (totalTracks == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } } moggDta.AddNode(trackArray); moggDta.AddNode(array.Array("song").Array("pans")); moggDta.AddNode(array.Array("song").Array("vols")); return(moggDta); }
/// <summary> /// Creates a list of static fields based on <see cref="TagRecord"/>.<see cref="TagRecord.FieldList"/>. /// </summary> private List <PdbTypeStaticField> EnumerateStaticFields() { List <PdbTypeStaticField> fields = new List <PdbTypeStaticField>(); foreach (TypeRecord field in EnumerateFieldList()) { if (field is StaticDataMemberRecord staticDataMemberRecord) { // Check if static field is constant string fullName = Name + "::" + staticDataMemberRecord.Name; var globals = Pdb.PdbFile.GlobalsStream; ConstantSymbol constant = null; ThreadLocalDataSymbol threadLocalData = null; DataSymbol data = null; if (globals.HashBuckets != null) { uint hash = HashTable.HashStringV1(fullName); var bucket = globals.HashBuckets[hash % (uint)globals.HashBuckets.Length]; for (int i = bucket.Start; i < bucket.End; i++) { SymbolRecord record = globals.Symbols[i]; if (record is ConstantSymbol c && c.Name.String == fullName) { constant = c; break; } else if (record is ThreadLocalDataSymbol tls && tls.Name.String == fullName) { threadLocalData = tls; break; } else if (record is DataSymbol ds && ds.Name.String == fullName) { data = ds; break; } // TODO: bucket items are ordered by byte value. Is it comparable by string.CompareTo? } }
static Builtins() { Funcs = new Dictionary <DataSymbol, Func <DataCommand, DataNode> >(); Funcs.Add(DataSymbol.Symbol("abs"), Abs); Funcs.Add(DataSymbol.Symbol("+"), Add); Funcs.Add(DataSymbol.Symbol("+="), AddEq); Funcs.Add(DataSymbol.Symbol("&"), BitAnd); Funcs.Add(DataSymbol.Symbol("append_str"), AppendStr); Funcs.Add(DataSymbol.Symbol("assign"), Assign); Funcs.Add(DataSymbol.Symbol("clamp"), Clamp); Funcs.Add(DataSymbol.Symbol("--"), Dec); Funcs.Add(DataSymbol.Symbol("/"), Divide); Funcs.Add(DataSymbol.Symbol("="), Eq); Funcs.Add(DataSymbol.Symbol("++"), Inc); Funcs.Add(DataSymbol.Symbol(">"), Gt); Funcs.Add(DataSymbol.Symbol("<"), Lt); Funcs.Add(DataSymbol.Symbol("-"), Subtract); Funcs.Add(DataSymbol.Symbol("if"), If); }
private static void AddLiteral(DataArray current, string tmp_literal) { int tmp_int; float tmp_float; if (int.TryParse(tmp_literal, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out tmp_int)) { current.AddNode(new DataAtom(tmp_int)); } else if (float.TryParse(tmp_literal, NumberStyles.Float, NumberFormatInfo.InvariantInfo, out tmp_float)) { current.AddNode(new DataAtom(tmp_float)); } else if (tmp_literal[0] == '$') { current.AddNode(DataVariable.Var(tmp_literal.Substring(1))); } else { current.AddNode(DataSymbol.Symbol(tmp_literal)); } }
/// <summary> /// Initializes a new instance of the <see cref="PdbTypeRegularStaticField"/> class. /// </summary> /// <param name="containerType">Type that contains this field.</param> /// <param name="staticDataMemberRecord">The static data member record.</param> /// <param name="data">Data symbol for this static field.</param> internal PdbTypeRegularStaticField(PdbUserDefinedType containerType, StaticDataMemberRecord staticDataMemberRecord, DataSymbol data) : base(containerType, staticDataMemberRecord) { Data = data; }
static GameObject[] ExtractVenuePropAnimsFromMidi(MidiFile mf) { var objs = new List <GameObject>(); short index = 1; var editorCom = new Component { Rev = 3, Name1 = "Editor", Name2 = "Editor", Unknown2 = 2, Props = new[] { new Property("capabilities", new UIntValue(62)) } }; objs.Add(new GameObject { Id = new GameObjectId { Index = 0, Layer = 0 }, Rev = 2, Name = "root", Components = new[] { editorComponent, entityHeaderComponent, new Component { Rev = 3, Name1 = "PropAnim", Name2 = "PropAnim", Unknown2 = 0, Props = StructValue.FromData( StructType.FromData(DTX.FromDtaString( @"(props (frame_range_start float) (frame_range_end float) (time_units int) (is_looping bool))")), DTX.FromDtaString( @"(frame_range_start 3.402823E+38) (frame_range_end -3.402823E+38) (time_units 0) (is_looping 0)")).Props } } }); var tracks = new Midi.MidiHelper().ProcessTracks(mf); var partMap = new Dictionary <string, string> { { "PART BASS", "bass_intensity" }, { "PART GUITAR", "guitar_intensity" }, { "PART DRUMS", "drum_intensity" }, { "PART VOCALS", "mic_intensity" }, #if DEBUG { "PART KEYS", "keyboard_intensity" }, #endif }; var intensityMap = new Dictionary <string, string> { // All { "[idle_realtime]", "idle_realtime" }, { "[idle]", "idle" }, { "[idle_intense]", "idle_intense" }, { "[play]", "play" }, { "[mellow]", "mellow" }, { "[intense]", "intense" }, // Guitar/bass only { "[play_solo]", "play_solo" }, // Vocal only { "[tambourine_start]", "tambourine_start" }, { "[tambourine_end]", "tambourine_end" }, { "[cowbell_start]", "cowbell_start" }, { "[cowbell_end]", "cowbell_end" }, { "[clap_start]", "clap_start" }, { "[clap_end]", "clap_end" }, // Drum only { "[ride_side_true]", "ride_side_true" }, { "[ride_side_false]", "ride_side_false" }, }; void AddAnimTrack(StructValue props) { objs.Add(new GameObject { Id = new GameObjectId { Index = index, Layer = index++ }, Rev = 2, Name = "Keys type 11", Components = new[] { editorCom, new Component { Rev = 3, Name1 = "PropKeysSymCom", Name2 = "PropKeys", Unknown2 = 0, Props = props.Props } } }); } StructValue MakeAnimProps(string drivenProp, List <Tuple <float, string> > frames) { var propkeys = DTX.FromDtaString( "(keys ()) " + "(interpolation 0) " + $"(driven_prop (0 0 RBVenueAuthoring 0 1 {drivenProp}))"); var keyframes = propkeys.Array("keys").Array(1); foreach (var(frame, key) in frames) { var keyframe = new DataArray(); keyframe.AddNode(new DataAtom(frame)); keyframe.AddNode(DataSymbol.Symbol(key)); keyframes.AddNode(keyframe); } return(StructValue.FromData(propKeysType, propkeys)); } foreach (var track in tracks) { if (!partMap.ContainsKey(track.Name)) { continue; } var frames = new List <Tuple <float, string> >(); foreach (var n in track.Items) { if (n is Midi.MidiText t) { if (intensityMap.ContainsKey(t.Text)) { frames.Add(Tuple.Create((float)n.StartTicks / mf.TicksPerQN, intensityMap[t.Text])); } } } AddAnimTrack(MakeAnimProps(partMap[track.Name], frames)); } AddAnimTrack(MakeAnimProps("shot_bg", new List <Tuple <float, string> > { Tuple.Create(0f, "coop_all_far") })); AddAnimTrack(MakeAnimProps("shot_bk", new List <Tuple <float, string> > { Tuple.Create(0f, "coop_all_far") })); AddAnimTrack(MakeAnimProps("shot_gk", new List <Tuple <float, string> > { Tuple.Create(0f, "coop_all_far") })); AddAnimTrack(MakeAnimProps("crowd", new List <Tuple <float, string> > { Tuple.Create(0f, "crowd_realtime") })); AddAnimTrack(MakeAnimProps("world_event", new List <Tuple <float, string> > { Tuple.Create(0f, "none") })); //AddAnimTrack(MakeAnimProps("part2_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") })); //AddAnimTrack(MakeAnimProps("part3_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") })); //AddAnimTrack(MakeAnimProps("part4_sing", new List<Tuple<float, string>> {Tuple.Create(0f, "singalong_off") })); AddAnimTrack(MakeAnimProps("lightpreset", new List <Tuple <float, string> > { Tuple.Create(0f, "silhouettes") })); AddAnimTrack(MakeAnimProps("postproc", new List <Tuple <float, string> > { Tuple.Create(0f, "profilm_a") })); AddAnimTrack(MakeAnimProps("lightpreset_keyframe", new List <Tuple <float, string> > { Tuple.Create(0f, "next") })); AddAnimTrack(MakeAnimProps("spot_bass", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); AddAnimTrack(MakeAnimProps("spot_guitar", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); AddAnimTrack(MakeAnimProps("spot_drums", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); //AddAnimTrack(MakeAnimProps("spot_keyboard", new List<Tuple<float, string>> {Tuple.Create(0f, "off") })); AddAnimTrack(MakeAnimProps("spot_vocal", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); //AddAnimTrack(MakeAnimProps("shot_5", new List<Tuple<float, string>> {Tuple.Create(0f, "coop_all_far") })); AddAnimTrack(MakeAnimProps("stagekit_fog", new List <Tuple <float, string> > { Tuple.Create(0f, "off") })); return(objs.ToArray()); }
public static DataArray MakeMoggDta(DataArray array, float volumeAdjustment) { var moggDta = new DataArray(); var trackArray = new DataArray(); trackArray.AddNode(DataSymbol.Symbol("tracks")); var trackSubArray = trackArray.AddNode(new DataArray()); foreach (var child in array.Array("song").Array("tracks").Array(1).Children) { if (child is DataArray a && a.Children[1] is DataArray b && b.Count > 0) { if (a.Symbol(0).Name == "drum") { switch (b.Count) { //Mix0 (2 channel) Whole kit in a stereo stream case 2: trackSubArray.AddNode(DTX.FromDtaString("drum (0 1)")); break; //Mix1 (4 channel) Mono kick, Mono Snare, Stereo Kit case 4: trackSubArray.AddNode(DTX.FromDtaString("drum (0)")); trackSubArray.AddNode(DTX.FromDtaString("drum (1)")); trackSubArray.AddNode(DTX.FromDtaString("drum (2 3)")); break; //Mix2 (5 channel) Mono kick, Stereo Snare, Stereo Kit case 5: trackSubArray.AddNode(DTX.FromDtaString("drum (0)")); trackSubArray.AddNode(DTX.FromDtaString("drum (1 2)")); trackSubArray.AddNode(DTX.FromDtaString("drum (3 4)")); break; //Mix3 (6 channel) Stereo kick, Stereo Snare, Stereo Kit case 6: trackSubArray.AddNode(DTX.FromDtaString("drum (0 1)")); trackSubArray.AddNode(DTX.FromDtaString("drum (2 3)")); trackSubArray.AddNode(DTX.FromDtaString("drum (4 5)")); break; //Mix4 (3 channel) Mono kick, Stereo Snare+Kit case 3: trackSubArray.AddNode(DTX.FromDtaString("drum (0)")); trackSubArray.AddNode(DTX.FromDtaString("drum (1 2)")); break; default: throw new Exception("You have too many or too few drum tracks. What are you doing?"); } } else { trackSubArray.AddNode(child); } } } var totalTracks = array.Array("song").Array("pans").Array(1).Children.Count; // Get the last track number. This is based on the assumption that the tracks are in order // We have to filter out empty track arrays because GHtoRB(?) does stuff like (keys ()) instead // of leaving out the keys array entirely var lastTrack = ((trackSubArray.Children .Where(x => x is DataArray dx ? dx.Array(1).Children.Count > 0 : false) .Last() as DataArray) .Array(1).Children.Last() as DataAtom).Int; var crowdChannel = array.Array("song").Array("crowd_channels")?.Int(1); if (crowdChannel != null) { if (crowdChannel == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (crowdChannel == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } trackSubArray.AddNode(DTX.FromDtaString($"crowd ({crowdChannel} {crowdChannel + 1})")); } else { if (totalTracks == lastTrack + 2) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1})")); } else if (totalTracks == lastTrack + 3) { trackSubArray.AddNode(DTX.FromDtaString($"fake ({lastTrack + 1} {lastTrack + 2})")); } } moggDta.AddNode(trackArray); moggDta.AddNode(array.Array("song").Array("pans")); // Process (vols (...)) var vols = array.Array("song").Array("vols"); var newVols = new DataArray(); newVols.AddNode(DataSymbol.Symbol("vols")); var volsArray = new DataArray(); for (int i = 0; i < vols.Array(1).Count; i++) { volsArray.AddNode(new DataAtom(vols.Array(1).Number(i) + volumeAdjustment)); } newVols.AddNode(volsArray); moggDta.AddNode(newVols); return(moggDta); }
/// <summary> /// Parses the string as DTA elements, adding each one to the given root array. /// </summary> /// <param name="data">string of DTA info</param> /// <param name="root">top-level array to add the string to</param> private static void ParseString(string data, DataArray root) { ParseState state = ParseState.whitespace; data += " "; // this ensures we parse the whole string... DataArray current = root; string tmp_literal = ""; int line = 1; for (int i = 0; i < data.Length; i++) { if (data[i] == '\uFEFF') { continue; } if (data[i] == '\n') { line++; } switch (state) { case ParseState.whitespace: switch (data[i]) { case '\'': tmp_literal = ""; state = ParseState.in_symbol; break; case '"': tmp_literal = ""; state = ParseState.in_string; break; case ';': tmp_literal = ""; state = ParseState.in_comment; break; case ' ': case '\r': case '\n': case '\t': continue; case '}': case ')': case ']': if (data[i] != current.ClosingChar || current.Parent == null) { throw new Exception($"Mismatched closing brace encountered at line {line}."); } current = current.Parent; break; case '(': current = (DataArray)current.AddNode(new DataArray()); break; case '{': current = (DataArray)current.AddNode(new DataCommand()); break; case '[': current = (DataArray)current.AddNode(new DataMacroDefinition()); break; default: state = ParseState.in_literal; tmp_literal = new string(data[i], 1); continue; } break; case ParseState.in_string: switch (data[i]) { case '"': current.AddNode(new DataAtom(tmp_literal)); state = ParseState.whitespace; break; default: tmp_literal += data[i]; continue; } break; case ParseState.in_literal: switch (data[i]) { case ' ': case '\r': case '\n': case '\t': AddLiteral(current, tmp_literal); state = ParseState.whitespace; break; case '}': case ')': case ']': AddLiteral(current, tmp_literal); if (data[i] != current.ClosingChar) { throw new Exception("Mismatched brace types encountered."); } current = current.Parent; state = ParseState.whitespace; break; case '(': AddLiteral(current, tmp_literal); current = (DataArray)current.AddNode(new DataArray()); break; case '{': AddLiteral(current, tmp_literal); current = (DataArray)current.AddNode(new DataCommand()); break; case '[': AddLiteral(current, tmp_literal); current = (DataArray)current.AddNode(new DataMacroDefinition()); break; default: tmp_literal += data[i]; continue; } break; case ParseState.in_symbol: switch (data[i]) { case ' ': case '\r': case '\n': case '\t': throw new Exception("Whitespace encountered in symbol."); case '}': case ')': case ']': current.AddNode(DataSymbol.Symbol(tmp_literal)); if (data[i] != current.ClosingChar) { throw new Exception("Mismatched brace types encountered."); } current = current.Parent; state = ParseState.whitespace; break; case '\'': current.AddNode(DataSymbol.Symbol(tmp_literal)); state = ParseState.whitespace; break; default: tmp_literal += data[i]; continue; } break; case ParseState.in_comment: switch (data[i]) { case '\r': case '\n': state = ParseState.whitespace; break; default: continue; } break; } } }
static DataArray parse_children(System.IO.Stream s, uint numChildren, DataType type = DataType.ARRAY, int version = 1) { DataArray ret = type == DataType.MACRO ? new DataMacroDefinition() : type == DataType.COMMAND ? new DataCommand() : new DataArray(); while (numChildren-- > 0) { DataType t = (DataType)s.ReadInt32LE(); switch (t) { case DataType.INT: ret.AddNode(new DataAtom(s.ReadInt32LE())); break; case DataType.FLOAT: ret.AddNode(new DataAtom(s.ReadFloat())); break; case DataType.VARIABLE: ret.AddNode(DataVariable.Var(s.ReadLengthUTF8())); break; case DataType.SYMBOL: ret.AddNode(DataSymbol.Symbol(s.ReadLengthUTF8())); break; case DataType.ARRAY: case DataType.COMMAND: case DataType.MACRO: if (version == 2) { s.Position += 4; uint nC = s.ReadUInt32LE(); ushort unk = s.ReadUInt16LE(); ret.AddNode(parse_children(s, nC, t, version)); } else if (version == 3) { s.Position += 4; ushort nC = s.ReadUInt16LE(); s.Position += 2; ret.AddNode(parse_children(s, nC, t, version)); } else { ushort nC = s.ReadUInt16LE(); // numChildren s.Position += 4; // id ret.AddNode(parse_children(s, nC, t, version)); } break; case DataType.STRING: ret.AddNode(new DataAtom(s.ReadLengthUTF8())); break; case DataType.EMPTY: s.Position += 4; break; case DataType.DEFINE: var constant = s.ReadLengthUTF8(); numChildren--; var definition = parse_children(s, 1, DataType.ARRAY, version).Array(0); ret.AddNode(new DataDefine(constant, definition)); break; case DataType.IFDEF: ret.AddNode(new DataIfDef(s.ReadLengthUTF8())); break; case DataType.IFNDEF: ret.AddNode(new DataIfNDef(s.ReadLengthUTF8())); break; case DataType.ELSE: s.Position += 4; ret.AddNode(new DataElse()); break; case DataType.ENDIF: s.Position += 4; ret.AddNode(new DataEndIf()); break; case DataType.INCLUDE: ret.AddNode(new DataInclude(s.ReadLengthUTF8())); break; case DataType.MERGE: ret.AddNode(new DataMerge(s.ReadLengthUTF8())); break; case DataType.AUTORUN: s.Position += 4; ret.AddNode(new DataAutorun()); break; case DataType.UNDEF: ret.AddNode(new DataUndef(s.ReadLengthUTF8())); break; default: throw new Exception("Unhandled DTB DataType " + Enum.GetName(typeof(DataType), t)); } } return(ret); }
/// <summary> /// Initializes a new instance of the <see cref="PdbTypeRegularStaticField"/> class. /// </summary> /// <param name="pdb">The PDB file reader.</param> /// <param name="data">Data symbol for this static field.</param> internal PdbGlobalVariable(PdbFileReader pdb, DataSymbol data) { Pdb = pdb; Data = data; }
/// <summary> /// Initializes a new instance of the <see cref="GlobalsStream"/> class. /// </summary> /// <param name="file">PDB file containing this stream.</param> /// <param name="reader">Binary stream reader.</param> public GlobalsStream(PdbFile file, IBinaryReader reader) { File = file; // Read header Header = GlobalsStreamHeader.Read(reader); if (Header.Signature != GlobalsStreamHeader.ExpectedSignature) { throw new Exception($"GSIHashHeader signature (0x{GlobalsStreamHeader.ExpectedSignature:X}) not found."); } if (Header.Version != GlobalsStreamHeader.ExpectedVersion) { throw new Exception("Encountered unsupported globals stream version."); } // Read hash records if (Header.HashRecordsSubstreamSize % GlobalsStreamHashRecord.Size != 0) { throw new Exception("Invalid hash record array size."); } if (reader.BytesRemaining < Header.HashRecordsSubstreamSize) { throw new Exception("Error reading hash records."); } GlobalsStreamHashRecord[] hashRecords = new GlobalsStreamHashRecord[Header.HashRecordsSubstreamSize / GlobalsStreamHashRecord.Size]; for (int i = 0; i < hashRecords.Length; i++) { hashRecords[i] = GlobalsStreamHashRecord.Read(reader); } HashRecords = hashRecords; // Read hash buckets if (Header.HashBucketsSubstreamSize > 0) { const uint IPHR_HASH = 4096; const uint SizeOfHROffsetCalc = 12; ulong bitmapSizeInBits = (IPHR_HASH / 32 + 1) * 32; int bitmapEntriesCount = (int)(bitmapSizeInBits / 8); if (reader.BytesRemaining < bitmapEntriesCount) { throw new Exception("Could not read a bitmap."); } byte[] hashBitmap = reader.ReadByteArray(bitmapEntriesCount); int nonEmptyBucketsCount = 0; for (int i = 0; i < hashBitmap.Length; i++) { nonEmptyBucketsCount += bitCount[hashBitmap[i]]; } if (reader.BytesRemaining < nonEmptyBucketsCount * 4) // 4 = sizeof(uint) { throw new Exception("Could not read a bitmap."); } uint[] nonEmptyBucketOffsets = reader.ReadUintArray(nonEmptyBucketsCount); GlobalsStreamHashBucket[] hashBuckets = new GlobalsStreamHashBucket[IPHR_HASH]; for (int i = 0, j = 0; i < IPHR_HASH; i++) { int byteIndex = i / 8; int bitIndex = i % 8; if ((hashBitmap[byteIndex] & (1 << bitIndex)) != 0) { uint start = nonEmptyBucketOffsets[j++] / SizeOfHROffsetCalc; uint end = j < nonEmptyBucketOffsets.Length ? nonEmptyBucketOffsets[j] / SizeOfHROffsetCalc : (uint)HashRecords.Length; hashBuckets[i] = new GlobalsStreamHashBucket { Start = (int)start, End = (int)end, }; } else { hashBuckets[i] = new GlobalsStreamHashBucket { Start = -1, End = -1, } }; } HashBuckets = hashBuckets; } Symbols = new ArrayCache <SymbolRecord>(HashRecords.Length, index => File.PdbSymbolStream.GetSymbolRecordByOffset(HashRecords[index].Offset - 1)); constantsCache = SimpleCache.CreateStruct(() => { List <ConstantSymbol> constants = new List <ConstantSymbol>(); for (int i = 0; i < Symbols.Count; i++) { ConstantSymbol constant = Symbols[i] as ConstantSymbol; if (constant != null) { constants.Add(constant); } } return(constants); }); threadLocalDataCache = SimpleCache.CreateStruct(() => { List <ThreadLocalDataSymbol> threadLocalData = new List <ThreadLocalDataSymbol>(); for (int i = 0; i < Symbols.Count; i++) { ThreadLocalDataSymbol tls = Symbols[i] as ThreadLocalDataSymbol; if (tls != null) { threadLocalData.Add(tls); } } return(threadLocalData); }); dataCache = SimpleCache.CreateStruct(() => { List <DataSymbol> data = new List <DataSymbol>(); for (int i = 0; i < Symbols.Count; i++) { DataSymbol d = Symbols[i] as DataSymbol; if (d != null) { data.Add(d); } } return(data); }); }
/// <summary> /// Reads symbol record from symbol references for the specified index. /// </summary> /// <param name="index">Index of the symbol record.</param> private SymbolRecord GetSymbol(int index) { // Since DictionaryCache is allowing only single thread to call this function, we don't need to lock reader here. SymbolRecordReference reference = references[index]; Reader.Position = reference.DataOffset; switch (reference.Kind) { case SymbolRecordKind.S_GPROC32: case SymbolRecordKind.S_LPROC32: case SymbolRecordKind.S_GPROC32_ID: case SymbolRecordKind.S_LPROC32_ID: case SymbolRecordKind.S_LPROC32_DPC: case SymbolRecordKind.S_LPROC32_DPC_ID: return(ProcedureSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_PUB32: return(Public32Symbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_CONSTANT: case SymbolRecordKind.S_MANCONSTANT: return(ConstantSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_LDATA32: case SymbolRecordKind.S_GDATA32: case SymbolRecordKind.S_LMANDATA: case SymbolRecordKind.S_GMANDATA: return(DataSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_PROCREF: case SymbolRecordKind.S_LPROCREF: return(ProcedureReferenceSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_TOKENREF: return(TokenReferenceSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_UDT: case SymbolRecordKind.S_COBOLUDT: return(UdtSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_LTHREAD32: case SymbolRecordKind.S_GTHREAD32: return(ThreadLocalDataSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_GMANPROC: case SymbolRecordKind.S_LMANPROC: return(ManagedProcedureSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_BLOCK32: return(BlockSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_OEM: return(OemSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_UNAMESPACE: return(NamespaceSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_MANSLOT: return(AttributeSlotSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_END: case SymbolRecordKind.S_INLINESITE_END: return(EndSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_ANNOTATION: return(AnnotationSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_ANNOTATIONREF: return(AnnotationReferenceSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_REGREL32: return(RegisterRelativeSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_OBJNAME: return(ObjectNameSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_COMPILE2: return(Compile2Symbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_COMPILE3: return(Compile3Symbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_ENVBLOCK: return(EnvironmentBlockSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_BUILDINFO: return(BuildInfoSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_FRAMEPROC: return(FrameProcedureSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_LABEL32: return(LabelSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_HEAPALLOCSITE: return(HeapAllocationSiteSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_CALLSITEINFO: return(CallSiteInfoSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_FRAMECOOKIE: return(FrameCookieSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_THUNK32: return(Thunk32Symbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_LOCAL: return(LocalSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_DEFRANGE_REGISTER: return(DefRangeRegisterSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_DEFRANGE_REGISTER_REL: return(DefRangeRegisterRelativeSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_DEFRANGE_SUBFIELD_REGISTER: return(DefRangeSubfieldRegisterSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_DEFRANGE_FRAMEPOINTER_REL: return(DefRangeFramePointerRelativeSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: return(DefRangeFramePointerRelativeFullScopeSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_CALLEES: case SymbolRecordKind.S_CALLERS: return(FunctionListSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); case SymbolRecordKind.S_FILESTATIC: return(FileStaticSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_TRAMPOLINE: return(TrampolineSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_SECTION: return(SectionSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_COFFGROUP: return(CoffGroupSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_EXPORT: return(ExportSymbol.Read(Reader, this, index, reference.Kind)); case SymbolRecordKind.S_INLINESITE: return(InlineSiteSymbol.Read(Reader, this, index, reference.Kind, reference.DataLen)); default: #if DEBUG throw new NotImplementedException($"Unknown reference kind: {reference.Kind}"); #else return(null); #endif } }