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; } } }
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); }