Beispiel #1
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);
        }
Beispiel #2
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));
        }