javaClass_serialisation.h
Go to the documentation of this file.
1 /*
2  @copyright Russell Standish 2000-2013
3  @author Russell Standish
4  This file is part of Classdesc
5 
6  Open source licensed under the MIT license. See LICENSE for details.
7 */
8 
12 #ifndef JAVACLASS_SERIALISATION_H
13 #define JAVACLASS_SERIALISATION_H
14 
15 #include <vector>
16 #include <string>
17 #include <pack_base.h>
18 #include <dump_base.h>
19 #include "javaClass.h"
20 
21 
22 namespace classdesc
23 {
24  template <> void dump(dump_t& buf, const string& d, const u8& a)
25  {dump(buf,d,a.v);}
26  template <> void dump(dump_t& buf, const string& d, const u4& a)
27  {dump(buf,d,a.v);}
28  template <> void dump(dump_t& buf, const string& d, const u2& a)
29  {dump(buf,d,a.v);}
30  template <> void dump(dump_t& buf, const string& d, const u1& a)
31  {buf << std::hex << int(a);}
32 }
33 
34 
35 namespace classdesc_access
36 {
37 /*
38  Strings and vectors are have specialised serialisation for javaClass
39 */
40 
41  template <>
42  struct access_pack<std::string>
43  {
44  void operator()(classdesc::pack_t& buf, const classdesc::string& d, const std::string& a)
45  {
46  classdesc::u2 length=a.length();
47  pack(buf,d,length);
48  buf.packraw(a.c_str(),length);
49  }
50  };
51 
52  template <>
53  struct access_unpack<std::string>
54  {
55  template <class U>
56  void operator()(classdesc::unpack_t& buf, const classdesc::string& d, U& a)
57  {
58  classdesc::u2 length;
59  unpack(buf,d,length);
60  char *s=new char[length];
61  buf.unpackraw(s,length);
62  a=std::string(s,length);
63  delete [] s;
64  }
65  };
66 
67  template <class T>
68  struct access_pack<std::vector<T> >
69  {
70  template <class U>
71  void operator()(classdesc::pack_t& buf, const classdesc::string& d, U& a)
72  {
73  classdesc::u2 length=a.size();
74  pack(buf,d,length);
75  for (int i=0; i<length; i++)
76  pack(buf,d,a[i]);
77  }
78  };
79 
80  template <class T>
81  struct access_unpack<std::vector<T> >
82  {
83  template <class U>
84  void operator()(classdesc::unpack_t& buf, const classdesc::string& d, U& a)
85  {
86  classdesc::u2 length;
87  unpack(buf,d,length);
88  a.resize(length);
89  for (int i=0; i<length; i++)
90  unpack(buf,d,a[i]);
91  }
92  };
93 
94  template <>
96  {
97  template <class U>
98  void operator()(classdesc::unpack_t& buf, const classdesc::string& d, U& a)
99  {
100  a.v=0;
101  for (int i=0; i<8; i++)
102  {
103  classdesc::u1 b;
104  unpack(buf,d,b);
105  a.v=(a.v<<8) | (0xFF&b);
106  }
107  }
108  };
109 
110  template <>
111  struct access_pack<classdesc::u8>
112  {
113  template <class U>
114  void operator()(classdesc::pack_t& buf, const classdesc::string& d, U& a)
115  {
116  for (int i=7; i>=0; i--)
117  {
118  classdesc::u1 b = a.v >> 8*i;
119  pack(buf,d,b);
120  }
121  }
122  };
123 
124  template <>
126  {
127  template <class U>
128  void operator()(classdesc::unpack_t& buf, const classdesc::string& d, U& a)
129  {
130  a.v=0;
131  for (int i=0; i<4; i++)
132  {
133  classdesc::u1 b;
134  unpack(buf,d,b);
135  a.v=(a.v<<8) | (0xFF&b);
136  }
137  }
138  };
139 
140  template <>
141  struct access_pack<classdesc::u4>
142  {
143  void operator()(classdesc::pack_t& buf, const classdesc::string& d, const classdesc::u4& a)
144  {
145  for (int i=3; i>=0; i--)
146  {
147  classdesc::u1 b = a.v >> 8*i;
148  pack(buf,d,b);
149  }
150  }
151  };
152 
153  template <>
155  {
156  void operator()(classdesc::unpack_t& buf, const classdesc::string& d, classdesc::u2& a)
157  {
158  classdesc::u1 b1, b2;
159  unpack(buf,d,b1);
160  unpack(buf,d,b2);
161  a=(b1<<8)| (0xFF & b2);
162  }
163  };
164 
165  template <>
166  struct access_pack<classdesc::u2>
167  {
168  void operator()(classdesc::pack_t& buf, const classdesc::string& d, const classdesc::u2& a)
169  {
170  classdesc::u1 b1=a.v>>8, b2=a.v;
171  pack(buf,d,b1);
172  pack(buf,d,b2);
173  }
174  };
175 
176  template <>
177  struct access_pack<classdesc::cp_info>
178  {
179  void operator()(classdesc::pack_t& buf, const classdesc::string& d, const classdesc::cp_info& a)
180  {
181  using namespace classdesc;
182  pack(buf,d,a.tag());
183  switch (a.tag())
184  {
185  case JVM_CONSTANT_Class:
186  case JVM_CONSTANT_String:
187  pack(buf,d,a.get<u2>()); break;
188  case JVM_CONSTANT_Fieldref:
189  case JVM_CONSTANT_Methodref:
190  case JVM_CONSTANT_InterfaceMethodref:
191  pack(buf,d,a.get<Ref>()); break;
192  case JVM_CONSTANT_Integer:
193  case JVM_CONSTANT_Float:
194  pack(buf,d,a.get<u4>()); break;
195  case JVM_CONSTANT_Long:
196  case JVM_CONSTANT_Double:
197  pack(buf,d,a.get<u8>()); break;
198  case JVM_CONSTANT_NameAndType:
199  pack(buf,d,a.get<NameAndTypeInfo>());
200  break;
201  case JVM_CONSTANT_Utf8:
202  pack(buf,d,a.get<std::string>()); break;
203  }
204  }
205  };
206 
207  template <>
209  {
210  void operator()(classdesc::unpack_t& buf, const classdesc::string& d, classdesc::cp_info& a)
211  {
212  using namespace classdesc;
213  u1 tag;
214  unpack(buf,d,tag);
215  switch (tag)
216  {
217  case JVM_CONSTANT_Class:
218  case JVM_CONSTANT_String:
219  a.unpack<u2>(buf,tag); break;
220  case JVM_CONSTANT_Fieldref:
221  case JVM_CONSTANT_Methodref:
222  case JVM_CONSTANT_InterfaceMethodref:
223  a.unpack<Ref>(buf,tag); break;
224  case JVM_CONSTANT_Integer:
225  case JVM_CONSTANT_Float:
226  a.unpack<u4>(buf,tag); break;
227  case JVM_CONSTANT_Long:
228  case JVM_CONSTANT_Double:
229  a.unpack<u8>(buf,tag); break;
230  case JVM_CONSTANT_NameAndType:
231  a.unpack<NameAndTypeInfo>(buf,tag);
232  break;
233  case JVM_CONSTANT_Utf8:
234  a.unpack<std::string>(buf,tag); break;
235  }
236  }
237  };
238 
239  // The zeroth element is not serialised in the constant_pool
240  template <>
241  struct access_pack<std::vector<classdesc::cp_info> >
242  {
243  template <class U>
244  void operator()(classdesc::pack_t& buf, const classdesc::string& d, U& a)
245  {
246  classdesc::u2 size=a.size();
247  pack(buf,d,size);
248  for (int i=1; i<size; i++)
249  pack(buf,d,a[i]);
250  }
251  };
252 
253  // The zeroth element is not serialised in the constant_pool
254  template <>
255  struct access_unpack<std::vector<classdesc::cp_info> >
256  {
257  void operator()(classdesc::pack_t& buf, const classdesc::string& d, std::vector<classdesc::cp_info>& a)
258  {
259  classdesc::u2 size; unpack(buf,d,size);
260  a.resize(size);
261  for (int i=1; i<size; i++)
262  unpack(buf,d,a[i]);
263  }
264  };
265 
266  template <>
268  {
269  template<class U>
270  void operator()(classdesc::pack_t& buf, const classdesc::string& d, U& a)
271  {
272  pack(buf,d,a.attribute_name_index);
273  classdesc::u4 length=a.info.size();
274  pack(buf,d,length);
275  // need to code this explicitly as attribute length is u4 not u2
276  for (size_t i=0; i<a.info.size(); i++)
277  pack(buf,d,a.info[i]);
278  }
279  };
280 
281  template <>
283  {
284  void operator()(classdesc::pack_t& buf, const classdesc::string& d, classdesc::attribute_info& a)
285  {
286  unpack(buf,d,a.attribute_name_index);
287  classdesc::u4 length;
288  unpack(buf,d,length);
289  // need to code this explicitly as attribute length is u4 not u2
290  a.info.resize(length);
291  for (size_t i=0; i<a.info.size(); i++)
292  unpack(buf,d,a.info[i]);
293  }
294  };
295 
296 }
297 
298 /* define this here to take advantage of cp_info's serialisation operators */
299 inline bool classdesc::cp_info::operator==(const classdesc::cp_info& x) const
300 {
301  pack_t b1, b2;
302  pack(b1,string(),*this);
303  pack(b2,string(),x);
304  return b1.size()==b2.size() && memcmp(b1.data(),b2.data(),b1.size())==0;
305 }
306 
307 
308 namespace classdesc
309 {
310 
311  void dumpp(dump_t& buf, const string& d, cp_info& a)
312  {
313  switch (a.tag())
314  {
315  case JVM_CONSTANT_Class:
316  case JVM_CONSTANT_String:
317  dump(buf,d,a.get<u2>()); break;
318  case JVM_CONSTANT_Fieldref:
319  case JVM_CONSTANT_Methodref:
320  case JVM_CONSTANT_InterfaceMethodref:
321  dump(buf,d,a.get<Ref>()); break;
322  case JVM_CONSTANT_Integer:
323  dump(buf,d,a.get<int>()); break;
324  case JVM_CONSTANT_Float:
325  dump(buf,d,a.get<float>()); break;
326  case JVM_CONSTANT_Long:
327  dump(buf,d,a.get<long long>()); break;
328  case JVM_CONSTANT_Double:
329  dump(buf,d,a.get<double>()); break;
330  case JVM_CONSTANT_NameAndType:
331  dump(buf,d,a.get<NameAndTypeInfo>());
332  break;
333  case JVM_CONSTANT_Utf8:
334  dump(buf,d,a.get<std::string>()); break;
335  }
336  }
337 }
338 
339 
340 namespace classdesc
341 {
342  inline void dumpp(dump_t& targ, const string& desc,struct attribute_info& arg)
343  {
344  dump(targ,desc+".attribute_name_index",arg.attribute_name_index);
345  int tab=format(targ, desc+".info");
346  targ << std::setw(tab) << "";
347  for (u1 *c=&arg.info[0]; c!=&arg.info[0]+arg.info.size(); c++)
348  targ << " "<<std::setw(2)<<std::setfill('0')<<std::hex << int(*c);
349  targ<<std::setfill(' ')<<std::endl;
350 
351  }
352 }
353 
354 template <class T> void classdesc::cp_info::unpack(pack_t& t, u1 tag) {
355  T tmp;
356  ::unpack(t,"",tmp);
357  set(tag,tmp);
358 }
359 
360 
361 #endif
Definition: javaClass.h:67
Java classfile representation.
size_t size() const
size of buffer
Definition: pack_base.h:154
Definition: graph.h:537
serialisation descriptor
Definition: javaClass.h:643
class to allow access to private members
Definition: classdesc_access.h:21
textual representation descriptor
Definition: javaClass.h:579
class to allow access to private members
Definition: classdesc_access.h:22
Definition: javaClass.h:603
void pack(pack_t &targ, const string &desc, is_treenode dum, const T *const &arg)
serialise a tree (or DAG)
Definition: pack_graph.h:28
void dump(dump_t &o, const string &d, const T &a)
forward declare generic dump operation
Definition: dump_epilogue.h:55
const char * data() const
actual buffer
Definition: pack_base.h:152
Definition: dump_base.h:29
Definition: javaClass.h:45
Contains definitions related to classdesc functionality.
Definition: arrays.h:2514
Definition: pack_base.h:124
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition: accessor.h:55
Definition: javaClass.h:57
Definition: javaClass.h:591
void unpack(unpack_t &targ, const string &desc, is_treenode dum, T *&arg)
unserialise a tree.
Definition: pack_graph.h:44