Mercurial > hg > Database > jungle-sharp
comparison Main/jungle-main/persistent/msgpack/src/ObjectPacker.cs @ 20:1f99e150f336
fix folder and add Object Mapper.
author | Kazuma Takeda |
---|---|
date | Thu, 15 Dec 2016 22:52:48 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
19:0865819106cf | 20:1f99e150f336 |
---|---|
1 // | |
2 // Copyright 2011 Kazuki Oikawa | |
3 // | |
4 // Licensed under the Apache License, Version 2.0 (the "License"); | |
5 // you may not use this file except in compliance with the License. | |
6 // You may obtain a copy of the License at | |
7 // | |
8 // http://www.apache.org/licenses/LICENSE-2.0 | |
9 // | |
10 // Unless required by applicable law or agreed to in writing, software | |
11 // distributed under the License is distributed on an "AS IS" BASIS, | |
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 // See the License for the specific language governing permissions and | |
14 // limitations under the License. | |
15 // | |
16 | |
17 using System; | |
18 using System.Collections.Generic; | |
19 using System.IO; | |
20 using System.Reflection; | |
21 using System.Runtime.Serialization; | |
22 using System.Text; | |
23 | |
24 namespace MsgPack | |
25 { | |
26 public class ObjectPacker | |
27 { | |
28 byte[] _buf = new byte[64]; | |
29 //Encoding _encoding = Encoding.UTF8; | |
30 static Dictionary<Type, PackDelegate> PackerMapping; | |
31 static Dictionary<Type, UnpackDelegate> UnpackerMapping; | |
32 | |
33 delegate void PackDelegate (ObjectPacker packer, MsgPackWriter writer, object o); | |
34 delegate object UnpackDelegate (ObjectPacker packer, MsgPackReader reader); | |
35 | |
36 static ObjectPacker () | |
37 { | |
38 PackerMapping = new Dictionary<Type, PackDelegate> (); | |
39 UnpackerMapping = new Dictionary<Type, UnpackDelegate> (); | |
40 | |
41 PackerMapping.Add (typeof (string), StringPacker); | |
42 UnpackerMapping.Add (typeof (string), StringUnpacker); | |
43 } | |
44 | |
45 public byte[] Pack (object o) | |
46 { | |
47 using (MemoryStream ms = new MemoryStream ()) { | |
48 Pack (ms, o); | |
49 return ms.ToArray (); | |
50 } | |
51 } | |
52 | |
53 public void Pack (Stream strm, object o) | |
54 { | |
55 if (o != null && o.GetType ().IsPrimitive) | |
56 throw new NotSupportedException (); | |
57 MsgPackWriter writer = new MsgPackWriter (strm); | |
58 Pack (writer, o); | |
59 } | |
60 | |
61 void Pack (MsgPackWriter writer, object o) | |
62 { | |
63 if (o == null) { | |
64 writer.WriteNil (); | |
65 return; | |
66 } | |
67 | |
68 Type t = o.GetType (); | |
69 if (t.IsPrimitive) { | |
70 if (t.Equals (typeof (int))) writer.Write ((int)o); | |
71 else if (t.Equals (typeof (uint))) writer.Write ((uint)o); | |
72 else if (t.Equals (typeof (float))) writer.Write ((float)o); | |
73 else if (t.Equals (typeof (double))) writer.Write ((double)o); | |
74 else if (t.Equals (typeof (long))) writer.Write ((long)o); | |
75 else if (t.Equals (typeof (ulong))) writer.Write ((ulong)o); | |
76 else if (t.Equals (typeof (bool))) writer.Write ((bool)o); | |
77 else if (t.Equals (typeof (byte))) writer.Write ((byte)o); | |
78 else if (t.Equals (typeof (sbyte))) writer.Write ((sbyte)o); | |
79 else if (t.Equals (typeof (short))) writer.Write ((short)o); | |
80 else if (t.Equals (typeof (ushort))) writer.Write ((ushort)o); | |
81 else if (t.Equals (typeof (char))) writer.Write ((ushort)(char)o); | |
82 else throw new NotSupportedException (); | |
83 return; | |
84 } | |
85 | |
86 PackDelegate packer; | |
87 if (PackerMapping.TryGetValue (t, out packer)) { | |
88 packer (this, writer, o); | |
89 return; | |
90 } | |
91 | |
92 if (t.IsArray) { | |
93 Array ary = (Array)o; | |
94 writer.WriteArrayHeader (ary.Length); | |
95 for (int i = 0; i < ary.Length; i ++) | |
96 Pack (writer, ary.GetValue (i)); | |
97 return; | |
98 } | |
99 | |
100 ReflectionCacheEntry entry = ReflectionCache.Lookup (t); | |
101 writer.WriteMapHeader (entry.FieldMap.Count); | |
102 foreach (KeyValuePair<string, FieldInfo> pair in entry.FieldMap) { | |
103 writer.Write (pair.Key, _buf); | |
104 object v = pair.Value.GetValue (o); | |
105 if (pair.Value.FieldType.IsInterface && v != null) { | |
106 writer.WriteArrayHeader (2); | |
107 writer.Write (v.GetType().FullName); | |
108 } | |
109 Pack (writer, v); | |
110 } | |
111 } | |
112 | |
113 public T Unpack<T> (byte[] buf) | |
114 { | |
115 return Unpack<T> (buf, 0, buf.Length); | |
116 } | |
117 | |
118 public T Unpack<T> (byte[] buf, int offset, int size) | |
119 { | |
120 using (MemoryStream ms = new MemoryStream (buf, offset, size)) { | |
121 return Unpack<T> (ms); | |
122 } | |
123 } | |
124 | |
125 public T Unpack<T> (Stream strm) | |
126 { | |
127 if (typeof (T).IsPrimitive) | |
128 throw new NotSupportedException (); | |
129 MsgPackReader reader = new MsgPackReader (strm); | |
130 return (T)Unpack (reader, typeof (T)); | |
131 } | |
132 | |
133 public object Unpack (Type type, byte[] buf) | |
134 { | |
135 return Unpack (type, buf, 0, buf.Length); | |
136 } | |
137 | |
138 public object Unpack (Type type, byte[] buf, int offset, int size) | |
139 { | |
140 using (MemoryStream ms = new MemoryStream (buf, offset, size)) { | |
141 return Unpack (type, ms); | |
142 } | |
143 } | |
144 | |
145 public object Unpack (Type type, Stream strm) | |
146 { | |
147 if (type.IsPrimitive) | |
148 throw new NotSupportedException (); | |
149 MsgPackReader reader = new MsgPackReader (strm); | |
150 return Unpack (reader, type); | |
151 } | |
152 | |
153 object Unpack (MsgPackReader reader, Type t) | |
154 { | |
155 if (t.IsPrimitive) { | |
156 if (!reader.Read ()) throw new FormatException (); | |
157 if (t.Equals (typeof (int)) && reader.IsSigned ()) return reader.ValueSigned; | |
158 else if (t.Equals (typeof (uint)) && reader.IsUnsigned ()) return reader.ValueUnsigned; | |
159 else if (t.Equals (typeof (float)) && reader.Type == TypePrefixes.Float) return reader.ValueFloat; | |
160 else if (t.Equals (typeof (double)) && reader.Type == TypePrefixes.Double) return reader.ValueDouble; | |
161 else if (t.Equals (typeof (long))) { | |
162 if (reader.IsSigned64 ()) | |
163 return reader.ValueSigned64; | |
164 if (reader.IsSigned ()) | |
165 return (long)reader.ValueSigned; | |
166 } else if (t.Equals (typeof (ulong))) { | |
167 if (reader.IsUnsigned64 ()) | |
168 return reader.ValueUnsigned64; | |
169 if (reader.IsUnsigned ()) | |
170 return (ulong)reader.ValueUnsigned; | |
171 } else if (t.Equals (typeof (bool)) && reader.IsBoolean ()) return (reader.Type == TypePrefixes.True); | |
172 else if (t.Equals (typeof (byte)) && reader.IsUnsigned ()) return (byte)reader.ValueUnsigned; | |
173 else if (t.Equals (typeof (sbyte)) && reader.IsSigned ()) return (sbyte)reader.ValueSigned; | |
174 else if (t.Equals (typeof (short)) && reader.IsSigned ()) return (short)reader.ValueSigned; | |
175 else if (t.Equals (typeof (ushort)) && reader.IsUnsigned ()) return (ushort)reader.ValueUnsigned; | |
176 else if (t.Equals (typeof (char)) && reader.IsUnsigned ()) return (char)reader.ValueUnsigned; | |
177 else throw new NotSupportedException (); | |
178 } | |
179 | |
180 UnpackDelegate unpacker; | |
181 if (UnpackerMapping.TryGetValue (t, out unpacker)) | |
182 return unpacker (this, reader); | |
183 | |
184 if (t.IsArray) { | |
185 if (!reader.Read () || (!reader.IsArray () && reader.Type != TypePrefixes.Nil)) | |
186 throw new FormatException (); | |
187 if (reader.Type == TypePrefixes.Nil) | |
188 return null; | |
189 Type et = t.GetElementType (); | |
190 Array ary = Array.CreateInstance (et, (int)reader.Length); | |
191 for (int i = 0; i < ary.Length; i ++) | |
192 ary.SetValue (Unpack (reader, et), i); | |
193 return ary; | |
194 } | |
195 | |
196 if (!reader.Read ()) | |
197 throw new FormatException (); | |
198 if (reader.Type == TypePrefixes.Nil) | |
199 return null; | |
200 if (t.IsInterface) { | |
201 if (reader.Type != TypePrefixes.FixArray && reader.Length != 2) | |
202 throw new FormatException (); | |
203 if (!reader.Read () || !reader.IsRaw ()) | |
204 throw new FormatException (); | |
205 CheckBufferSize ((int)reader.Length); | |
206 reader.ReadValueRaw (_buf, 0, (int)reader.Length); | |
207 t = Type.GetType (Encoding.UTF8.GetString (_buf, 0, (int)reader.Length)); | |
208 if (!reader.Read () || reader.Type == TypePrefixes.Nil) | |
209 throw new FormatException (); | |
210 } | |
211 if (!reader.IsMap ()) | |
212 throw new FormatException (); | |
213 | |
214 object o = FormatterServices.GetUninitializedObject (t); | |
215 ReflectionCacheEntry entry = ReflectionCache.Lookup (t); | |
216 int members = (int)reader.Length; | |
217 for (int i = 0; i < members; i ++) { | |
218 if (!reader.Read () || !reader.IsRaw ()) | |
219 throw new FormatException (); | |
220 CheckBufferSize ((int)reader.Length); | |
221 reader.ReadValueRaw (_buf, 0, (int)reader.Length); | |
222 string name = Encoding.UTF8.GetString (_buf, 0, (int)reader.Length); | |
223 FieldInfo f; | |
224 if (!entry.FieldMap.TryGetValue (name, out f)) | |
225 throw new FormatException (); | |
226 f.SetValue (o, Unpack (reader, f.FieldType)); | |
227 } | |
228 | |
229 IDeserializationCallback callback = o as IDeserializationCallback; | |
230 if (callback != null) | |
231 callback.OnDeserialization (this); | |
232 return o; | |
233 } | |
234 | |
235 void CheckBufferSize (int size) | |
236 { | |
237 if (_buf.Length < size) | |
238 Array.Resize<byte> (ref _buf, size); | |
239 } | |
240 | |
241 static void StringPacker (ObjectPacker packer, MsgPackWriter writer, object o) | |
242 { | |
243 writer.Write (Encoding.UTF8.GetBytes ((string)o)); | |
244 } | |
245 | |
246 static object StringUnpacker (ObjectPacker packer, MsgPackReader reader) | |
247 { | |
248 if (!reader.Read ()) | |
249 throw new FormatException (); | |
250 if (reader.Type == TypePrefixes.Nil) | |
251 return null; | |
252 if (!reader.IsRaw ()) | |
253 throw new FormatException (); | |
254 packer.CheckBufferSize ((int)reader.Length); | |
255 reader.ReadValueRaw (packer._buf, 0, (int)reader.Length); | |
256 return Encoding.UTF8.GetString (packer._buf, 0, (int)reader.Length); | |
257 } | |
258 } | |
259 } |