Пример #1
0
        public override UnprocessedChunk Unprocess(int chunkid)
        {
            byte[] data = new byte [Length];
            BitConv.ToInt16(data, 0, Magic);
            BitConv.ToInt16(data, 2, Type);
            BitConv.ToInt32(data, 4, chunkid);
            BitConv.ToInt32(data, 8, entries.Count);
            // Checksum is here, but calculated later
            int offset = 20 + entries.Count * 4;

            for (int i = 0; i < entries.Count; i++)
            {
                UnprocessedEntry entry     = entries[i].Unprocess();
                byte[]           entrydata = entry.Save();
                offset += entry.HeaderLength;
                Aligner.Align(ref offset, Alignment);
                offset -= entry.HeaderLength;
                if (offset + entrydata.Length > Length)
                {
                    throw new PackingException();
                }
                BitConv.ToInt32(data, 16 + i * 4, offset);
                entrydata.CopyTo(data, offset);
                offset += entrydata.Length;
            }
            BitConv.ToInt32(data, 16 + entries.Count * 4, offset);
            int checksum = CalculateChecksum(data);

            BitConv.ToInt32(data, 12, checksum);
            return(new UnprocessedChunk(data));
        }
Пример #2
0
        public override byte[] Save()
        {
            int length = 20 + Items.Count * 4;

            Aligner.Align(ref length, 4);
            foreach (byte[] item in Items)
            {
                length += item.Length;
                Aligner.Align(ref length, 4);
            }
            byte[] data = new byte [length];
            BitConv.ToInt32(data, 0, Magic);
            BitConv.ToInt32(data, 4, EID);
            BitConv.ToInt32(data, 8, Type);
            BitConv.ToInt32(data, 12, Items.Count);
            int offset = 20 + Items.Count * 4;

            Aligner.Align(ref offset, 4);
            BitConv.ToInt32(data, 16, offset);
            for (int i = 0; i < Items.Count; i++)
            {
                Items[i].CopyTo(data, offset);
                offset += Items[i].Length;
                Aligner.Align(ref offset, 4);
                BitConv.ToInt32(data, 20 + i * 4, offset);
            }
            return(data);
        }
Пример #3
0
        public override byte[] Save()
        {
            if (rows.Count == 0)
            {
                return(new byte [0]);
            }
            int length;

            if (IsSparse)
            {
                length = rows.Count * 2;
            }
            else
            {
                length = 2;
            }
            if (HasMetaValues)
            {
                length += rows.Count * 2;
            }
            Aligner.Align(ref length, 4);
            foreach (EntityPropertyRow <T> row in rows)
            {
                length += row.Values.Count * ElementSize;
            }
            Aligner.Align(ref length, 4);
            byte[] data   = new byte [length];
            int    offset = 0;

            if (IsSparse)
            {
                foreach (EntityPropertyRow <T> row in rows)
                {
                    BitConv.ToInt16(data, offset, (short)row.Values.Count);
                    offset += 2;
                }
            }
            else
            {
                BitConv.ToInt16(data, offset, (short)rows[0].Values.Count);
                offset += 2;
            }
            if (HasMetaValues)
            {
                foreach (EntityPropertyRow <T> row in rows)
                {
                    if (!row.MetaValue.HasValue)
                    {
                        throw new InvalidOperationException("EntityPropertyRow MetaValues must be consistently present or non-present.");
                    }
                    BitConv.ToInt16(data, offset, row.MetaValue.Value);
                    offset += 2;
                }
            }
            Aligner.Align(ref offset, 4);
            byte[] elementdata = new byte [ElementSize];
            foreach (EntityPropertyRow <T> row in rows)
            {
                foreach (T value in row.Values)
                {
                    SaveElement(elementdata, value);
                    elementdata.CopyTo(data, offset);
                    offset += ElementSize;
                }
            }
            return(data);
        }
Пример #4
0
        public sealed override EntityProperty Load(byte elementsize, short unknown, bool issparse, bool hasmetavalues, byte[] data)
        {
            if (elementsize != ElementSize)
            {
                ErrorManager.SignalError("EntityProperty: Element size is wrong");
            }
            if (unknown < 0)
            {
                ErrorManager.SignalError("EntityProperty: Unknown value is invalid");
            }
            List <EntityPropertyRow <T> > rows = new List <EntityPropertyRow <T> >();

            for (int i = 0; i < unknown; i++)
            {
                rows.Add(new EntityPropertyRow <T>());
            }
            int offset = 0;

            if (issparse)
            {
                if (offset + 2 * unknown > data.Length)
                {
                    ErrorManager.SignalError("EntityProperty: Not enough data");
                }
                foreach (EntityPropertyRow <T> row in rows)
                {
                    int valuecount = (ushort)BitConv.FromInt16(data, offset);
                    offset += 2;
                    for (int i = 0; i < valuecount; i++)
                    {
                        row.Values.Add(new T());
                    }
                }
            }
            else
            {
                if (offset + 2 > data.Length)
                {
                    ErrorManager.SignalError("EntityProperty: Not enough data");
                }
                int valuecount = (ushort)BitConv.FromInt16(data, offset);
                offset += 2;
                foreach (EntityPropertyRow <T> row in rows)
                {
                    for (int i = 0; i < valuecount; i++)
                    {
                        row.Values.Add(new T());
                    }
                }
            }
            if (hasmetavalues)
            {
                if (offset + 2 * unknown > data.Length)
                {
                    ErrorManager.SignalError("EntityProperty: Not enough data");
                }
                foreach (EntityPropertyRow <T> row in rows)
                {
                    short metavalue = BitConv.FromInt16(data, offset);
                    offset       += 2;
                    row.MetaValue = metavalue;
                }
            }
            Aligner.Align(ref offset, 4);
            byte[] elementdata = new byte [elementsize];
            foreach (EntityPropertyRow <T> row in rows)
            {
                if (offset + row.Values.Count * elementsize > data.Length)
                {
                    ErrorManager.SignalError("EntityProperty: Not enough data");
                }
                for (int i = 0; i < row.Values.Count; i++)
                {
                    Array.Copy(data, offset, elementdata, 0, elementsize);
                    offset       += elementsize;
                    row.Values[i] = LoadElement(elementdata);
                }
            }
            Aligner.Align(ref offset, 4);
            if (offset != data.Length)
            {
                ErrorManager.SignalIgnorableError("EntityProperty: More data than expected");
            }
            return(Load(rows));
        }