Пример #1
0
        public static MsgPackItem Unpack(Stream stream, bool dynamicallyCompact = true, bool preservePackages = false, bool continueProcessingOnBreakingError = false, bool readUntilEof = false)
        {
            var settings = new MsgPackSettings()
            {
                DynamicallyCompact = dynamicallyCompact,
                PreservePackages   = preservePackages,
                ContinueProcessingOnBreakingError = continueProcessingOnBreakingError
            };

            if (!readUntilEof)
            {
                return(Unpack(stream, settings));
            }

            var item = Unpack(stream, settings);

            if (stream.Position == stream.Length)
            {
                return(item);
            }
            var items = new List <MsgPackItem>();

            items.Add(item);
            do
            {
                items.Add(Unpack(stream, settings));
            } while (stream.Position < stream.Length);
            return(new MpArray(settings, items));
        }
Пример #2
0
 internal MpError(MsgPackSettings settings, MsgPackItem partialItemWithNestedError) : this(settings, partialItemWithNestedError.StoredOffset, partialItemWithNestedError.TypeId,
                                                                                           string.Concat("A nested item contains an error. ", settings.ContinueProcessingOnBreakingError
 ? "Inspect the PartialItem to view the part of the message that could be read. Since the option 'ContinueProcessingOnBreakingError' is used, the 'IsBestGuess' property of each subitem will indicate if it was read before or after the error."
 : "Inspect the PartialItem to view the part of the message that could be read."))
 {
     PartialItem = partialItemWithNestedError;
 }
Пример #3
0
        protected static byte[] SwapIfLittleEndian(MsgPackSettings settings, byte[] bytes, int start, int count)
        {
            byte[] final = new byte[count];
            int    last  = count - 1;

            if (!SwapEndianChoice(settings, count))
            {
                int offset = start + last;
                for (int t = last; t >= 0; t--)
                {
                    final[t] = bytes[offset];
                    offset--;
                }
                return(final);
            }

            int c = start;

            for (int t = last; t >= 0; t--)
            {
                final[t] = bytes[c];
                c++;
            }

            return(final);
        }
Пример #4
0
        public static MsgPackItem SerializeObject(object item, MsgPackSettings settings)
        {
            if (ReferenceEquals(item, null))
            {
                return(new MpNull());
            }
            Type tType = item.GetType();

            if (MsgPackSerializer.NativelySupportedTypes.Contains(tType))
            {
                return(MsgPackItem.Pack(item, settings));
                // Maybe we should rather throw an exception here
            }
            PropertyInfo[] props = GetSerializedProps(tType);
            Dictionary <string, object> propVals = new Dictionary <string, object>(props.Length);

            for (int t = props.Length - 1; t >= 0; t--)
            {
                propVals.Add(props[t].Name, props[t].GetValue(item, null));
            }
            return(new MpMap(settings)
            {
                Value = propVals
            });
        }
Пример #5
0
        private static byte[] ToFExt4Bytes(MsgPackSettings settings, DateTime dt)
        {
            long seconds = DateTimeToEpoch(dt);
            uint sec     = (uint)seconds;

            return(SwapIfLittleEndian(settings, BitConverter.GetBytes(sec)));
        }
Пример #6
0
 public MpMap(KeyValuePair <object, object>[] val, bool dynamicallyCompact = true) : this()
 {
     _settings = new MsgPackSettings()
     {
         _dynamicallyCompact = dynamicallyCompact
     };
     value = val;
 }
Пример #7
0
        public static void Serialize <T>(T item, Stream target, MsgPackSettings settings)
        {
            MsgPackItem packed = SerializeObject(item, settings);

            byte[] buffer = packed.ToBytes();
            target.Write(buffer, 0, buffer.Length);
            return;
        }
Пример #8
0
 public MpArray(MsgPackSettings settings, List <MsgPackItem> initialPackedItems) : base(settings)
 {
     packedItems = initialPackedItems.ToArray();
     value       = new object[packedItems.Length];
     for (var i = 0; i < packedItems.Length; i++)
     {
         value[i] = packedItems[i].Value;
     }
 }
Пример #9
0
        private static MpDateTime ToExt8(MsgPackSettings settings, DateTime dt)
        {
            MpDateTime mpdt = new MpDateTime()
            {
                BaseValue = ToExt8Bytes(settings, dt),
                Value     = dt
            };

            return(mpdt);
        }
