public DwarfAbbreviationItem GetOrCreate(DwarfAbbreviationItemKey itemKey) { if (!_mapKeyToItem.TryGetValue(itemKey, out var item)) { item = new DwarfAbbreviationItem(_nextCode, itemKey.Tag, itemKey.HasChildren, itemKey.Descriptors) { Parent = this }; if (_mapItems.Count > 0) { _mapItems[_nextCode] = item; } else { _items.Add(item); } _mapKeyToItem[itemKey] = item; _nextCode++; } return(item); }
private bool TryReadNext(DwarfReader reader) { var startOffset = (ulong)reader.Offset; var code = reader.ReadULEB128(); if (code == 0) { return(false); } var item = new DwarfAbbreviationItem { Offset = startOffset, Code = code }; var index = code - 1; bool canAddToList = _mapItems.Count == 0 && index < int.MaxValue && _items.Count == (int)index; item.ReadInternal(reader); if (canAddToList) { _items.Add(item); _nextCode++; } else { if (_mapItems.Count == 0) { for (var i = 0; i < _items.Count; i++) { var previousItem = _items[i]; _mapItems.Add((ulong)i + 1, previousItem); } _items.Clear(); } // TODO: check collisions if (_mapItems.ContainsKey(code)) { reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation."); return(false); } _mapItems.Add(code, item); _nextCode = Math.Max(code, _nextCode) + 1; } var key = new DwarfAbbreviationItemKey(item.Tag, item.HasChildren, item.Descriptors); _mapKeyToItem.Add(key, item); return(true); }
public bool TryFindByCode(ulong code, out DwarfAbbreviationItem item) { item = null; if (code == 0) { return(false); } code--; if (_mapItems.Count > 0) { return(_mapItems.TryGetValue(code, out item)); } if (code < int.MaxValue && (int)code < _items.Count) { item = _items[(int)code]; return(true); } item = null; return(false); }
private bool TryReadNext(DwarfReaderWriter reader, DiagnosticBag diagnostics) { var code = reader.ReadLEB128(); if (code == 0) { return(false); } var item = new DwarfAbbreviationItem(); var index = code - 1; bool canAddToList = _mapItems == null && index < int.MaxValue && _items.Count == (int)index; item.Tag = reader.ReadLEB128As <DwarfTag>(); var hasChildrenRaw = reader.ReadU8(); bool hasChildren = false; if (hasChildrenRaw == DwarfNative.DW_CHILDREN_yes) { hasChildren = true; } else if (hasChildrenRaw != DwarfNative.DW_CHILDREN_no) { diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid children {hasChildrenRaw}. Must be either {DwarfNative.DW_CHILDREN_yes} or {DwarfNative.DW_CHILDREN_no}"); return(false); } item.Code = code; item.HasChildren = hasChildren; if (canAddToList) { _items.Add(item); } else { if (_mapItems == null) { _mapItems = new Dictionary <ulong, DwarfAbbreviationItem>(); for (var i = 0; i < _items.Count; i++) { var previousItem = _items[i]; _mapItems.Add((ulong)i + 1, previousItem); } _items.Clear(); } // TODO: check collisions if (_mapItems.ContainsKey(code)) { diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation."); return(false); } _mapItems.Add(code, item); } List <DwarfAttributeDescriptor> descriptors = null; while (true) { var attributeName = reader.ReadLEB128As <DwarfAttributeName>(); var attributeForm = reader.ReadLEB128As <DwarfAttributeForm>(); if (attributeForm.Value == 0 && attributeForm.Value == 0) { break; } if (descriptors == null) { descriptors = new List <DwarfAttributeDescriptor>(1); } descriptors.Add(new DwarfAttributeDescriptor(attributeName, attributeForm)); } if (descriptors != null) { item.Descriptors = descriptors; } return(true); }