예제 #1
0
        public static MsgPackItem Unpack(Stream stream)
        {
            int typeByte = stream.ReadByte();

            if (typeByte < 0)
            {
                throw new MsgPackException("Unexpected end of data.", stream.Position);
            }
            MsgPackItem item = null;

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

                case MsgPackTypeId.MpBoolFalse:
                case MsgPackTypeId.MpBoolTrue: item = new MpBool(); 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(); break;

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

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

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

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

                //case MsgPackTypeId.MpMap4:
                case MsgPackTypeId.MpMap16:
                case MsgPackTypeId.MpMap32: item = new MpMap(); 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(); break;

                case MsgPackTypeId.NeverUsed: throw new MsgPackException("The specification specifically states that the value 0xC1 should never be used.",
                                                                         stream.Position - 1, MsgPackTypeId.NeverUsed);
                }

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

                if (!ReferenceEquals(item, null))
                {
                    return(item.Read(type, stream));
                }
                else
                {
                    throw new MsgPackException(string.Concat("The type identifier with value 0x", ((int)type).ToString("X"),
                                                             " is either new or invalid. It is not (yet) implemented in this version of LsMsgPack."), stream.Position, type);
                }
            }catch (Exception ex) {
                if (!(ex is MsgPackException))
                {
                    MsgPackException mpex = new MsgPackException("Error while reading data.", ex, stream.Position, (MsgPackTypeId)typeByte);
                    throw mpex;
                }
                else
                {
                    throw;
                }
            }
        }
예제 #2
0
        private static object Materialize(Type tType, MpMap map)
        {
            PropertyInfo[] props    = GetSerializedProps(tType);
            KeyValuePair[] propVals = (KeyValuePair[])map.Value;

            object result = tType.CreateInstance();

            for (int t = props.Length - 1; t >= 0; t--)
            {
                object val;
                if (propVals.TryGetValue(props[t].Name, out val))
                {
                    Type propType = props[t].PropertyType;
                    if (!ReferenceEquals(val, null))
                    {
                        if (!MsgPackSerializer.NativelySupportedTypes.Contains(propType) &&
                            val is KeyValuePair[])
                        {
                            val = Materialize(propType, new MpMap((KeyValuePair[])val));
                        }
                        if (propType.IsArray && !(propType == typeof(object)))
                        {
                            // Need to cast object[] to whatever[]
                            object[] valAsArr         = (object[])val;
                            Type     arrayElementType = propType.GetElementType();
                            //Array newInstance = Array.CreateInstance(propType, valAsArr.Length);
                            ArrayList newInstance = new ArrayList();

                            // Part of the check for complex types can be done outside the loop
                            bool complexTypes = !MsgPackSerializer.NativelySupportedTypes.Contains(arrayElementType);
                            bool intType      = MsgPackMeta.NativeIntTypeFamily.Contains(arrayElementType);
                            for (int i = 0; i < valAsArr.Length; i++)
                            {
                                if (complexTypes && !ReferenceEquals(valAsArr[i], null) &&
                                    valAsArr[i] is KeyValuePair[])
                                {
                                    valAsArr[i] = Materialize(arrayElementType, new MpMap((KeyValuePair[])valAsArr[i]));
                                }
                                else if (intType)
                                {
                                    valAsArr[i] = MpInt.CovertIntType(arrayElementType, valAsArr[i]);
                                }
                                //newInstance.SetValue(valAsArr[i], i); // <- Got stuck on this one, using ArrayList instead.
                                newInstance.Add(valAsArr[i]);
                            }

                            props[t].SetValue(result, newInstance.ToArray(arrayElementType), null);
                            continue;
                        }
                        if (propType.IsInstanceOfType(typeof(IList)))
                        {
                            IList newInstance = (IList)propType.CreateInstance();

                            object[] valAsArr = (object[])val;

                            // Part of the check for complex types can be done outside the loop
                            bool complexTypes = !MsgPackSerializer.NativelySupportedTypes.Contains(propType);
                            bool intType      = MsgPackMeta.NativeIntTypeFamily.Contains(propType);
                            for (int i = 0; i < valAsArr.Length; i++)
                            {
                                if (complexTypes && !ReferenceEquals(valAsArr[i], null) &&
                                    valAsArr[i] is KeyValuePair[])
                                {
                                    valAsArr[i] = Materialize(propType, new MpMap((KeyValuePair[])valAsArr[i]));
                                }
                                else if (intType)
                                {
                                    valAsArr[i] = MpInt.CovertIntType(propType, valAsArr[i]);
                                }
                                newInstance.Add(valAsArr[i]);
                            }
                            props[t].SetValue(result, newInstance, null);
                            continue;
                        }
                        if (MsgPackMeta.NativeIntTypeFamily.Contains(propType))
                        {
                            val = MpInt.CovertIntType(propType, val);
                        }
                    }
                    props[t].SetValue(result, val, null);
                }
            }

            return(result);
        }