Пример #10
0
        public static MpRoot PackMultiple(MsgPackSettings settings, IEnumerable values)
        {
            MpRoot root = new MpRoot(settings);

            foreach (object item in values)
            {
                root.Add(Pack(item, settings));
            }
            return(root);
        }
Пример #11
0
        public static MpRoot PackMultiple(MsgPackSettings settings, params object[] values)
        {
            MpRoot root = new MpRoot(settings, values.Length);

            for (int t = 0; t < values.Length; t++)
            {
                root.Add(Pack(values[t], settings));
            }
            return(root);
        }
Пример #12
0
        public static DateTime ConvertExt(MsgPackSettings settings, MpExt ext)
        {
            if (ext.TypeSpecifier != -1)
            {
                throw new MsgPackException(string.Concat("The extension type ", ext.TypeSpecifier, " is not a recognised DatTime or TimeStamp, expected type -1."), ext.StoredOffset + 1, ext.TypeId);
            }

            switch (ext.TypeId)
            {
            case MsgPackTypeId.MpFExt4:
                uint seconds = BitConverter.ToUInt32(SwapIfLittleEndian(settings, (byte[])ext.Value), 0);
                return(EpochToLocalDateTime(seconds));

            case MsgPackTypeId.MpFExt8:
                byte[] bitVal = (byte[])ext.Value;

                if (BitConverter.IsLittleEndian)
                {
                    SwapIfLittleEndian(settings, bitVal, 0, 4);
                    SwapIfLittleEndian(settings, bitVal, 4, 4);
                }

                ulong bytes = BitConverter.ToUInt64(bitVal, 0);
                ulong nanoSecc;
                ulong sec;
                long  ticks;
                unchecked {
                    nanoSecc = bytes >> 34;
                    ulong mask = 0x3FFFFFFFF;
                    sec   = (bytes & mask);
                    ticks = (long)nanoSecc / 100;
                }

                DateTime ret = Zero.AddSeconds(sec).Add(new TimeSpan(ticks));
                return(ret.ToLocalTime());

            case MsgPackTypeId.MpExt8:
                byte[]   vall    = (byte[])ext.Value;
                uint     nanoSec = BitConverter.ToUInt32(SwapIfLittleEndian(settings, vall, 0, 4), 0);
                long     sc      = BitConverter.ToInt64(SwapIfLittleEndian(settings, vall, 4, 8), 0);
                long     tick    = nanoSec / 100;
                TimeSpan subSec  = TimeSpan.FromTicks(tick);
                if (sc < 0)
                {
                    return(EpochToLocalDateTime(sc) - subSec);
                }
                else
                {
                    return(EpochToLocalDateTime(sc) + subSec);
                }
            }

            throw new MsgPackException(string.Concat("The extension type with base type ", GetOfficialTypeName(ext.TypeId), " is not recognised as a DatTime or TimeStamp. expected ", GetOfficialTypeName(MsgPackTypeId.MpFExt4), " or ", GetOfficialTypeName(MsgPackTypeId.MpFExt8), " or ", GetOfficialTypeName(MsgPackTypeId.MpExt8)), ext.StoredOffset, ext.TypeId);
        }
Пример #13
0
        public static byte[] Serialize <T>(T item, MsgPackSettings settings)
        {
            if (MsgPackSerializer.NativelySupportedTypes.Contains(typeof(T)))
            {
                return(MsgPackItem.Pack(item, settings).ToBytes());
            }
            MemoryStream ms = new MemoryStream();

            Serialize(item, ms, settings);
            return(ms.ToArray());
        }
Пример #14
0
        private static byte[] ToExt8Bytes(MsgPackSettings settings, DateTime dt)
        {
            long seconds         = DateTimeToEpoch(dt);
            long ticksFractional = (dt.Ticks % TimeSpan.TicksPerSecond);
            uint nanoSec         = (uint)ticksFractional * 100;

            byte[] bitVal = new byte[12];
            SwapIfLittleEndian(settings, BitConverter.GetBytes(nanoSec)).CopyTo(bitVal, 0);
            SwapIfLittleEndian(settings, BitConverter.GetBytes(seconds)).CopyTo(bitVal, 4);
            return(bitVal);
        }
