Ejemplo n.º 1
0
        private void WriteStringTableTo(UtfHeader header, Stream bufferStream)
        {
            bufferStream.Seek(header.StringTableOffset, SeekOrigin.Begin);
            bufferStream.WriteBytes(TableNameBytesCache);

            var row0 = Rows[0];

            foreach (var fieldImage in row0)
            {
                bufferStream.WriteBytes(fieldImage.NameBytesCache);
            }

            foreach (var fieldImage in row0)
            {
                if ((fieldImage.Storage == ColumnStorage.Constant || fieldImage.Storage == ColumnStorage.Constant2) && fieldImage.Type == ColumnType.String)
                {
                    bufferStream.WriteBytes(fieldImage.StringValueBytesCache);
                }
            }

            foreach (var row in Rows)
            {
                foreach (var fieldImage in row)
                {
                    if (fieldImage.Type == ColumnType.String && fieldImage.Storage == ColumnStorage.PerRow)
                    {
                        bufferStream.WriteBytes(fieldImage.StringValueBytesCache);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private void WriteExtraDataTo(UtfHeader header, Stream bufferStream)
        {
            var baseOffset = header.ExtraDataOffset;

            for (var i = 0; i < Rows.Count; ++i)
            {
                var row = Rows[i];

                foreach (var fieldImage in row)
                {
                    if (fieldImage.Type == ColumnType.Data)
                    {
                        var shouldWrite = false;

                        switch (fieldImage.Storage)
                        {
                        case ColumnStorage.Constant:
                        case ColumnStorage.Constant2:
                            shouldWrite = i == 0;
                            break;

                        case ColumnStorage.PerRow:
                            shouldWrite = true;
                            break;
                        }

                        if (shouldWrite && fieldImage.DataValue.Length > 0)
                        {
                            bufferStream.SeekAndWriteBytes(fieldImage.DataValue, baseOffset + fieldImage.DataOffset);
                        }
                    }
                }
            }
        }
        private uint GetExtraDataSize(UtfHeader header, out UtfFieldImage[] orderedDataFieldImages)
        {
            var  baseOffset = header.ExtraDataOffset;
            uint totalSize  = 0;

            var fieldImagesInNewOrder = new List <UtfFieldImage>();
            var row0 = Rows[0];
            var firstTableDataFieldIndex = -1;

            foreach (var fieldImage in row0)
            {
                if (fieldImage.Type == ColumnType.Data && (fieldImage.Storage == ColumnStorage.Constant || fieldImage.Storage == ColumnStorage.Constant2))
                {
                    AddToNewOrdererdDataFieldList(fieldImagesInNewOrder, fieldImage, ref firstTableDataFieldIndex);
                }
            }

            foreach (var row in Rows)
            {
                foreach (var fieldImage in row)
                {
                    if (fieldImage.Type == ColumnType.Data && fieldImage.Storage == ColumnStorage.PerRow)
                    {
                        AddToNewOrdererdDataFieldList(fieldImagesInNewOrder, fieldImage, ref firstTableDataFieldIndex);
                    }
                }
            }

            // If the first field is a table, rebase the whole data field.
            if (firstTableDataFieldIndex == 0)
            {
                baseOffset             = SerializationHelper.RoundUpAsTable(baseOffset, Alignment);
                header.ExtraDataOffset = baseOffset;
            }

            orderedDataFieldImages = fieldImagesInNewOrder.ToArray();

            foreach (var fieldImage in orderedDataFieldImages)
            {
                var rawOffset = baseOffset;

                // Tables' starting locations are rounded by Alignment (usually 0x20).
                if (fieldImage.IsTable && fieldImage.DataValue.Length > 0)
                {
                    baseOffset = SerializationHelper.RoundUpAsTable(baseOffset, Alignment);
                }

                baseOffset += (uint)fieldImage.DataValue.Length;

                // Tables' ending locations are rounded by 4.
                if (fieldImage.IsTable && fieldImage.DataValue.Length > 0)
                {
                    baseOffset = AcbHelper.RoundUpToAlignment(baseOffset, 4);
                }

                totalSize += (baseOffset - rawOffset);
            }

            return(totalSize);
        }
Ejemplo n.º 4
0
 private static void WriteHeaderTo(UtfHeader header, Stream bufferStream)
 {
     bufferStream.SeekAndWriteBytes(UtfTable.UtfSignature, 0);
     bufferStream.SeekAndWriteUInt32BE(header.TableSize - 8, 4);
     bufferStream.SeekAndWriteUInt16BE(header.Unknown1, 8);
     bufferStream.SeekAndWriteUInt16BE((ushort)(header.PerRowDataOffset - 8), 10);
     bufferStream.SeekAndWriteUInt32BE(header.StringTableOffset - 8, 12);
     bufferStream.SeekAndWriteUInt32BE(header.ExtraDataOffset - 8, 16);
     bufferStream.SeekAndWriteUInt32BE(header.TableNameOffset, 20);
     bufferStream.SeekAndWriteUInt16BE(header.FieldCount, 24);
     bufferStream.SeekAndWriteUInt16BE(header.RowSize, 26);
     bufferStream.SeekAndWriteUInt32BE(header.RowCount, 28);
 }
 private void WritePerRowDataTo(UtfHeader header, Stream bufferStream)
 {
     bufferStream.Seek(header.PerRowDataOffset, SeekOrigin.Begin);
     foreach (var row in Rows)
     {
         foreach (var fieldImage in row)
         {
             if (fieldImage.Storage == ColumnStorage.PerRow)
             {
                 fieldImage.WriteValueTo(bufferStream);
             }
         }
     }
 }
        private void WriteFieldDescriptorsTo(UtfHeader header, Stream bufferStream)
        {
            bufferStream.Seek(SchemaOffset, SeekOrigin.Begin);
            var row = Rows[0];

            foreach (var fieldImage in row)
            {
                bufferStream.WriteByte((byte)((byte)fieldImage.Storage | (byte)fieldImage.Type));
                bufferStream.WriteUInt32BE(fieldImage.NameOffset);
                if (fieldImage.Storage == ColumnStorage.Constant || fieldImage.Storage == ColumnStorage.Constant2)
                {
                    fieldImage.WriteValueTo(bufferStream);
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Some fields are not filled.
        /// </summary>
        /// <returns></returns>
        public UtfHeader GetHeader(out UtfFieldImage[] orderedDataFieldImages)
        {
            // Basic information
            if (Rows.Count < 1)
            {
                throw new InvalidOperationException("Rows should not be empty.");
            }

            var fieldCount = Rows[0].Count;

            for (var i = 1; i < Rows.Count; ++i)
            {
                if (Rows[i].Count != fieldCount)
                {
                    throw new InvalidOperationException("Number of fields in each row do not match.");
                }
            }

            var singleRowDataSize = GetSingleRowDataSize();
            var rowDescriptorSize = GetRowDescriptorSize();

            var header = new UtfHeader {
                TableName        = TableName,
                RowCount         = (uint)Rows.Count,
                FieldCount       = (ushort)fieldCount,
                Unknown1         = 1,
                RowSize          = singleRowDataSize,
                PerRowDataOffset = rowDescriptorSize + SchemaOffset // "per row" data offset, actually
            };

            var perRowDataSize = header.RowCount * header.RowSize;

            header.StringTableOffset = header.PerRowDataOffset + perRowDataSize;
            header.TableNameOffset   = 0;

            var stringTableSize = GetStringTableSize();

            header.ExtraDataOffset = header.StringTableOffset + stringTableSize;

            var extraDataSize = GetExtraDataSize(header, out orderedDataFieldImages);

            header.TableSize = header.ExtraDataOffset + extraDataSize;

            // ???
            header.TableSize = AcbHelper.RoundUpToAlignment(header.TableSize, 4);

            return(header);
        }
Ejemplo n.º 8
0
        private void SetExtraDataFieldRelocations(UtfHeader header, UtfFieldImage[] orderedFieldImages)
        {
            // This value is already calibrated in GetExtraDataSize(). It will move to a mod16 position if the first item is a table.
            var baseOffset    = header.ExtraDataOffset;
            var currentOffset = baseOffset;

            foreach (var fieldImage in orderedFieldImages)
            {
                if (fieldImage.DataValue.Length > 0)
                {
                    // For priority, see AddToNewOrderedDataFieldList().
                    if (fieldImage.IsTable)
                    {
                        currentOffset = SerializationHelper.RoundUpAsTable(currentOffset, Alignment);
                    }

                    fieldImage.DataOffset = currentOffset - baseOffset;

                    currentOffset += (uint)fieldImage.DataValue.Length;

                    // Extra 4-byte alignment at the end of tables.
                    if (fieldImage.IsTable)
                    {
                        currentOffset = AcbHelper.RoundUpToAlignment(currentOffset, Alignment);
                    }
                }
                else
                {
                    fieldImage.DataOffset = 0;
                }
            }

            var row0 = Rows[0];

            for (var i = 1; i < Rows.Count; ++i)
            {
                for (var j = 0; j < Rows[i].Count; ++j)
                {
                    var fieldImage = Rows[i][j];

                    if (fieldImage.Type == ColumnType.Data && (fieldImage.Storage == ColumnStorage.Constant || fieldImage.Storage == ColumnStorage.Constant2))
                    {
                        fieldImage.DataOffset = row0[j].DataOffset;
                    }
                }
            }
        }
Ejemplo n.º 9
0
        private void SetStringFieldRelocations(UtfHeader header)
        {
            // String table
            var currentStringTableOffset = (uint)TableNameBytesCache.Length;
            var row0 = Rows[0];

            // Field names and static strings
            foreach (var fieldImage in row0)
            {
                fieldImage.NameOffset     = currentStringTableOffset;
                currentStringTableOffset += (uint)fieldImage.NameBytesCache.Length;
            }

            foreach (var fieldImage in row0)
            {
                switch (fieldImage.Storage)
                {
                case ColumnStorage.Constant:
                case ColumnStorage.Constant2:
                    if (fieldImage.Type == ColumnType.String)
                    {
                        fieldImage.StringOffset   = currentStringTableOffset;
                        currentStringTableOffset += (uint)fieldImage.StringValueBytesCache.Length;
                    }
                    break;
                }
            }

            for (var i = 1; i < Rows.Count; ++i)
            {
                for (var j = 0; j < Rows[i].Count; ++j)
                {
                    var fieldImage = Rows[i][j];

                    fieldImage.NameOffset = row0[j].NameOffset;

                    switch (fieldImage.Storage)
                    {
                    case ColumnStorage.Constant:
                    case ColumnStorage.Constant2:
                        if (fieldImage.Type == ColumnType.String)
                        {
                            fieldImage.StringOffset = row0[j].StringOffset;
                        }
                        break;
                    }
                }
            }

            // Per-row strings
            foreach (var r in Rows)
            {
                foreach (var fieldImage in r)
                {
                    if (fieldImage.Storage == ColumnStorage.PerRow && fieldImage.Type == ColumnType.String)
                    {
                        fieldImage.StringOffset   = currentStringTableOffset;
                        currentStringTableOffset += (uint)fieldImage.StringValueBytesCache.Length;
                    }
                }
            }
        }