EvEmu  0.8.4
11 September 2021
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
EVEUnmarshal.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: Bloody.Rabbit, Captnoord, Zhur
24 */
25 
26 #include "eve-common.h"
27 
29 #include "python/PyVisitor.h"
30 #include "python/PyRep.h"
31 
32 #include "marshal/EVEUnmarshal.h"
35 
36 #include "utils/EVEUtils.h"
37 
38 PyRep* Unmarshal( const Buffer& data )
39 {
40  UnmarshalStream* pUMS = new UnmarshalStream();
41  PyRep* res = pUMS->Load( data );
42  SafeDelete(pUMS);
43  return res;
44 }
45 
46 PyRep* InflateUnmarshal( const Buffer& data )
47 {
48  if (IsDeflated(data)) {
49  Buffer inflatedData;
50  if (!InflateData(data, inflatedData))
51  return nullptr;
52  return Unmarshal(inflatedData);
53  }
54 
55  return Unmarshal(data);
56 }
57 
59 {
60  //PySafeDecRef(mStoredObjects);
61 }
62 
63 /************************************************************************/
64 /* UnmarshalStream */
65 /************************************************************************/
67 {
69  &UnmarshalStream::LoadNone, //Op_PyNone
70  &UnmarshalStream::LoadToken, //Op_PyToken
71  &UnmarshalStream::LoadIntegerLongLong, //Op_PyLongLong
73  &UnmarshalStream::LoadIntegerSignedShort, //Op_PySignedShort
75  &UnmarshalStream::LoadIntegerMinusOne, //Op_PyMinusOne
76  &UnmarshalStream::LoadIntegerZero, //Op_PyZeroInteger
77  &UnmarshalStream::LoadIntegerOne, //Op_PyOneInteger
78  &UnmarshalStream::LoadReal, //Op_PyReal
79  &UnmarshalStream::LoadRealZero, //Op_PyZeroReal
81  &UnmarshalStream::LoadBuffer, //Op_PyBuffer
82  &UnmarshalStream::LoadStringEmpty, //Op_PyEmptyString
83  &UnmarshalStream::LoadStringChar, //Op_PyCharString
84  &UnmarshalStream::LoadStringShort, //Op_PyShortString
85  &UnmarshalStream::LoadStringTable, //Op_PyStringTableItem
86  &UnmarshalStream::LoadWStringUCS2, //Op_PyWStringUCS2
87  &UnmarshalStream::LoadStringLong, //Op_PyLongString
88  &UnmarshalStream::LoadTuple, //Op_PyTuple
89  &UnmarshalStream::LoadList, //Op_PyList
90  &UnmarshalStream::LoadDict, //Op_PyDict
91  &UnmarshalStream::LoadObject, //Op_PyObject
93  &UnmarshalStream::LoadSubStruct, //Op_PySubStruct
95  &UnmarshalStream::LoadSavedStreamElement, //Op_PySavedStreamElement
96  &UnmarshalStream::LoadChecksumedStream, //Op_PyChecksumedStream
99  &UnmarshalStream::LoadBoolTrue, //Op_PyTrue
100  &UnmarshalStream::LoadBoolFalse, //Op_PyFalse
101  &UnmarshalStream::LoadError, //Op_cPicked
102  &UnmarshalStream::LoadObjectEx1, //Op_PyObjectEx1
103  &UnmarshalStream::LoadObjectEx2, //Op_PyObjectEx2
104  &UnmarshalStream::LoadTupleEmpty, //Op_PyEmptyTuple
105  &UnmarshalStream::LoadTupleOne, //Op_PyOneTuple
106  &UnmarshalStream::LoadListEmpty, //Op_PyEmptyList
107  &UnmarshalStream::LoadListOne, //Op_PyOneList
108  &UnmarshalStream::LoadWStringEmpty, //Op_PyEmptyWString
109  &UnmarshalStream::LoadWStringUCS2Char, //Op_PyWStringUCS2Char
110  &UnmarshalStream::LoadPackedRow, //Op_PyPackedRow
111  &UnmarshalStream::LoadSubStream, //Op_PySubStream
112  &UnmarshalStream::LoadTupleTwo, //Op_PyTwoTuple
113  &UnmarshalStream::LoadError, //Op_PackedTerminator
114  &UnmarshalStream::LoadWStringUTF8, //Op_PyWStringUTF8
115  &UnmarshalStream::LoadIntegerVar, //Op_PyVarInteger
131  &UnmarshalStream::LoadError
132 };
133 
135 {
136  mInItr = data.begin<uint8>();
137  PyRep* res = LoadStream( data.size() );
139 
140  return res;
141 }
142 
143 PyRep* UnmarshalStream::LoadStream( size_t streamLength )
144 {
145  const uint8 header = Read<uint8>();
146  if (MarshalHeaderByte != header) {
147  sLog.Error( "Unmarshal", "Invalid stream received (header byte 0x%X).", header );
148  return nullptr;
149  }
150 
151  const uint32 saveCount = Read<uint32>();
152  CreateObjectStore( streamLength - sizeof( uint8 ) - sizeof( uint32 ), saveCount );
153 
154  PyRep* rep = LoadRep();
155 
157  return rep;
158 }
159 
161 {
162  const uint8 header = Read<uint8>();
163 
164  const bool flagUnknown = ( header & PyRepUnknownMask ) != 0;
165  const bool flagSave = ( header & PyRepSaveMask ) != 0;
166  const uint8 opcode = ( header & PyRepOpcodeMask );
167 
168  if( flagUnknown )
169  sLog.Warning( "Unmarshal", "Encountered flagUnknown in header 0x%X.", header );
170 
171  const uint32 storageIndex = ( flagSave ? GetStorageIndex() : 0 );
172 
173  PyRep* rep = ( this->*s_mLoadMap[ opcode ] )();
174 
175  if( 0 != storageIndex )
176  StoreObject( storageIndex, rep );
177 
178  return rep;
179 }
180 
181 void UnmarshalStream::CreateObjectStore( size_t streamLength, uint32 saveCount )
182 {
184 
185  if( 0 < saveCount )
186  {
187  mStoreIndexItr = ( ( mInItr + streamLength ).As<uint32>() - saveCount );
188  mStoredObjects = new PyList( saveCount );
189  }
190 }
191 
193 {
196 }
197 
199 {
200  if( 0 < index )
201  return mStoredObjects->GetItem( --index );
202  return nullptr;
203 }
204 
206 {
207  if( 0 < index )
208  {
209  PyIncRef( object );
210  mStoredObjects->SetItem( --index, object );
211  }
212 }
213 
215 {
216  /* this is one of the stranger fields I have found, it seems to be a variable
217  * length integer field (somewhat of a 'bigint' style data type), but it gets
218  * used at times for integers which would fit into the other primitive data
219  * types.... I would really like to see the criteria they use to determine
220  * what gets marshaled as what...
221  */
222 
223  const uint32 len = ReadSizeEx();
224  const Buffer::const_iterator<uint8> data = Read<uint8>( len );
225 
226  if( sizeof( int32 ) >= len )
227  {
228  int32 intval(0);
229  memcpy( &intval, &*data, len );
230 
231  return new PyInt( intval );
232  }
233  else if( sizeof( int64 ) >= len )
234  {
235  int64 intval(0);
236  memcpy( &intval, &*data, len );
237 
238  return new PyLong( intval );
239  }
240  else
241  {
242  //int64 is not big enough
243  //just pass it up to the application layer as a buffer...
244  return new PyBuffer( data, data + len );
245  }
246 }
247 
249 {
250  const Buffer::const_iterator<char> str = Read<char>( 1 );
251 
252  return new PyString( str, str + 1 );
253 }
254 
256 {
257  const uint8 len = Read<uint8>();
258  const Buffer::const_iterator<char> str = Read<char>( len );
259 
260  return new PyString( str, str + len );
261 }
262 
264 {
265  const uint32 len = ReadSizeEx();
266  const Buffer::const_iterator<char> str = Read<char>( len );
267 
268  return new PyString( str, str + len );
269 }
270 
272 {
273  const uint8 index = Read<uint8>();
274 
275  const char* str = sMarshalStringTable.LookupString( index );
276  if( NULL == str )
277  {
278  assert( false );
279  sLog.Error( "Unmarshal", "String Table Item %u is out of range!", index );
280 
281  char ebuf[64];
282  snprintf( ebuf, 64, "Invalid String Table Item %u", index );
283  return new PyString( ebuf );
284  }
285  else
286  return new PyString( str );
287 }
288 
290 {
291  const Buffer::const_iterator<uint16> wstr = Read<uint16>( 1 );
292 
293  // convert to UTF-8
294  std::string str;
295  utf8::utf16to8( wstr, wstr + 1, std::back_inserter( str ) );
296 
297  return new PyWString( str );
298 }
299 
301 {
302  const uint32 len = ReadSizeEx();
303  const Buffer::const_iterator<uint16> wstr = Read<uint16>( len );
304 
305  // convert to UTF-8
306  std::string str;
307  utf8::utf16to8( wstr, wstr + len, std::back_inserter( str ) );
308 
309  return new PyWString( str );
310 }
311 
313 {
314  const uint32 len = ReadSizeEx();
315  const Buffer::const_iterator<char> wstr = Read<char>( len );
316 
317  return new PyWString( wstr, wstr + len );
318 }
319 
321 {
322  const uint8 len = Read<uint8>();
323  const Buffer::const_iterator<char> str = Read<char>( len );
324 
325  return new PyToken( str, str + len );
326 }
327 
329 {
330  const uint32 len = ReadSizeEx();
331  const Buffer::const_iterator<uint8> data = Read<uint8>( len );
332 
333  return new PyBuffer( data, data + len );
334 }
335 
337 {
338  const uint32 count = ReadSizeEx();
339  PyTuple* tuple = new PyTuple( count );
340 
341  for ( uint32 i(0); i < count; ++i ) {
342  PyRep* rep = LoadRep();
343  if (rep == nullptr) {
344  PyDecRef( tuple );
345  return nullptr;
346  }
347 
348  tuple->SetItem( i, rep );
349  }
350 
351  return tuple;
352 }
353 
355 {
356  PyRep* i = LoadRep();
357  if( NULL == i )
358  return nullptr;
359 
360  PyTuple* tuple = new PyTuple( 1 );
361  tuple->SetItem( 0, i );
362 
363  return tuple;
364 }
365 
367 {
368  PyRep* i = LoadRep();
369  if( NULL == i )
370  return nullptr;
371 
372  PyRep* j = LoadRep();
373  if( NULL == j )
374  {
375  PyDecRef( i );
376  return nullptr;
377  }
378 
379  PyTuple *tuple = new PyTuple( 2 );
380  tuple->SetItem( 0, i );
381  tuple->SetItem( 1, j );
382 
383  return tuple;
384 }
385 
387 {
388  const uint32 count = ReadSizeEx();
389  PyList* list = new PyList( count );
390 
391  for ( uint32 i(0); i < count; i++ )
392  {
393  PyRep* rep = LoadRep();
394  if (rep == nullptr)
395  {
396  PyDecRef( list );
397  return nullptr;
398  }
399 
400  list->SetItem( i, rep );
401  }
402 
403  return list;
404 }
405 
407 {
408  PyRep* i = LoadRep();
409  if( NULL == i )
410  return nullptr;
411 
412  PyList* list = new PyList();
413  list->AddItem( i );
414 
415  return list;
416 }
417 
419 {
420  const uint32 count = ReadSizeEx();
421  PyDict* dict = new PyDict;
422 
423  for ( uint32 i(0); i < count; i++ )
424  {
425  PyRep* value = LoadRep();
426  if( NULL == value )
427  return nullptr;
428 
429  PyRep* key = LoadRep();
430  if( NULL == key )
431  {
432  PyDecRef( value );
433  return nullptr;
434  }
435 
436  dict->SetItem( key, value );
437  }
438 
439  return dict;
440 }
441 
443 {
444  PyRep* type = LoadRep();
445  if( NULL == type )
446  return nullptr;
447 
448  if( !type->IsString() )
449  {
450  sLog.Error( "Unmarshal", "Object: Expected 'String' as type, got '%s'.", type->TypeString() );
451 
452  PyDecRef( type );
453  return nullptr;
454  }
455 
456  PyRep* arguments = LoadRep();
457  if( NULL == arguments )
458  {
459  PyDecRef( type );
460  return nullptr;
461  }
462 
463  return new PyObject( type->AsString(), arguments );
464 }
465 
467 {
468  return LoadObjectEx( false );
469 }
470 
472 {
473  return LoadObjectEx( true );
474 }
475 
477 {
478  const uint32 len = ReadSizeEx();
479  const Buffer::const_iterator<uint8> data = Read<uint8>( len );
480 
481  return new PySubStream( new PyBuffer( data, data + len ) );
482 }
483 
485 {
486  // This is actually a remote object specification
487 
488  PyRep* ss = LoadRep();
489  if( NULL == ss )
490  return nullptr;
491 
492  return new PySubStruct( ss );
493 }
494 
496 {
497  const uint32 sum = Read<uint32>();
498 
499  PyRep* ss = LoadRep();
500  if( NULL == ss )
501  return nullptr;
502 
503  return new PyChecksumedStream( ss, sum );
504 }
505 
507 {
508  // PyPackedRows are just a packed form of blue.DBRow
509  // these take a DBRowDescriptor and the column data in different formats
510  PyRep* header_element = LoadRep();
511  if( NULL == header_element )
512  return nullptr;
513 
514  // create the base packed row to be filled with data
515  PyPackedRow* row = new PyPackedRow( (DBRowDescriptor*)header_element );
516 
517  // create the sizemap and sort it by bitsize, the value of the map indicates the index of the column
518  // this can be used to identify things easily
519  std::multimap< uint8, uint32, std::greater< uint8 > > sizeMap;
520  std::map<uint8,uint8> booleanColumns;
521 
522  uint32 columnCount = row->header()->ColumnCount();
523  size_t byteDataBitLength = 0;
524  size_t booleansBitLength = 0;
525  size_t nullsBitLength = 0;
526 
527  for (uint32 i(0); i < columnCount; i++ )
528  {
529  DBTYPE columnType = row->header()->GetColumnType (i);
530  uint8_t size = DBTYPE_GetSizeBits (columnType);
531 
532  // count booleans
533  if (columnType == DBTYPE_BOOL)
534  {
535  booleanColumns.insert (std::make_pair (i, booleansBitLength));
536  booleansBitLength++;
537  }
538 
539  // count all columns as possible nulls
540  nullsBitLength ++;
541 
542  // increase the bytedata length only if a column is longer than 7 bits
543  // this is used as an indicator of what is written in the first, second or third part
544  if (size >= 8)
545  byteDataBitLength += size;
546 
547  // add the column to the list
548  sizeMap.insert (std::make_pair (size, i));
549  }
550 
551  size_t expectedByteSize = (byteDataBitLength >> 3) + ((booleansBitLength + nullsBitLength) >> 3) + 1;
552 
553  // reserve enough space for the buffer
554  Buffer unpacked (expectedByteSize, 0);
555 
556  if( !LoadRLE(unpacked) )
557  {
558  PyDecRef( header_element );
559  return nullptr;
560  }
561 
562  Buffer::const_iterator<uint8> unpackedItr = unpacked.begin<uint8>();
563  Buffer::const_iterator<uint8> bitIterator = unpacked.begin<uint8>();
564 
565  std::multimap< uint8, uint32, std::greater< uint8 > >::iterator cur, end;
566  cur = sizeMap.begin();
567  end = sizeMap.end();
568  for (; cur != end; ++cur)
569  {
570  const uint32 index = cur->second;
571  const DBTYPE columnType = row->header ()->GetColumnType (index);
572 
573  unsigned long nullBit = byteDataBitLength + booleansBitLength + cur->second;
574  unsigned long nullByte = nullBit >> 3;
575  // setup the iterator to the proper byte
576  // first check for nulls
577  bitIterator = unpacked.begin<uint8>() + nullByte;
578 
579  if ((*bitIterator & (1 << (nullBit & 0x7))) == (1 << (nullBit & 0x7)))
580  {
581  // PyNone value found! override it and increase the original iterator the required steps
582  unpackedItr += DBTYPE_GetSizeBits (columnType) >> 3;
583  row->SetField (index, new PyNone ());
584 
585  // continue should only be performed if the columns are not normal marshal objects
586  if (columnType != DBTYPE_BYTES && columnType != DBTYPE_STR && columnType != DBTYPE_WSTR)
587  continue;
588  }
589 
590  switch (columnType)
591  {
592  case DBTYPE_I8:
593  case DBTYPE_CY:
594  case DBTYPE_UI8:
595  case DBTYPE_FILETIME:
596  {
597  Buffer::const_iterator<int64> v = unpackedItr.As<int64>();
598  row->SetField( index, new PyLong( *v++ ) );
599  unpackedItr = v.As<uint8>();
600  } break;
601 
602  case DBTYPE_I4:
603  {
604  Buffer::const_iterator<int32> v = unpackedItr.As<int32>();
605  row->SetField( index, new PyInt( *v++ ) );
606  unpackedItr = v.As<uint8>();
607  } break;
608  case DBTYPE_UI4:
609  {
610  Buffer::const_iterator<uint32> v = unpackedItr.As<uint32>();
611  row->SetField( index, new PyInt( *v++ ) );
612  unpackedItr = v.As<uint8>();
613  } break;
614 
615  case DBTYPE_I2:
616  {
617  Buffer::const_iterator<int16> v = unpackedItr.As<int16>();
618  row->SetField( index, new PyInt( *v++ ) );
619  unpackedItr = v.As<uint8>();
620  } break;
621  case DBTYPE_UI2:
622  {
623  Buffer::const_iterator<uint16> v = unpackedItr.As<uint16>();
624  row->SetField( index, new PyInt( *v++ ) );
625  unpackedItr = v.As<uint8>();
626  } break;
627 
628  case DBTYPE_I1:
629  {
630  Buffer::const_iterator<int8> v = unpackedItr.As<int8>();
631  row->SetField( index, new PyInt( *v++ ) );
632  unpackedItr = v.As<uint8>();
633  } break;
634 
635  case DBTYPE_UI1:
636  {
637  Buffer::const_iterator<uint8> v = unpackedItr.As<uint8>();
638  row->SetField( index, new PyInt( *v++ ) );
639  unpackedItr = v.As<uint8>();
640  } break;
641 
642  case DBTYPE_R8:
643  {
644  Buffer::const_iterator<double> v = unpackedItr.As<double>();
645  row->SetField( index, new PyFloat( *v++ ) );
646  unpackedItr = v.As<uint8>();
647  } break;
648 
649  case DBTYPE_R4:
650  {
651  Buffer::const_iterator<float> v = unpackedItr.As<float>();
652  row->SetField( index, new PyFloat( *v++ ) );
653  unpackedItr = v.As<uint8>();
654  } break;
655 
656  case DBTYPE_BOOL:
657  {
658  // get the bit this boolean should be read from
659  unsigned long boolBit = byteDataBitLength + booleanColumns.find (index)->second;
660  unsigned long boolByte = boolBit >> 3;
661  // setup the iterator to the proper byte
662  bitIterator = unpacked.begin<uint8>() + boolByte;
663 
664  row->SetField (index, new PyBool ((*bitIterator & (1 << (boolBit & 0x7))) == (1 << (boolBit & 0x7))));
665  } break;
666 
667  // these objects are read directly from the end of the PyPackedRow
668  // so they can be kept
669  case DBTYPE_BYTES:
670  case DBTYPE_STR:
671  case DBTYPE_WSTR:
672  {
673  PyRep* el = LoadRep();
674  if( NULL == el )
675  {
676  PyDecRef( row );
677  return nullptr;
678  }
679 
680  row->SetField( index, el );
681  } break;
682 
683  case DBTYPE_EMPTY:
684  case DBTYPE_ERROR:
685  return nullptr;
686  }
687  }
688 
689  return row;
690 }
691 
693 {
694  sLog.Error( "Unmarshal", "Invalid opcode encountered." );
695 
696  return nullptr;
697 }
698 
700 {
701  const uint32 index = ReadSizeEx();
702 
703  PyRep* obj = GetStoredObject( index );
704  if( NULL == obj )
705  {
706  sLog.Error( "Unmarshal", "SavedStreamElement: Got invalid stored object." );
707  return nullptr;
708  }
709 
710  return obj->Clone();
711 }
712 
714 {
715  PyRep* header = LoadRep();
716  if( NULL == header )
717  return nullptr;
718 
719  PyObjectEx* obj = new PyObjectEx( is_type_2, header );
720 
721  while( Op_PackedTerminator != Peek<uint8>() )
722  {
723  PyRep* el = LoadRep();
724  if( NULL == el )
725  {
726  PyDecRef( obj );
727  return nullptr;
728  }
729 
730  obj->list().AddItem( el );
731  }
732  //skip Op_PackedTerminator
733  Read<uint8>();
734 
735  while( Op_PackedTerminator != Peek<uint8>() )
736  {
737  PyRep* key = LoadRep();
738  if( NULL == key )
739  {
740  PyDecRef( obj );
741  return nullptr;
742  }
743 
744  PyRep* value = LoadRep();
745  if( NULL == value )
746  {
747  PyDecRef( key );
748  PyDecRef( obj );
749  return nullptr;
750  }
751 
752  obj->dict().SetItem( key, value );
753  }
754  //skip Op_PackedTerminator
755  Read<uint8>();
756 
757  return obj;
758 }
759 
761 {
762  const uint32 in_size = ReadSizeEx();
763 
765  cur = Read<uint8>(in_size );
766  end = cur + in_size;
767  Buffer::const_iterator<uint8> in_ix = cur;
768  int out_ix = 0;
769  int count;
770  int run = 0;
771  int nibble = 0;
772 
773  while(in_ix < end)
774  {
775  nibble = !nibble;
776  if(nibble)
777  {
778  run = (unsigned char)*in_ix++;
779  count = (run & 0x0f) - 8;
780  }
781  else
782  count = (run >> 4) - 8;
783 
784  if(count >= 0)
785  {
786  if (out_ix + count + 1 > out.size())
787  return false;
788 
789  while(count-- >= 0)
790  out[out_ix++] = 0;
791  }
792  else
793  {
794  if (out_ix - count > out.size())
795  return false;
796 
797  while(count++ && in_ix < end)
798  out[out_ix++] = *in_ix++;
799  }
800  }
801 
802  // no need to set the rest of the buffer to zero as the output is already
803  // set to 0
804  // while(out_ix < out.size())
805  // out[out_ix++] = 0;
806 
807  return true;
808 }
Base Python wire object.
Definition: PyRep.h:66
list_type & list()
Definition: PyRep.h:889
PyRep * Load(const Buffer &data)
Loads Python object from given bytecode.
unsigned __int8 uint8
Definition: eve-compat.h:46
PyRep * LoadIntegerVar()
void StoreObject(uint32 index, PyRep *object)
Stores object.
PyRep * LoadStringShort()
PyRep * InflateUnmarshal(const Buffer &data)
Turns possibly inflated marshal stream into Python object.
PyRep * LoadIntegerOne()
Definition: EVEUnmarshal.h:167
Python string.
Definition: PyRep.h:430
PyRep * LoadSubStruct()
PyRep * LoadIntegerMinusOne()
Definition: EVEUnmarshal.h:163
Python's dictionary.
Definition: PyRep.h:719
DBRowDescriptor * header() const
Definition: PyRep.h:983
virtual PyRep * Clone() const =0
Clones object.
PyRep * LoadObject()
uint32 GetStorageIndex()
Obtains storage index for StoreObject.
Definition: EVEUnmarshal.h:126
bool IsString() const
Definition: PyRep.h:105
Buffer::const_iterator< uint8 > mInItr
Definition: EVEUnmarshal.h:247
#define sMarshalStringTable
Python floating point number.
Definition: PyRep.h:292
Python wide string.
Definition: PyRep.h:475
PyRep * LoadListOne()
PyRep * GetStoredObject(uint32 index)
Obtains previously stored object.
PyRep * LoadWStringUCS2Char()
static const uint8 PyRepSaveMask
PyRep * LoadIntegerLongLong()
Definition: EVEUnmarshal.h:153
Python tuple.
Definition: PyRep.h:567
const_iterator< T2 > As() const
Converts const_iterator to another const_iterator with different type.
Definition: Buffer.h:108
PyRep * LoadIntegerByte()
Definition: EVEUnmarshal.h:159
PyRep * LoadIntegerZero()
Definition: EVEUnmarshal.h:165
signed __int8 int8
Definition: eve-compat.h:45
PyRep * LoadStringTable()
PyList * mStoredObjects
Definition: EVEUnmarshal.h:252
PyRep * LoadStringEmpty()
Definition: EVEUnmarshal.h:175
static const uint8 PyRepUnknownMask
void AddItem(PyRep *i)
Definition: PyRep.h:701
void SafeDelete(T *&p)
Deletes and nullifies a pointer.
Definition: SafeMem.h:83
PyRep * LoadStringLong()
signed __int32 int32
Definition: eve-compat.h:49
PyRep * GetItem(size_t index) const
Returns Python object.
Definition: PyRep.h:674
Python boolean.
Definition: PyRep.h:323
PyRep * LoadTupleEmpty()
Definition: EVEUnmarshal.h:201
#define sLog
Evaluates to a NewLog instance.
Definition: LogNew.h:250
PyRep * LoadList()
PyRep * LoadObjectEx2()
PyRep * LoadSubStream()
iterator< T > begin()
Definition: Buffer.h:381
DBTYPE GetColumnType(uint32 index) const
Definition: PyDatabase.cpp:70
Python extended object.
Definition: PyRep.h:861
Generic class for buffers.
Definition: Buffer.h:40
Python object.
Definition: PyRep.h:826
Python object "blue.DBRowDescriptor".
Definition: PyDatabase.h:41
uint32 ColumnCount() const
Definition: PyDatabase.cpp:60
Python's "none".
Definition: PyRep.h:352
PyRep * LoadIntegerLong()
Definition: EVEUnmarshal.h:155
void SetItem(size_t index, PyRep *object)
Stores Python object.
Definition: PyRep.h:610
DBTYPE
Definition: dbtype.h:67
#define snprintf
Definition: eve-compat.h:184
PyRep * LoadTupleOne()
PyRep * LoadTupleTwo()
Python integer.
Definition: PyRep.h:231
bool IsDeflated(const Buffer &data)
Checks whether given data is deflated.
Definition: Deflate.cpp:32
void SetItem(size_t index, PyRep *object)
Stores Python object.
Definition: PyRep.h:682
PyRep * LoadBoolFalse()
Definition: EVEUnmarshal.h:150
PyString * AsString()
Definition: PyRep.h:132
PyRep * LoadWStringUCS2()
PyRep * LoadIntegerSignedShort()
Definition: EVEUnmarshal.h:157
dict_type & dict()
Definition: PyRep.h:892
PyRep * LoadWStringEmpty()
Definition: EVEUnmarshal.h:186
PyRep * LoadSavedStreamElement()
PyRep * LoadTuple()
#define PyDecRef(op)
Definition: PyRep.h:57
PyRep * LoadError()
unsigned __int32 uint32
Definition: eve-compat.h:50
#define PyIncRef(op)
Definition: PyRep.h:56
PyRep * Unmarshal(const Buffer &data)
Turns marshal stream into Python object.
uint8 DBTYPE_GetSizeBits(DBTYPE type)
Definition: dbtype.cpp:30
bool InflateData(Buffer &data)
Inflates given data.
Definition: Deflate.cpp:68
PyRep * LoadChecksumedStream()
PyRep * LoadToken()
Python token (eg. class name).
Definition: PyRep.h:522
Buffer::const_iterator< uint32 > mStoreIndexItr
Definition: EVEUnmarshal.h:250
PyRep * LoadObjectEx1()
signed __int64 int64
Definition: eve-compat.h:51
PyRep * LoadReal()
Definition: EVEUnmarshal.h:170
static const uint8 MarshalHeaderByte
PyObjectEx * LoadObjectEx(bool is_type_2)
PyRep * LoadNone()
Definition: EVEUnmarshal.h:145
void CreateObjectStore(size_t streamLength, uint32 saveCount)
Initializes object store.
PyRep * LoadPackedRow()
size_type size() const
Definition: Buffer.h:610
bool SetField(uint32 index, PyRep *value)
Definition: PyRep.cpp:1031
Class which turns marshal bytecode into Python object.
Definition: EVEUnmarshal.h:54
signed __int16 int16
Definition: eve-compat.h:47
PyRep * LoadRealZero()
Definition: EVEUnmarshal.h:172
PyRep * LoadListEmpty()
Definition: EVEUnmarshal.h:210
void DestroyObjectStore()
Destroys object store.
PyRep * LoadStream(size_t streamLength)
static PyRep *(UnmarshalStream::*const s_mLoadMap[])()
Definition: EVEUnmarshal.h:255
#define PySafeDecRef(op)
Definition: PyRep.h:61
Python buffer.
Definition: PyRep.h:382
Packed row.
Definition: PyRep.h:961
PyRep * LoadWStringUTF8()
bool LoadRLE(Buffer &out)
typeID Spawn an NPC with the specified type text Search for items matching the specified query() type() key(value)-Send an OnRemoteMessage" ) COMMAND( setbpattr
std::string utf16to8(std::u16string &str)
Definition: utfUtils.cpp:309
PyRep * LoadStringChar()
PyRep * LoadBuffer()
unsigned __int16 uint16
Definition: eve-compat.h:48
void SetItem(PyRep *key, PyRep *value)
SetItem adds or sets a database entry.
Definition: PyRep.cpp:713
const char * TypeString() const
Definition: PyRep.cpp:76
Python list.
Definition: PyRep.h:639
uint32 ReadSizeEx()
Definition: EVEUnmarshal.h:94
Python long integer.
Definition: PyRep.h:261
PyRep * LoadBoolTrue()
Definition: EVEUnmarshal.h:148
PyRep * LoadDict()