35 internal readonly List<ResourceDirectoryEntry> entries =
new();
36 internal int namedEntries;
46 this.ordinalOrName = ordinalOrName;
56 throw new ArgumentNullException(nameof(other));
58 this.ordinalOrName = other.ordinalOrName;
60 this.namedEntries = other.namedEntries;
66 public int Count => entries.Count;
77 foreach (var entry
in entries)
78 if (entry.ordinalOrName.Equals(
id))
85 for (var i = namedEntries; i < entries.Count; i++)
87 if (entries[i].ordinalOrName.IsGreaterThan(
id))
89 entries.Insert(i, newEntry);
94 entries.Add(newEntry);
99 for (
int i = 0; i < namedEntries; i++)
101 if (entries[i].ordinalOrName.IsGreaterThan(
id))
103 entries.Insert(i, newEntry);
109 entries.Insert(namedEntries++, newEntry);
125 var length = 16 + entries.Count * 8;
126 foreach (var entry
in entries)
127 length += entry.DirectoryLength;
134 internal void Write(ByteBuffer bb, List<int> linkOffsets)
136 if (entries.Count != 0)
138 var stringTableOffset = DirectoryLength;
139 var strings =
new Dictionary<string, int>();
140 var stringTable =
new ByteBuffer(16);
141 int offset = 16 + entries.Count * 8;
142 for (
int pass = 0; pass < 3; pass++)
143 Write(bb, pass, 0,
ref offset, strings,
ref stringTableOffset, stringTable);
147 stringTable.Align(4);
148 offset += stringTable.Length;
149 WriteResourceDataEntries(bb, linkOffsets,
ref offset);
150 bb.Write(stringTable);
155 void WriteResourceDataEntries(ByteBuffer bb, List<int> linkOffsets,
ref int offset)
157 foreach (var entry
in entries)
159 if (entry.data !=
null)
161 linkOffsets.Add(bb.Position);
163 bb.Write(entry.data.Length);
166 offset += (entry.data.Length + 3) & ~3;
170 entry.WriteResourceDataEntries(bb, linkOffsets,
ref offset);
175 void WriteData(ByteBuffer bb)
177 foreach (var entry
in entries)
179 if (entry.data !=
null)
181 bb.Write(entry.data);
191 void Write(ByteBuffer bb,
int writeDepth,
int currentDepth,
ref int offset, Dictionary<string, int> strings,
ref int stringTableOffset, ByteBuffer stringTable)
193 if (currentDepth == writeDepth)
199 bb.Write((ushort)namedEntries);
200 bb.Write((ushort)(entries.Count - namedEntries));
203 foreach (var entry
in entries)
205 if (currentDepth == writeDepth)
206 entry.WriteEntry(bb,
ref offset, strings,
ref stringTableOffset, stringTable);
208 entry.Write(bb, writeDepth, currentDepth + 1,
ref offset, strings,
ref stringTableOffset, stringTable);
212 void WriteEntry(ByteBuffer bb,
ref int offset, Dictionary<string, int> strings,
ref int stringTableOffset, ByteBuffer stringTable)
214 WriteNameOrOrdinal(bb, ordinalOrName, strings,
ref stringTableOffset, stringTable);
216 bb.Write(0x80000000U | (uint)offset);
220 offset += 16 + entries.Count * 8;
223 static void WriteNameOrOrdinal(ByteBuffer bb,
OrdinalOrName id, Dictionary<string, int> strings,
ref int stringTableOffset, ByteBuffer stringTable)
227 bb.Write((
int)
id.Ordinal);
231 if (strings.TryGetValue(
id.Name, out var stringOffset) ==
false)
233 stringOffset = stringTableOffset;
234 strings.Add(
id.
Name, stringOffset);
235 stringTableOffset += id.Name.Length * 2 + 2;
236 stringTable.Write((ushort)
id.
Name.Length);
237 foreach (var c
in id.
Name)
238 stringTable.Write((
short)c);
241 bb.Write(0x80000000U | (uint)stringOffset);