// Build the hash table List <int>[] BuildHashTable(binary_library.IBinaryFile f) { int sc = f.GetSymbolCount(); int bc = CalculateBucketCount(sc); List <int>[] ht = new List <int> [bc]; for (int i = 1; i < sc; i++) { binary_library.ISymbol sym = f.GetSymbol(i); uint hash = HashFunction(sym.Name); int bucket_no = (int)(hash % (uint)bc); if (ht[bucket_no] == null) { ht[bucket_no] = new List <int>(); } ht[bucket_no].Add(i); } return(ht); }
// Write out the hash table public void Write(BinaryWriter s, binary_library.IBinaryFile f, int ver, int endian, int bitness) { long offset_to_hash_table = 0; long offset_to_file_name = 0; if (ver > 0) { // Write header long header_offset = s.BaseStream.Position; s.Write((byte)'T'); s.Write((byte)'Y'); s.Write((byte)'H'); s.Write((byte)'A'); s.Write((byte)'S'); s.Write((byte)'H'); s.Write((byte)' '); s.Write((byte)' '); s.Write((ushort)ver); s.Write((byte)endian); s.Write((byte)bitness); offset_to_hash_table = s.BaseStream.Position; s.Write((int)0); offset_to_file_name = s.BaseStream.Position; s.Write((int)0); } // Build hash table long hash_table_start = s.BaseStream.Position; List <int>[] ht = BuildHashTable(f); WriteIntPtr(s, ht.Length, bitness); WriteIntPtr(s, f.GetSymbolCount(), bitness); // Build arrays to contain the bucket and chains long[] buckets = new long[ht.Length]; long[] chains = new long[f.GetSymbolCount()]; // Iterate through each chain for (int i = 0; i < ht.Length; i++) { List <int> bucket = ht[i]; if (bucket == null) { continue; } for (int j = 0; j < bucket.Count; j++) { int chain = bucket[j]; // First entry is pointed to by bucket if (j == 0) { buckets[i] = chain; } int next_chain = 0; if (j < (bucket.Count - 1)) { next_chain = bucket[j + 1]; } chains[chain] = next_chain; } } // Write out foreach (long b in buckets) { WriteIntPtr(s, b, bitness); } foreach (long c in chains) { WriteIntPtr(s, c, bitness); } if (ver > 0) { // Point the hash table pointer to the hash table long cur_pos = s.BaseStream.Position; s.BaseStream.Seek(offset_to_hash_table, SeekOrigin.Begin); s.Write((int)hash_table_start); // Write out the input file name s.BaseStream.Seek(offset_to_file_name, SeekOrigin.Begin); s.Write((int)cur_pos); s.BaseStream.Seek(cur_pos, SeekOrigin.Begin); System.IO.FileInfo fi = new FileInfo(f.Filename); foreach (char c in fi.Name) { s.Write((byte)c); } s.Write((byte)0); } }