66using System . Collections . Generic ;
77using System . Diagnostics ;
88using System . Diagnostics . CodeAnalysis ;
9+ using System . Linq ;
910using LibObjectFile . Diagnostics ;
1011
1112namespace LibObjectFile . Dwarf ;
1213
1314[ DebuggerDisplay ( "{" + nameof ( DebuggerDisplay ) + ",nq}" ) ]
1415public sealed class DwarfAbbreviation : DwarfObject < DwarfAbbreviationTable >
1516{
16- private readonly List < DwarfAbbreviationItem > _items ;
17- private readonly Dictionary < ulong , DwarfAbbreviationItem > _mapItems ; // Only used if code are non contiguous
17+ private readonly Dictionary < ulong , DwarfAbbreviationItem > _mapUlongToItems ;
18+
1819 private readonly Dictionary < DwarfAbbreviationItemKey , DwarfAbbreviationItem > _mapKeyToItem ;
1920 private ulong _nextCode ;
2021
2122 public DwarfAbbreviation ( )
2223 {
23- _items = new List < DwarfAbbreviationItem > ( ) ;
24- _mapItems = new Dictionary < ulong , DwarfAbbreviationItem > ( ) ;
24+ _mapUlongToItems = new Dictionary < ulong , DwarfAbbreviationItem > ( ) ;
2525 _mapKeyToItem = new Dictionary < DwarfAbbreviationItemKey , DwarfAbbreviationItem > ( ) ;
2626 _nextCode = 1 ;
2727 }
2828
2929 public void Reset ( )
3030 {
3131 // Reset parent dependency
32- foreach ( var dwarfAbbreviationItem in _items )
33- {
34- dwarfAbbreviationItem . Parent = null ;
35- }
36-
37- if ( _mapItems . Count > 0 )
32+ foreach ( var keyPair in _mapUlongToItems . Values )
3833 {
39- foreach ( var keyPair in _mapItems )
40- {
41- keyPair . Value . Parent = null ;
42- }
34+ keyPair . Parent = null ;
4335 }
44-
45- _items . Clear ( ) ;
46- _mapItems . Clear ( ) ;
36+ _mapUlongToItems . Clear ( ) ;
4737 _mapKeyToItem . Clear ( ) ;
4838 _nextCode = 1 ;
4939 }
5040
51- public IEnumerable < DwarfAbbreviationItem > Items => _mapItems . Count > 0 ? GetMapItems ( ) : _items ;
41+ public IEnumerable < DwarfAbbreviationItem > Items => _mapUlongToItems . Values ;
5242
53- private IEnumerable < DwarfAbbreviationItem > GetMapItems ( )
54- {
55- foreach ( var item in _mapItems . Values )
56- {
57- yield return item ;
58- }
59- }
60-
6143 public DwarfAbbreviationItem GetOrCreate ( DwarfAbbreviationItemKey itemKey )
6244 {
63- if ( ! _mapKeyToItem . TryGetValue ( itemKey , out var item ) )
45+ if ( ! TryFindByKey ( itemKey , out var item ) )
6446 {
6547 item = new DwarfAbbreviationItem ( _nextCode , itemKey . Tag , itemKey . HasChildren , itemKey . Descriptors )
6648 {
6749 Parent = this
6850 } ;
6951
70- if ( _mapItems . Count > 0 )
71- {
72-
73- _mapItems [ _nextCode ] = item ;
74- }
75- else
76- {
77- _items . Add ( item ) ;
78- }
52+ // insert or update new item
53+ _mapUlongToItems [ _nextCode ] = item ;
7954
55+ // not found insert new item
8056 _mapKeyToItem [ itemKey ] = item ;
8157
8258 _nextCode ++ ;
@@ -93,24 +69,16 @@ public bool TryFindByCode(ulong code, [NotNullWhen(true)] out DwarfAbbreviationI
9369 return false ;
9470 }
9571
96- code -- ;
97-
98- if ( _mapItems . Count > 0 )
99- {
100- return _mapItems . TryGetValue ( code , out item ) ;
101- }
102-
103- if ( code < int . MaxValue && ( int ) code < _items . Count )
104- {
105- item = _items [ ( int ) code ] ;
106- return true ;
107- }
72+ return _mapUlongToItems . TryGetValue ( code , out item ) ;
73+ }
10874
75+ public bool TryFindByKey ( DwarfAbbreviationItemKey key , [ NotNullWhen ( true ) ] out DwarfAbbreviationItem ? item )
76+ {
10977 item = null ;
110- return false ;
78+ return _mapKeyToItem . TryGetValue ( key , out item ) ;
11179 }
11280
113- private string DebuggerDisplay => $ "Count = { ( _mapItems . Count > 0 ? _mapItems . Count : _items . Count ) } ";
81+ private string DebuggerDisplay => $ "Count = { _mapUlongToItems . Count } ";
11482
11583 private bool TryReadNext ( DwarfReader reader )
11684 {
@@ -123,45 +91,27 @@ private bool TryReadNext(DwarfReader reader)
12391
12492 var item = new DwarfAbbreviationItem
12593 {
126- Position = startOffset ,
94+ Position = startOffset ,
12795 Code = code
12896 } ;
12997
130- var index = code - 1 ;
131- bool canAddToList = _mapItems . Count == 0 && index < int . MaxValue && _items . Count == ( int ) index ;
132-
13398 item . Read ( reader ) ;
13499
135- if ( canAddToList )
100+ if ( _mapUlongToItems . ContainsKey ( code ) )
136101 {
137- _items . Add ( item ) ;
138- _nextCode ++ ;
102+ reader . Diagnostics . Error ( DiagnosticId . DWARF_ERR_InvalidData , $ "Invalid code { code } found while another code already exists in this abbreviation." ) ;
103+ return false ;
139104 }
140- else
141- {
142- if ( _mapItems . Count == 0 )
143- {
144- for ( var i = 0 ; i < _items . Count ; i ++ )
145- {
146- var previousItem = _items [ i ] ;
147- _mapItems . Add ( ( ulong ) i + 1 , previousItem ) ;
148- }
149- _items . Clear ( ) ;
150- }
151-
152- // TODO: check collisions
153- if ( _mapItems . ContainsKey ( code ) )
154- {
155- reader . Diagnostics . Error ( DiagnosticId . DWARF_ERR_InvalidData , $ "Invalid code { code } found while another code already exists in this abbreviation.") ;
156- return false ;
157- }
158- _mapItems . Add ( code , item ) ;
159105
160- _nextCode = Math . Max ( code , _nextCode ) + 1 ;
161- }
106+ _mapUlongToItems . Add ( code , item ) ;
107+ _nextCode = Math . Max ( code , _nextCode ) + 1 ;
162108
163109 var key = new DwarfAbbreviationItemKey ( item . Tag , item . HasChildren , item . Descriptors ) ;
164- _mapKeyToItem . Add ( key , item ) ;
110+
111+ if ( ! _mapKeyToItem . ContainsKey ( key ) )
112+ {
113+ _mapKeyToItem . Add ( key , item ) ;
114+ }
165115
166116 return true ;
167117 }
@@ -180,24 +130,9 @@ public override void Write(DwarfWriter writer)
180130 {
181131 var startOffset = writer . Position ;
182132 Debug . Assert ( startOffset == Position ) ;
183- if ( _mapItems . Count > 0 )
133+ foreach ( var item in _mapUlongToItems . Values )
184134 {
185- foreach ( var itemPair in _mapItems )
186- {
187- var item = itemPair . Value ;
188- item . Write ( writer ) ;
189- }
190-
191- }
192- else
193- {
194- if ( _items . Count > 0 )
195- {
196- foreach ( var item in _items )
197- {
198- item . Write ( writer ) ;
199- }
200- }
135+ item . Write ( writer ) ;
201136 }
202137
203138 // End of abbreviation item
@@ -210,28 +145,11 @@ protected override void UpdateLayoutCore(DwarfLayoutContext context)
210145 {
211146 var endOffset = Position ;
212147
213- if ( _mapItems . Count > 0 )
148+ foreach ( var item in _mapUlongToItems . Values )
214149 {
215- foreach ( var itemPair in _mapItems )
216- {
217- var item = itemPair . Value ;
218- item . Position = endOffset ;
219- item . UpdateLayout ( context ) ;
220- endOffset += item . Size ;
221- }
222-
223- }
224- else
225- {
226- if ( _items . Count > 0 )
227- {
228- foreach ( var item in _items )
229- {
230- item . Position = endOffset ;
231- item . UpdateLayout ( context ) ;
232- endOffset += item . Size ;
233- }
234- }
150+ item . Position = endOffset ;
151+ item . UpdateLayout ( context ) ;
152+ endOffset += item . Size ;
235153 }
236154
237155 endOffset += DwarfHelper . SizeOfULEB128 ( 0 ) ;
0 commit comments