private static Metadata readMetadataTable(FileStream metadataStream, int offset)
        {
            MetadataTableInfo           info  = readMetadataTableInfo(metadataStream, offset);
            List <Tuple <int, byte[]> > table = new List <Tuple <int, byte[]> >();
            int offs_acc = info.tableOffset.value;

            for (int i = 0; i < info.numEntries; i++)
            {
                table.Add(readMetadataEntry(metadataStream, offs_acc));
                offs_acc += metadataStream.ReadInt(offs_acc) + 4;
                offs_acc  = HexTools.align(offs_acc); //word align
            }
            Metadata ret = new Metadata();

            ret.data = table;
            ret.info = info;
            return(ret);
        }
        public void writeMetadata()
        {
            //metadataStream.Seek(0, SeekOrigin.Begin);

            //TODO
            //Load all tables into RAM, erase the file, rewrite all the tables.
            mainTable.info.numEntries = tables.Count;

            metadataStream = File.Open(metadataPath, FileMode.Open);

            MetadataTableInfo[] tableInfo = new MetadataTableInfo[tables.Count];
            var myData = new List <Metadata>();

            foreach (var table in tables)
            {
                myData.Add(table.Value);
            }

            for (int i = 0; i < tables.Count; i++)
            {
                tableInfo[i] = myData[i].info;
            }
            int [] tableInfoOffsets = new int[myData.Count];

            int offs_acc = TABLE_INFO_SIZE;

            for (int i = 0; i < myData.Count; i++)
            {
                tableInfoOffsets[i] = offs_acc;
                MetadataTableInfo curTable;
                curTable  = myData[i].info;
                offs_acc += TABLE_INFO_SIZE;
            }

            mainTable.info.tableOffset = new Pointer(offs_acc); //start of main data
            //mainTable.data = new List<Tuple<int, byte[]>>();

            //now write the main table
            for (int i = 0; i < myData.Count; i++)
            {
                metadataStream.WriteInt(4, offs_acc);
                offs_acc += 4;
                metadataStream.WriteInt(tableInfoOffsets[i], offs_acc);
                offs_acc += 4;
                //mainTable.data.Add(Tuple.Create(4, BitConverter.GetBytes(tableInfoOffsets[i])));
            }

            //now write all the other tables' data
            for (int i = 0; i < myData.Count; i++)
            {
                tableInfo[i].tableOffset = new Pointer(offs_acc);
                for (int j = 0; j < myData[i].data.Count; j++)
                {
                    int len = myData[i].data[j].Item1;
                    metadataStream.WriteInt(len, offs_acc); //length
                    offs_acc += 4;
                    metadataStream.Seek(offs_acc, SeekOrigin.Begin);
                    metadataStream.Write(myData[i].data[j].Item2, 0, len);
                    offs_acc += len;
                    int align_diff = HexTools.align(offs_acc) - offs_acc;
                    if (align_diff != 0)
                    {
                        byte[] alignment = new byte[align_diff];
                        Array.Clear(alignment, 0, align_diff);
                        metadataStream.Write(alignment, 0, align_diff);
                    }
                    offs_acc += align_diff;
                }
            }
            metadataStream.SetLength(offs_acc);

            //now go back to the top and write all the table data
            writeMetadataTableInfo(metadataStream, mainTable.info, 0);
            offs_acc = TABLE_INFO_SIZE;

            for (int i = 0; i < myData.Count; i++)
            {
                writeMetadataTableInfo(metadataStream, tableInfo[i], offs_acc);
                offs_acc += TABLE_INFO_SIZE;
            }

            mainTable = readMetadataTable(metadataStream, 0);

            metadataStream.Flush();
            metadataStream.Close();

            //And we're done.


            //All headers, then all data
            //TableData1, TableData2, TableData3, . . .
            //length, dataaaaaaaaaaaa; length, dataaaaaaaaaaaaa, . . .
        }