EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
PyXMLGenerator.cpp
Go to the documentation of this file.
1 /*
2  ------------------------------------------------------------------------------------
3  LICENSE:
4  ------------------------------------------------------------------------------------
5  This file is part of EVEmu: EVE Online Server Emulator
6  Copyright 2006 - 2021 The EVEmu Team
7  For the latest information visit https://evemu.dev
8  ------------------------------------------------------------------------------------
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13 
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public License along with
19  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
20  Place - Suite 330, Boston, MA 02111-1307, USA, or go to
21  http://www.gnu.org/copyleft/lesser.txt.
22  ------------------------------------------------------------------------------------
23  Author: Zhur, mmcs
24 */
25 
26 #include "eve-common.h"
27 
28 #include "python/PyXMLGenerator.h"
29 #include "python/PyRep.h"
30 
31 PyXMLGenerator::PyXMLGenerator( FILE* into, const char* pfx )
32 : PyPfxVisitor( pfx ),
33  mInto( into ),
34  mItem( 0 )
35 {
36 }
37 
39 {
40  fprintf( mInto, "%s<int name=\"integer%u\" />\n", _pfx(), mItem++ );
41 
42  return true;
43 }
44 
46 {
47  fprintf( mInto, "%s<long name=\"long%u\" />\n", _pfx(), mItem++ );
48 
49  return true;
50 }
51 
53 {
54  fprintf( mInto, "%s<real name=\"real%u\" />\n", _pfx(), mItem++ );
55 
56  return true;
57 }
58 
60 {
61  fprintf( mInto, "%s<bool name=\"bool%u\" />\n", _pfx(), mItem++ );
62 
63  return true;
64 }
65 
67 {
68  fprintf( mInto, "%s<none />\n", _pfx() );
69 
70  return true;
71 }
72 
74 {
75  fprintf( mInto, "%s<buffer name=\"buffer%u\" />\n", _pfx(), mItem++ );
76 
77  return true;
78 }
79 
81 {
82  fprintf( mInto, "%s<string name=\"string%u\" />\n", _pfx(), mItem++ );
83 
84  return true;
85 }
86 
88 {
89  fprintf( mInto, "%s<!-- PyPackedRow stub -->\n", _pfx() );
90 
91  return true;
92 }
93 
95 {
96  fprintf( mInto, "%s<objectInline>\n", _pfx() );
97 
98  _pfxExtend( " " );
99  bool res = PyPfxVisitor::VisitObject( rep );
100  _pfxWithdraw();
101 
102  fprintf( mInto, "%s</objectInline>\n", _pfx() );
103 
104  return res;
105 }
106 
108 {
109  fprintf( mInto, "%s<!-- PyObjectEx stub -->\n", _pfx() );
110 
111  return true;
112 }
113 
115 {
116  fprintf( mInto, "%s<substructInline>\n", _pfx() );
117 
118  _pfxExtend( " " );
119  bool res = PyVisitor::VisitSubStruct( rep );
120  _pfxWithdraw();
121 
122  fprintf( mInto, "%s</substructInline>\n", _pfx() );
123 
124  return res;
125 }
126 
128 {
129  fprintf( mInto, "%s<substreamInline>\n", _pfx() );
130 
131  _pfxExtend( " " );
132  bool res = PyVisitor::VisitSubStream( rep );
133  _pfxWithdraw();
134 
135  fprintf( mInto, "%s</substreamInline>\n", _pfx() );
136 
137  return res;
138 }
139 
141 {
142  fprintf( mInto, "%s<!-- PyChecksumedStream stub -->\n", _pfx() );
143 
144  return true;
145 }
146 
148 {
149  enum
150  {
151  DictInline,
152  DictStringKey,
153  DictIntKey,
154  DictRaw
155  } ktype;
156 
157  enum
158  {
159  ValueUnknown,
160  ValueString,
161  ValueInt,
162  ValueReal,
163  ValueMixed
164  } vtype;
165 
166  ktype = DictInline;
167  vtype = ValueUnknown;
168 
169  //this is kinda a hack, but we want to try and classify the contents of this dict:
170  PyDict::const_iterator cur, end;
171  cur = rep->begin();
172  end = rep->end();
173  for(; cur != end; ++cur)
174  {
175  if( cur->first->IsString() )
176  {
177  if( ktype == DictIntKey )
178  {
179  //we have varying key types, raw dict it is.
180  ktype = DictRaw;
181  break;
182  }
183  else if( ktype == DictInline )
184  ktype = DictStringKey;
185  }
186  else if( cur->first->IsInt() )
187  {
188  if( ktype == DictStringKey )
189  {
190  //we have varying key types, raw dict it is.
191  ktype = DictRaw;
192  break;
193  }
194  else if( ktype == DictInline )
195  ktype = DictIntKey;
196  }
197  else
198  {
199  //anything but those key types is more than we can think about, keep it raw.
200  ktype = DictRaw;
201  break;
202  }
203 
204  if( cur->second->IsString() )
205  {
206  if( vtype == ValueInt || vtype == ValueReal )
207  vtype = ValueMixed;
208  else if( vtype == ValueUnknown )
209  vtype = ValueString;
210  }
211  else if(cur->second->IsInt())
212  {
213  if( vtype == ValueString || vtype == ValueReal )
214  vtype = ValueMixed;
215  else if( vtype == ValueUnknown )
216  vtype = ValueInt;
217  }
218  else if( cur->second->IsFloat() )
219  {
220  if( vtype == ValueString || vtype == ValueInt )
221  vtype = ValueMixed;
222  else if(vtype == ValueUnknown)
223  vtype = ValueReal;
224  }
225  else
226  vtype = ValueMixed;
227  }
228 
229  if( ktype == DictRaw )
230  {
231  fprintf( mInto, "%s<dict name=\"dict%u\" />\n", _pfx(), mItem++ );
232  return true;
233  }
234  else if( ktype == DictIntKey )
235  {
236  //cant do an inline dict, but can try a vector
237  switch( vtype )
238  {
239  case ValueString:
240  fprintf( mInto, "%s<dictInt name=\"dict%u\" type=\"string\" />\n", _pfx(), mItem++ );
241  break;
242  case ValueInt:
243  fprintf( mInto, "%s<dictInt name=\"dict%u\" type=\"int\" />\n", _pfx(), mItem++ );
244  break;
245  case ValueReal:
246  fprintf( mInto, "%s<dictInt name=\"dict%u\" type=\"real\" />\n", _pfx(), mItem++ );
247  break;
248  case ValueUnknown:
249  case ValueMixed:
250  fprintf( mInto, "%s<dictRaw name=\"dict%u\" />\n", _pfx(), mItem++ );
251  break;
252  }
253 
254  return true;
255  }
256 
257  fprintf( mInto, "%s<dictInline>\n", _pfx() );
258 
259  _pfxExtend( " " );
260 
262  cur = rep->begin();
263  end = rep->end();
264  for(; cur != end; ++cur)
265  {
266  if( !cur->first->IsString() )
267  {
268  fprintf( mInto, "%s<!-- non-string dict key of type %s -->\n", _pfx(), cur->first->TypeString() );
269  return false;
270  }
271  PyString* str = cur->first->AsString();
272 
273  fprintf( mInto, "%s<dictInlineEntry key=\"%s\">\n", _pfx(), str->content().c_str() );
274 
275  _pfxExtend( " " );
276  cur->second->visit( *this );
277  _pfxWithdraw();
278 
279  fprintf( mInto, "%s</dictInlineEntry>\n", _pfx() );
280  }
281 
282  _pfxWithdraw();
283 
284  fprintf( mInto, "%s</dictInline>\n", _pfx() );
285 
286  return true;
287 }
288 
290 {
291  //for now presume we cant do anything useful with lists that contain
292  //more than a few things...
293  if( rep->size() < 5 )
294  {
295  fprintf( mInto, "%s<listInline>\n", _pfx() );
296 
297  _pfxExtend( " " );
298 
300  PyList::const_iterator cur, end;
301  cur = rep->begin();
302  end = rep->end();
303  for( uint32 i = 0; cur != end; ++cur, ++i )
304  {
305  fprintf( mInto, "%s<!-- %u -->\n", _pfx(), i );
306  (*cur)->visit( *this );
307  }
308 
309  _pfxWithdraw();
310 
311  fprintf( mInto, "%s</listInline>\n", _pfx() );
312  }
313  else
314  {
315  enum
316  {
317  TypeUnknown,
318  TypeString,
319  TypeInteger,
320  TypeReal,
321  TypeMixed
322  } eletype;
323  eletype = TypeUnknown;
324 
325  //scan the list to see if we can classify the contents.
326  PyList::const_iterator cur, end;
327  cur = rep->begin();
328  end = rep->end();
329  for(; cur != end; cur++)
330  {
331  if( (*cur)->IsString() )
332  {
333  if( eletype == TypeInteger || eletype == TypeReal )
334  {
335  eletype = TypeMixed;
336  break;
337  }
338  else if( eletype == TypeUnknown )
339  eletype = TypeString;
340  }
341  else if( (*cur)->IsInt() )
342  {
343  if( eletype == TypeString || eletype == TypeReal )
344  {
345  eletype = TypeMixed;
346  break;
347  }
348  else if( eletype == TypeUnknown )
349  eletype = TypeInteger;
350  }
351  else if( (*cur)->IsFloat() )
352  {
353  if( eletype == TypeString || eletype == TypeInteger )
354  {
355  eletype = TypeMixed;
356  break;
357  }
358  else if( eletype == TypeUnknown )
359  eletype = TypeReal;
360  }
361  else
362  {
363  eletype = TypeMixed;
364  break;
365  }
366  }
367 
368  switch( eletype )
369  {
370  case TypeString:
371  fprintf( mInto, "%s<listStr name=\"list%u\" />\n", _pfx(), mItem++ );
372  break;
373  case TypeInteger:
374  fprintf( mInto, "%s<listInt name=\"list%u\" />\n", _pfx(), mItem++ );
375  break;
376  case TypeReal:
377  fprintf( mInto, "%s<listReal name=\"list%u\" />\n", _pfx(), mItem++ );
378  break;
379  case TypeUnknown:
380  case TypeMixed:
381  fprintf( mInto, "%s<list name=\"list%u\" />\n", _pfx(), mItem++ );
382  break;
383  }
384  }
385 
386  return true;
387 }
388 
390 {
391  fprintf( mInto, "%s<tupleInline>\n", _pfx() );
392 
393  _pfxExtend( " " );
394 
396  PyTuple::const_iterator cur, end;
397  cur = rep->begin();
398  end = rep->end();
399  for(uint32 i = 0; cur != end; ++cur, ++i)
400  {
401  fprintf( mInto, "%s<!-- %d -->\n", _pfx(), i );
402  (*cur)->visit( *this );
403  }
404 
405  _pfxWithdraw();
406 
407  fprintf( mInto, "%s</tupleInline>\n", _pfx() );
408 
409  return true;
410 }
411 
412 
413 
414 
415 
416 
417 
418 
419 
420 
421 
422 
423 
424 
425 
426 
427 
428 
429 
430 
bool VisitChecksumedStream(const PyChecksumedStream *rep)
bool VisitInteger(const PyInt *rep)
primitive data visitors
void _pfxExtend(const char *fmt,...)
Definition: PyVisitor.cpp:148
Python string.
Definition: PyRep.h:430
virtual bool VisitSubStream(const PySubStream *rep)
Definition: PyVisitor.cpp:119
bool VisitObject(const PyObject *rep)
Object type visitor.
Python's dictionary.
Definition: PyRep.h:719
bool VisitDict(const PyDict *rep)
bool VisitBoolean(const PyBool *rep)
bool VisitList(const PyList *rep)
bool VisitSubStruct(const PySubStruct *rep)
wrapper types Visitor
bool VisitNone(const PyNone *rep)
storage_type::const_iterator const_iterator
Definition: PyRep.h:572
FILE *const mInto
Python floating point number.
Definition: PyRep.h:292
bool VisitReal(const PyFloat *rep)
const_iterator begin() const
Definition: PyRep.h:660
storage_type::const_iterator const_iterator
Definition: PyRep.h:644
void _pfxWithdraw()
Definition: PyVisitor.h:91
Python tuple.
Definition: PyRep.h:567
Python boolean.
Definition: PyRep.h:323
bool VisitBuffer(const PyBuffer *rep)
Python extended object.
Definition: PyRep.h:861
Python object.
Definition: PyRep.h:826
Python's "none".
Definition: PyRep.h:352
bool VisitString(const PyString *rep)
virtual bool VisitSubStruct(const PySubStruct *rep)
wrapper types Visitor
Definition: PyVisitor.cpp:112
Python integer.
Definition: PyRep.h:231
PyString * AsString()
Definition: PyRep.h:132
unsigned __int32 uint32
Definition: eve-compat.h:50
bool VisitPackedRow(const PyPackedRow *rep)
PackedRow type visitor.
const_iterator begin() const
Definition: PyRep.h:766
virtual bool VisitObject(const PyObject *rep)
Object type visitor.
Definition: PyVisitor.cpp:69
const_iterator end() const
Definition: PyRep.h:661
storage_type::const_iterator const_iterator
Definition: PyRep.h:750
bool VisitObjectEx(const PyObjectEx *rep)
bool VisitSubStream(const PySubStream *rep)
const std::string & content() const
Get the PyString content.
Definition: PyRep.h:458
const_iterator end() const
Definition: PyRep.h:767
size_t size() const
Definition: PyRep.h:663
Python buffer.
Definition: PyRep.h:382
Packed row.
Definition: PyRep.h:961
bool VisitLong(const PyLong *rep)
const_iterator end() const
Definition: PyRep.h:589
const_iterator begin() const
Definition: PyRep.h:588
PyXMLGenerator(FILE *into, const char *pfx="")
const char * _pfx() const
Definition: PyVisitor.h:89
Python list.
Definition: PyRep.h:639
Python long integer.
Definition: PyRep.h:261
bool VisitTuple(const PyTuple *rep)
the nested types Visitor