// Take the concatenated set of redirect URL data, parse them, and populate the master list private static bool MergeRawDataIntoMasterList(byte[] rawChunkData, ref MasterList[] masterLists, int masterListsOffset) { uint index = 0; while (rawChunkData.Length > index) { bool fIsAddChunk = false; // Read chunk type (add or sub) if ((('a' != rawChunkData[index]) && ('s' != rawChunkData[index])) || (':' != rawChunkData[index + 1])) { // Invalid file format return false; } if ('a' == rawChunkData[index]) { fIsAddChunk = true; } // Move the position marker past the "?:" index += 2; // Read chunk number uint chunkNumber = 0; if (false == GetUintFromString(rawChunkData, ref index, (byte)':', out chunkNumber)) { // Invalid file format return false; } // Pick the appropriate master list to put this data into (based on whether it's an add or sub chunk) int masterListsIndex = masterListsOffset + ((true == fIsAddChunk) ? 0 : 1); // Read size of hash prefix (not size of hash key) uint cbHashPrefix = 0; if (false == GetUintFromString(rawChunkData, ref index, (byte)':', out cbHashPrefix)) { // Invalid file format return false; } // Read size of chunk uint cbChunk = 0; if (false == GetUintFromString(rawChunkData, ref index, 0x0A, out cbChunk)) { // Invalid file format return false; } Chunk chunk = new Chunk(); // Iterate through chunk binary blob and read all hash keys // Add hash keys to dictionary uint endIndex = index + cbChunk; for (; endIndex > index; ) { // Read the host key byte[] hostKey = new byte[4]; Buffer.BlockCopy(rawChunkData, (int)index, hostKey, 0, hostKey.Length); index += (uint)hostKey.Length; HostKeyData hostKeyData = new HostKeyData(); uint prefixCount = rawChunkData[index++]; // If it's a sub chunk and there are no prefixes, then get the add chunk reference if ((false == fIsAddChunk) && (0 == prefixCount)) { hostKeyData.addChunkReference = GetBigEndianUintFromByteArray(ref rawChunkData, ref index); } else { hostKeyData.addChunkReference = 0; // Iterate through the count of hash key prefixes (and add chunk references, if this is a sub chunk) for (int prefixIndex = 0; prefixCount > prefixIndex; prefixIndex++) { uint hashPrefixAddChunkReference = 0; if (false == fIsAddChunk) { hashPrefixAddChunkReference = GetBigEndianUintFromByteArray(ref rawChunkData, ref index); } // Read the hash prefix byte[] hashPrefix = new byte[cbHashPrefix]; Buffer.BlockCopy(rawChunkData, (int)index, hashPrefix, 0, hashPrefix.Length); index += (uint)hashPrefix.Length; // Add/replace hash prefix entry to HostKeyData object if (hostKeyData.e.ContainsKey(hashPrefix)) { hostKeyData.e.Remove(hashPrefix); } hostKeyData.e.Add(hashPrefix, hashPrefixAddChunkReference); } } uint hostKeyNumber = GetLittleEndianUintFromByteArray(ref hostKey); // Add/replace chunk entry to chunk object if (chunk.e.ContainsKey(hostKeyNumber)) { chunk.e.Remove(hostKeyNumber); } chunk.e.Add(hostKeyNumber, hostKeyData); } // Add/replace chunk dictionary to master chunk list if (masterLists[masterListsIndex].e.ContainsKey(chunkNumber)) { masterLists[masterListsIndex].e.Remove(chunkNumber); } masterLists[masterListsIndex].e.Add(chunkNumber, chunk); } return true; }
// Reads the contents of this object to disk public void ReadFromDisk(BinaryReader br) { e.Clear(); int count = br.ReadInt32(); for (int index = 0; count > index; index++) { uint key = br.ReadUInt32(); HostKeyData value = new HostKeyData(); value.ReadFromDisk(br); e.Add(key, value); } }