Пример #15
0
 public static bool SwapEndianChoice(MsgPackSettings settings, int length)
 {
     if (settings.EndianAction == EndianAction.NeverSwap || length <= 1)
     {
         return(false);
     }
     if (settings.EndianAction == EndianAction.SwapIfCurrentSystemIsLittleEndian && !BitConverter.IsLittleEndian)
     {
         return(false);
     }
     return(true);
 }
Пример #16
0
        public static MpDateTime FromDateTime(MsgPackSettings settings, DateTime dt, bool preserveFractionalSeconds = true)
        {
            dt = dt.ToUniversalTime();

            if (dt < Zero || dt > MaxFExt8)
            {
                return(ToExt8(settings, dt)); // lartgest 15 bytes
            }
            if (dt > MaxFExt4 || (preserveFractionalSeconds && HasFractionalSeconds(dt)))
            {
                return(ToFExt8(settings, dt)); // 10 bytes
            }
            return(ToFExt4(settings, dt));     // 6 bytes
        }
Пример #17
0
        private static byte[] ToBaseValue(MsgPackSettings settings, DateTime dt, bool preserveFractionalSeconds = true)
        {
            dt = dt.ToUniversalTime();

            if (dt < Zero || dt > MaxFExt8)
            {
                return(ToExt8Bytes(settings, dt)); // lartgest 15 bytes
            }
            if (dt > MaxFExt4 || (preserveFractionalSeconds && HasFractionalSeconds(dt)))
            {
                return(ToFExt8Bytes(settings, dt)); // 10 bytes
            }
            return(ToFExt4Bytes(settings, dt));     // 6 bytes
        }
Пример #18
0
        protected static void ReorderIfLittleEndian(MsgPackSettings settings, List <byte> bytes)
        {
            if (!SwapEndianChoice(settings, bytes.Count))
            {
                return;
            }
            byte[] swapped = new byte[bytes.Count];
            int    c       = 0;

            for (int t = swapped.Length - 1; t >= 0; t--)
            {
                swapped[t] = bytes[c];
                c++;
            }
            bytes.Clear();
            bytes.AddRange(swapped);
        }
Пример #19
0
        private static byte[] ToFExt8Bytes(MsgPackSettings settings, DateTime dt)
        {
            ulong seconds         = (ulong)DateTimeToEpoch(dt);
            long  ticksFractional = (dt.Ticks % TimeSpan.TicksPerSecond);
            ulong nanoSec         = (ulong)ticksFractional * 100;

            ulong prepareBytes = nanoSec << 34;

            prepareBytes = prepareBytes | seconds;
            byte[] bitVal = BitConverter.GetBytes(prepareBytes);
            if (BitConverter.IsLittleEndian)
            {
                SwapIfLittleEndian(settings, bitVal, 0, 4);
                SwapIfLittleEndian(settings, bitVal, 4, 4);
            }
            return(bitVal);
        }
Пример #20
0
        protected static byte[] SwapIfLittleEndian(MsgPackSettings settings, byte[] bytes)
        {
            if (!SwapEndianChoice(settings, bytes.Length))
            {
                return(bytes);
            }

            byte[] final = new byte[bytes.Length];
            int    c     = 0;

            for (int t = final.Length - 1; t >= 0; t--)
            {
                final[t] = bytes[c];
                c++;
            }

            return(final);
        }
Пример #21
0
        protected static void ReorderIfLittleEndian(MsgPackSettings settings, byte[] bytes)
        {
            if (!SwapEndianChoice(settings, bytes.Length))
            {
                return;
            }

            byte[] swapped = new byte[bytes.Length];
            int    c       = 0;

            for (int t = swapped.Length - 1; t >= 0; t--)
            {
                swapped[t] = bytes[c];
                c++;
            }
            for (int t = bytes.Length - 1; t >= 0; t--)
            {
                bytes[t] = swapped[t];
            }
        }
