public void Read(ref uint id_begin, SubTableMeta subTable, Stream input) { ids = new List <List <Id> >(); long subtable_ids_begin = input.Position; uint id_count = subTable.max_id + 1; uint block_64ids_count = (id_count - 1) >> 6; ushort[] block_64ids_offsets = new ushort[block_64ids_count]; for (uint i = 0; i < block_64ids_count; ++i) { block_64ids_offsets[i] = input.ReadValueU16(); } for (uint j = 0; j < id_count; j += 64) { List <Id> ids_in_block = new List <Id>(); if (j >= 64 && j % 64 == 0) { long block_64ids_offset = block_64ids_offsets[(j >> 6) - 1]; if (block_64ids_offset == 0) { ids.Add(ids_in_block); continue; } input.Position = subtable_ids_begin + block_64ids_offset; } uint current_size_in_bits = 0; uint k = 0; while (k < Math.Min(id_count - j, 64)) { Id new_id = new Id(id_begin + j + k); new_id.Read(ref k, ref current_size_in_bits, input); ids_in_block.Add(new_id); } // Adjust offsets from the start uint delta = ((uint)(input.Position - start)) << 3; foreach (Id new_id in ids_in_block) { new_id.lo += delta; new_id.hi += delta; } ids.Add(ids_in_block); } id_begin += id_count; }
public long Read(Stream input) { first_id = input.ReadValueU32(); offset_length = input.ReadValueU32(); long save = input.Position; offset = offset_length >> 4; length = offset_length & 15; // read meta data for each subtable input.Position = offset; sub_table_metas = new SubTableMeta[length]; for (uint i = 0; i < length; ++i) { sub_table_metas[i] = new SubTableMeta(); sub_table_metas[i].Read(input); } // read ids and bit offset (lo and hi) for each subtable sub_table_ids = new SubTableIds[length]; uint block_first_id = first_id; long block_position = input.Position; for (uint i = 0; i < length; ++i) { input.Position = block_position; block_first_id += sub_table_metas[i].delta_from_prev_id; sub_table_ids[i] = new SubTableIds((uint)block_position); sub_table_ids[i].Read(ref block_first_id, sub_table_metas[i], input); block_position += sub_table_metas[i].size; } input.Position = save; return(block_position); }