Пример #22
0
        public static MpRoot UnpackMultiple(Stream stream, MsgPackSettings settings)
        {
            MpRoot items = new MpRoot(settings)
            {
                storedOffset = stream.Position
            };
            long len     = stream.Length - 1;
            long lastpos = stream.Position;

            while (stream.Position < len)
            {
                try {
                    items.Add(Unpack(stream, settings));
                    lastpos = stream.Position;
                } catch (Exception ex) {
                    items.Add(new MpError(settings, ex, "Offset after parsing error is ", stream.Position)
                    {
                        storedOffset = lastpos, storedLength = stream.Position - lastpos
                    });
                    if (settings.ContinueProcessingOnBreakingError)
                    {
                        if (lastpos == stream.Position && stream.Position < len)
                        {
                            FindNextValidTypeId(stream);
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            items.storedLength = stream.Position - items.storedOffset;
            return(items);
        }
Пример #23
0
 public MpFloat(MsgPackSettings settings) : base(settings)
 {
 }
Пример #24
0
 public MpArray(MsgPackSettings settings) : base(settings)
 {
 }
Пример #25
0
        public static MsgPackItem Unpack(Stream stream, MsgPackSettings settings)
        {
            int typeByte = stream.ReadByte();

            if (typeByte < 0)
            {
                return(new MpError(settings, stream.Position, MsgPackTypeId.NeverUsed, "Unexpected end of data."));
            }
            MsgPackItem item = null;

            try {
                MsgPackTypeId type = (MsgPackTypeId)typeByte;
                switch (type)
                {
                case MsgPackTypeId.MpNull: item = new MpNull(settings); break;

                case MsgPackTypeId.MpBoolFalse:
                case MsgPackTypeId.MpBoolTrue: item = new MpBool(settings); break;

                //case MsgPackTypes.MpBytePart:
                //case MsgPackTypes.MpSBytePart:
                case MsgPackTypeId.MpSByte:
                case MsgPackTypeId.MpShort:
                case MsgPackTypeId.MpInt:
                case MsgPackTypeId.MpLong:
                case MsgPackTypeId.MpUByte:
                case MsgPackTypeId.MpUShort:
                case MsgPackTypeId.MpUInt:
                case MsgPackTypeId.MpULong: item = new MpInt(settings); break;

                case MsgPackTypeId.MpFloat:
                case MsgPackTypeId.MpDouble: item = new MpFloat(settings); break;

                //case MsgPackTypeId.MpStr5:
                case MsgPackTypeId.MpStr8:
                case MsgPackTypeId.MpStr16:
                case MsgPackTypeId.MpStr32: item = new MpString(settings); break;

                case MsgPackTypeId.MpBin8:
                case MsgPackTypeId.MpBin16:
                case MsgPackTypeId.MpBin32: item = new MpBin(settings); break;

                //case MsgPackTypeId.MpArray4:
                case MsgPackTypeId.MpArray16:
                case MsgPackTypeId.MpArray32: item = new MpArray(settings); break;

                //case MsgPackTypeId.MpMap4:
                case MsgPackTypeId.MpMap16:
                case MsgPackTypeId.MpMap32: item = new MpMap(settings); break;

                case MsgPackTypeId.MpFExt1:
                case MsgPackTypeId.MpFExt2:
                case MsgPackTypeId.MpFExt4:
                case MsgPackTypeId.MpFExt8:
                case MsgPackTypeId.MpFExt16:
                case MsgPackTypeId.MpExt8:
                case MsgPackTypeId.MpExt16:
                case MsgPackTypeId.MpExt32: item = new MpExt(settings); break;

                case MsgPackTypeId.NeverUsed:
                {
                    long pos = stream.Position - 1;
                    if (settings.ContinueProcessingOnBreakingError)
                    {
                        FindNextValidTypeId(stream);
                    }
                    return(new MpError(settings, pos, MsgPackTypeId.NeverUsed, "The specification specifically states that the value 0xC1 should never be used.")
                        {
                            storedLength = (stream.Position - pos)
                        });
                }
                }

                if (ReferenceEquals(item, null))
                {
                    if (((byte)type & 0xE0) == 0xE0 || (((byte)type & 0x80) == 0))
                    {
                        item = new MpInt(settings);
                    }
                    else if (((byte)type & 0xA0) == 0xA0)
                    {
                        item = new MpString(settings);
                    }
                    else if (((byte)type & 0x90) == 0x90)
                    {
                        item = new MpArray(settings);
                    }
                    else if (((byte)type & 0x80) == 0x80)
                    {
                        item = new MpMap(settings);
                    }
                }

                if (!ReferenceEquals(item, null))
                {
                    item.storedOffset = stream.Position - 1;
                    item._settings    = settings; // maybe redundent, but want to be sure
                    MsgPackItem ret = item.Read(type, stream);
                    item.storedLength = stream.Position - item.storedOffset;
                    if (!ReferenceEquals(item, ret))
                    {
                        ret.storedLength = item.storedLength;
                    }
                    return(ret);
                }
                else
                {
                    long pos = stream.Position - 1;
                    if (settings.ContinueProcessingOnBreakingError)
                    {
                        FindNextValidTypeId(stream);
                    }
                    return(new MpError(settings, pos, type, "The type identifier with value 0x", BitConverter.ToString(new byte[] { (byte)type }),
                                       " is either new or invalid. It is not (yet) implemented in this version of LsMsgPack.")
                    {
                        storedLength = (stream.Position - pos)
                    });
                }
            }catch (Exception ex) {
                long pos = stream.Position - 1;
                if (settings.ContinueProcessingOnBreakingError)
                {
                    FindNextValidTypeId(stream);
                }
                return(new MpError(settings, new MsgPackException("Error while reading data.", ex, stream.Position, (MsgPackTypeId)typeByte))
                {
                    storedOffset = pos,
                    storedLength = (stream.Position - pos),
                    PartialItem = item
                });
            }
        }
Пример #26
0
 public MsgPackItem(MsgPackSettings settings)
 {
     _settings    = settings;
     _isBestGuess = _settings.FileContainsErrors;
 }
Пример #27
0
        public static MsgPackItem Pack(object value, MsgPackSettings settings)
        {
            if (ReferenceEquals(value, null))
            {
                return(new MpNull(settings));
            }
            if (value is bool)
            {
                return new MpBool(settings)
                       {
                           Value = value
                       }
            }
            ;
            if (value is sbyte ||
                value is short ||
                value is int ||
                value is long ||
                value is byte ||
                value is ushort ||
                value is uint ||
                value is ulong)
            {
                return new MpInt(settings)
                       {
                           Value = value
                       }
            }
            ;
            if (value is float ||
                value is double)
            {
                return new MpFloat(settings)
                       {
                           Value = value
                       }
            }
            ;
            if (value is string)
            {
                return new MpString(settings)
                       {
                           Value = value
                       }
            }
            ;
            if (value is byte[])
            {
                return new MpBin(settings)
                       {
                           Value = value
                       }
            }
            ;
            if (value is object[])
            {
                return new MpArray(settings)
                       {
                           Value = value
                       }
            }
            ;

            Type valuesType = value.GetType();

            if (valuesType.IsEnum)
            {
                return(new MpInt(settings).SetEnumVal(value));
            }
            if (IsSubclassOfArrayOfRawGeneric(typeof(KeyValuePair <,>), valuesType))
            {
                return new MpMap(settings)
                       {
                           Value = value
                       }
            }
            ;
            if (IsSubclassOfRawGeneric(typeof(Dictionary <,>), valuesType))
            {
                return new MpMap(settings)
                       {
                           Value = value
                       }
            }
            ;
            if (valuesType.IsArray)
            {
                return new MpArray(settings)
                       {
                           Value = ((IEnumerable)value).Cast <Object>().ToArray()
                       }
            }
            ;
            if (typeof(IEnumerable).IsAssignableFrom(valuesType))
            {
                return new MpArray(settings)
                       {
                           Value = ((IEnumerable)value).Cast <Object>().ToArray()
                       }
            }
            ;

            // Extension types will come in like this most of the time:
            MsgPackItem val = value as MsgPackItem;

            if (!ReferenceEquals(val, null))
            {
                val._settings = settings;

                return(val);
            }

            return(MsgPackSerializer.SerializeObject(value, settings));
        }
Пример #28
0
 public MsgPackVarLen(MsgPackSettings settings) : base(settings)
 {
 }
Пример #29
0
 public MpBool(MsgPackSettings settings) : base(settings)
 {
 }
Пример #30
0
 public MpInt(MsgPackSettings settings) : base(settings)
 {
 }