Added dict object
This commit is contained in:
27
numeric.cpp
27
numeric.cpp
@@ -1,9 +1,7 @@
|
||||
#include "numeric.h"
|
||||
#include "data.h"
|
||||
#include "module.h"
|
||||
|
||||
PycObjRef Pyc_False = new PycObject(PycObject::TYPE_FALSE);
|
||||
PycObjRef Pyc_True = new PycObject(PycObject::TYPE_TRUE);
|
||||
#include <cstring>
|
||||
|
||||
/* PycInt */
|
||||
void PycInt::load(PycData* stream, PycModule*)
|
||||
@@ -21,6 +19,21 @@ void PycLong::load(PycData* stream, PycModule*)
|
||||
m_value.push_back(stream->get16());
|
||||
}
|
||||
|
||||
bool PycLong::isEqual(PycRef<PycObject> obj) const
|
||||
{
|
||||
PycRef<PycLong> longObj = obj.cast<PycLong>();
|
||||
if (m_size != longObj->m_size)
|
||||
return false;
|
||||
std::list<int>::const_iterator it1 = m_value.begin();
|
||||
std::list<int>::const_iterator it2 = longObj->m_value.begin();
|
||||
while (it1 != m_value.end()) {
|
||||
if (*it1 != *it2)
|
||||
return false;
|
||||
++it1, ++it2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* PycFloat */
|
||||
void PycFloat::load(PycData* stream, PycModule*)
|
||||
@@ -35,3 +48,11 @@ void PycFloat::load(PycData* stream, PycModule*)
|
||||
m_value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool PycFloat::isEqual(PycRef<PycObject> obj) const
|
||||
{
|
||||
PycRef<PycFloat> floatObj = obj.cast<PycFloat>();
|
||||
if (m_value == floatObj->m_value)
|
||||
return true;
|
||||
return (strcmp(m_value, floatObj->m_value) == 0);
|
||||
}
|
||||
|
11
numeric.h
11
numeric.h
@@ -12,6 +12,9 @@ public:
|
||||
bool isType(int type) const
|
||||
{ return (type == TYPE_INT) || PycObject::isType(type); }
|
||||
|
||||
bool isEqual(PycRef<PycObject> obj) const
|
||||
{ return m_value == obj.cast<PycInt>()->m_value; }
|
||||
|
||||
void load(class PycData* stream, class PycModule* mod);
|
||||
|
||||
int value() const { return m_value; }
|
||||
@@ -28,6 +31,8 @@ public:
|
||||
bool isType(int type) const
|
||||
{ return (type == TYPE_LONG) || PycObject::isType(type); }
|
||||
|
||||
bool isEqual(PycRef<PycObject> obj) const;
|
||||
|
||||
void load(class PycData* stream, class PycModule* mod);
|
||||
|
||||
int size() const { return m_size; }
|
||||
@@ -48,6 +53,8 @@ public:
|
||||
bool isType(int type) const
|
||||
{ return (type == TYPE_FLOAT) || PycObject::isType(type); }
|
||||
|
||||
bool isEqual(PycRef<PycObject> obj) const;
|
||||
|
||||
void load(class PycData* stream, class PycModule* mod);
|
||||
|
||||
const char* value() const { return m_value; }
|
||||
@@ -56,8 +63,4 @@ private:
|
||||
char* m_value; // Floats are stored as strings
|
||||
};
|
||||
|
||||
/* Static Singleton objects */
|
||||
extern PycObjRef Pyc_False;
|
||||
extern PycObjRef Pyc_True;
|
||||
|
||||
#endif
|
||||
|
20
object.cpp
20
object.cpp
@@ -6,12 +6,14 @@
|
||||
#include "numeric.h"
|
||||
#include "code.h"
|
||||
|
||||
PycObjRef Pyc_NULL = (PycObject*)0;
|
||||
PycObjRef Pyc_None = new PycObject(PycObject::TYPE_NONE);
|
||||
PycObjRef Pyc_Ellipsis = new PycObject(PycObject::TYPE_ELLIPSIS);
|
||||
PycObjRef Pyc_StopIteration = new PycObject(PycObject::TYPE_STOPITER);
|
||||
PycRef<PycObject> Pyc_NULL = (PycObject*)0;
|
||||
PycRef<PycObject> Pyc_None = new PycObject(PycObject::TYPE_NONE);
|
||||
PycRef<PycObject> Pyc_Ellipsis = new PycObject(PycObject::TYPE_ELLIPSIS);
|
||||
PycRef<PycObject> Pyc_StopIteration = new PycObject(PycObject::TYPE_STOPITER);
|
||||
PycRef<PycObject> Pyc_False = new PycObject(PycObject::TYPE_FALSE);
|
||||
PycRef<PycObject> Pyc_True = new PycObject(PycObject::TYPE_TRUE);
|
||||
|
||||
PycObjRef CreateObject(int type)
|
||||
PycRef<PycObject> CreateObject(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case PycObject::TYPE_NULL:
|
||||
@@ -50,8 +52,8 @@ PycObjRef CreateObject(int type)
|
||||
return new PycTuple();
|
||||
case PycObject::TYPE_LIST:
|
||||
return new PycList();
|
||||
//case PycObject::TYPE_DICT:
|
||||
// ...
|
||||
case PycObject::TYPE_DICT:
|
||||
return new PycDict();
|
||||
case PycObject::TYPE_CODE:
|
||||
case PycObject::TYPE_CODE2:
|
||||
return new PycCode();
|
||||
@@ -67,9 +69,9 @@ PycObjRef CreateObject(int type)
|
||||
}
|
||||
}
|
||||
|
||||
PycObjRef LoadObject(PycData* stream, PycModule* mod)
|
||||
PycRef<PycObject> LoadObject(PycData* stream, PycModule* mod)
|
||||
{
|
||||
PycObjRef obj = CreateObject(stream->getByte());
|
||||
PycRef<PycObject> obj = CreateObject(stream->getByte());
|
||||
if (obj != Pyc_NULL)
|
||||
obj->load(stream, mod);
|
||||
return obj;
|
||||
|
120
object.h
120
object.h
@@ -1,57 +1,6 @@
|
||||
#ifndef _PYC_OBJECT_H
|
||||
#define _PYC_OBJECT_H
|
||||
|
||||
/* Please only hold PycObjects inside PycRefs! */
|
||||
class PycObject {
|
||||
public:
|
||||
enum Type {
|
||||
// From the Python Marshallers
|
||||
TYPE_NULL = '0',
|
||||
TYPE_NONE = 'N',
|
||||
TYPE_FALSE = 'F',
|
||||
TYPE_TRUE = 'T',
|
||||
TYPE_STOPITER = 'S',
|
||||
TYPE_ELLIPSIS = '.',
|
||||
TYPE_INT = 'i',
|
||||
TYPE_INT64 = 'I',
|
||||
TYPE_FLOAT = 'f',
|
||||
TYPE_BINARY_FLOAT = 'g',
|
||||
TYPE_COMPLEX = 'x',
|
||||
TYPE_BINARY_COMPLEX = 'y',
|
||||
TYPE_LONG = 'l',
|
||||
TYPE_STRING = 's',
|
||||
TYPE_INTERNED = 't',
|
||||
TYPE_STRINGREF = 'R',
|
||||
TYPE_TUPLE = '(',
|
||||
TYPE_LIST = '[',
|
||||
TYPE_DICT = '{',
|
||||
TYPE_CODE = 'c',
|
||||
TYPE_CODE2 = 'C', // Used in Python 1.0 - 1.2
|
||||
TYPE_UNICODE = 'u',
|
||||
TYPE_UNKNOWN = '?',
|
||||
TYPE_SET = '<',
|
||||
TYPE_FROZENSET = '>',
|
||||
};
|
||||
|
||||
PycObject(int type = TYPE_UNKNOWN) : m_refs(0), m_type(type) { }
|
||||
virtual ~PycObject() { }
|
||||
|
||||
int type() const { return (this) ? m_type : TYPE_NULL; }
|
||||
|
||||
virtual bool isType(int type) const
|
||||
{ return (this) ? type == m_type : type == TYPE_NULL; }
|
||||
|
||||
virtual void load(class PycData*, class PycModule*) { }
|
||||
|
||||
private:
|
||||
int m_refs;
|
||||
int m_type;
|
||||
|
||||
public:
|
||||
void addRef() { if (this) ++m_refs; }
|
||||
void delRef() { if (this && --m_refs == 0) delete this; }
|
||||
};
|
||||
|
||||
|
||||
template <class _Obj>
|
||||
class PycRef {
|
||||
@@ -94,15 +43,70 @@ private:
|
||||
_Obj* m_obj;
|
||||
};
|
||||
|
||||
typedef PycRef<PycObject> PycObjRef;
|
||||
|
||||
PycObjRef CreateObject(int type);
|
||||
PycObjRef LoadObject(class PycData* stream, class PycModule* mod);
|
||||
/* Please only hold PycObjects inside PycRefs! */
|
||||
class PycObject {
|
||||
public:
|
||||
enum Type {
|
||||
// From the Python Marshallers
|
||||
TYPE_NULL = '0',
|
||||
TYPE_NONE = 'N',
|
||||
TYPE_FALSE = 'F',
|
||||
TYPE_TRUE = 'T',
|
||||
TYPE_STOPITER = 'S',
|
||||
TYPE_ELLIPSIS = '.',
|
||||
TYPE_INT = 'i',
|
||||
TYPE_INT64 = 'I',
|
||||
TYPE_FLOAT = 'f',
|
||||
TYPE_BINARY_FLOAT = 'g',
|
||||
TYPE_COMPLEX = 'x',
|
||||
TYPE_BINARY_COMPLEX = 'y',
|
||||
TYPE_LONG = 'l',
|
||||
TYPE_STRING = 's',
|
||||
TYPE_INTERNED = 't',
|
||||
TYPE_STRINGREF = 'R',
|
||||
TYPE_TUPLE = '(',
|
||||
TYPE_LIST = '[',
|
||||
TYPE_DICT = '{',
|
||||
TYPE_CODE = 'c',
|
||||
TYPE_CODE2 = 'C', // Used in Python 1.0 - 1.2
|
||||
TYPE_UNICODE = 'u',
|
||||
TYPE_UNKNOWN = '?',
|
||||
TYPE_SET = '<',
|
||||
TYPE_FROZENSET = '>',
|
||||
};
|
||||
|
||||
PycObject(int type = TYPE_UNKNOWN) : m_refs(0), m_type(type) { }
|
||||
virtual ~PycObject() { }
|
||||
|
||||
int type() const { return (this) ? m_type : TYPE_NULL; }
|
||||
|
||||
virtual bool isType(int type) const
|
||||
{ return (this) ? type == m_type : type == TYPE_NULL; }
|
||||
|
||||
virtual bool isEqual(PycRef<PycObject> obj) const
|
||||
{ return (this == (PycObject*)obj); }
|
||||
|
||||
virtual void load(class PycData*, class PycModule*) { }
|
||||
|
||||
private:
|
||||
int m_refs;
|
||||
int m_type;
|
||||
|
||||
public:
|
||||
void addRef() { if (this) ++m_refs; }
|
||||
void delRef() { if (this && --m_refs == 0) delete this; }
|
||||
};
|
||||
|
||||
PycRef<PycObject> CreateObject(int type);
|
||||
PycRef<PycObject> LoadObject(class PycData* stream, class PycModule* mod);
|
||||
|
||||
/* Static Singleton objects */
|
||||
extern PycObjRef Pyc_NULL;
|
||||
extern PycObjRef Pyc_None;
|
||||
extern PycObjRef Pyc_Ellipsis;
|
||||
extern PycObjRef Pyc_StopIteration;
|
||||
extern PycRef<PycObject> Pyc_NULL;
|
||||
extern PycRef<PycObject> Pyc_None;
|
||||
extern PycRef<PycObject> Pyc_Ellipsis;
|
||||
extern PycRef<PycObject> Pyc_StopIteration;
|
||||
extern PycRef<PycObject> Pyc_False;
|
||||
extern PycRef<PycObject> Pyc_True;
|
||||
|
||||
#endif
|
||||
|
75
sequence.cpp
75
sequence.cpp
@@ -11,6 +11,21 @@ void PycTuple::load(PycData* stream, PycModule* mod)
|
||||
m_values[i] = LoadObject(stream, mod);
|
||||
}
|
||||
|
||||
bool PycTuple::isEqual(PycRef<PycObject> obj) const
|
||||
{
|
||||
PycRef<PycTuple> tupleObj = obj.cast<PycTuple>();
|
||||
if (m_size != tupleObj->m_size)
|
||||
return false;
|
||||
value_t::const_iterator it1 = m_values.begin();
|
||||
value_t::const_iterator it2 = tupleObj->m_values.begin();
|
||||
while (it1 != m_values.end()) {
|
||||
if (!(*it1)->isEqual(*it2))
|
||||
return false;
|
||||
++it1, ++it2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* PycList */
|
||||
void PycList::load(PycData* stream, PycModule* mod)
|
||||
@@ -19,3 +34,63 @@ void PycList::load(PycData* stream, PycModule* mod)
|
||||
for (int i=0; i<m_size; i++)
|
||||
m_values.push_back(LoadObject(stream, mod));
|
||||
}
|
||||
|
||||
bool PycList::isEqual(PycRef<PycObject> obj) const
|
||||
{
|
||||
PycRef<PycList> listObj = obj.cast<PycList>();
|
||||
if (m_size != listObj->m_size)
|
||||
return false;
|
||||
value_t::const_iterator it1 = m_values.begin();
|
||||
value_t::const_iterator it2 = listObj->m_values.begin();
|
||||
while (it1 != m_values.end()) {
|
||||
if (!(*it1)->isEqual(*it2))
|
||||
return false;
|
||||
++it1, ++it2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* PycDict */
|
||||
void PycDict::load(PycData* stream, PycModule* mod)
|
||||
{
|
||||
m_size = stream->get32();
|
||||
for (int i=0; i<m_size; i++)
|
||||
m_values.push_back(LoadObject(stream, mod));
|
||||
}
|
||||
|
||||
bool PycDict::isEqual(PycRef<PycObject> obj) const
|
||||
{
|
||||
PycRef<PycDict> dictObj = obj.cast<PycDict>();
|
||||
if (m_size != dictObj->m_size)
|
||||
return false;
|
||||
|
||||
key_t::const_iterator ki1 = m_keys.begin();
|
||||
key_t::const_iterator ki2 = dictObj->m_keys.begin();
|
||||
while (ki1 != m_keys.end()) {
|
||||
if (!(*ki1)->isEqual(*ki2))
|
||||
return false;
|
||||
++ki1, ++ki2;
|
||||
}
|
||||
|
||||
value_t::const_iterator vi1 = m_values.begin();
|
||||
value_t::const_iterator vi2 = dictObj->m_values.begin();
|
||||
while (vi1 != m_values.end()) {
|
||||
if (!(*vi1)->isEqual(*vi2))
|
||||
return false;
|
||||
++vi1, ++vi2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PycRef<PycObject> PycDict::get(PycRef<PycObject> key) const
|
||||
{
|
||||
key_t::const_iterator ki = m_keys.begin();
|
||||
value_t::const_iterator vi = m_values.begin();
|
||||
while (ki != m_keys.end()) {
|
||||
if ((*ki)->isEqual(key))
|
||||
return *vi;
|
||||
++ki, ++vi;
|
||||
}
|
||||
return Pyc_NULL; // Disassembly shouldn't get non-existant keys
|
||||
}
|
||||
|
36
sequence.h
36
sequence.h
@@ -12,6 +12,11 @@ public:
|
||||
PycTuple(int type = TYPE_TUPLE)
|
||||
: PycObject(type), m_size(0) { }
|
||||
|
||||
bool isType(int type) const
|
||||
{ return (type == TYPE_TUPLE) || PycObject::isType(type); }
|
||||
|
||||
bool isEqual(PycRef<PycObject> obj) const;
|
||||
|
||||
void load(class PycData* stream, class PycModule* mod);
|
||||
|
||||
int size() const { return m_size; }
|
||||
@@ -29,6 +34,11 @@ public:
|
||||
PycList(int type = TYPE_LIST)
|
||||
: PycObject(type), m_size(0) { }
|
||||
|
||||
bool isType(int type) const
|
||||
{ return (type == TYPE_LIST) || PycObject::isType(type); }
|
||||
|
||||
bool isEqual(PycRef<PycObject> obj) const;
|
||||
|
||||
void load(class PycData* stream, class PycModule* mod);
|
||||
|
||||
int size() const { return m_size; }
|
||||
@@ -39,4 +49,30 @@ private:
|
||||
value_t m_values;
|
||||
};
|
||||
|
||||
class PycDict : public PycObject {
|
||||
public:
|
||||
typedef std::list<PycRef<PycObject> > key_t;
|
||||
typedef std::list<PycRef<PycObject> > value_t;
|
||||
|
||||
PycDict(int type = TYPE_DICT)
|
||||
: PycObject(type), m_size(0) { }
|
||||
|
||||
bool isType(int type) const
|
||||
{ return (type == TYPE_DICT) || PycObject::isType(type); }
|
||||
|
||||
bool isEqual(PycRef<PycObject> obj) const;
|
||||
|
||||
void load(class PycData* stream, class PycModule* mod);
|
||||
|
||||
int size() const { return m_size; }
|
||||
PycRef<PycObject> get(PycRef<PycObject> key) const;
|
||||
key_t keys() const { return m_keys; }
|
||||
value_t values() const { return m_values; }
|
||||
|
||||
private:
|
||||
int m_size;
|
||||
key_t m_keys;
|
||||
value_t m_values;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@@ -33,6 +33,14 @@ void PycString::load(PycData* stream, PycModule* mod)
|
||||
}
|
||||
}
|
||||
|
||||
bool PycString::isEqual(PycRef<PycObject> obj) const
|
||||
{
|
||||
PycRef<PycString> strObj = obj.cast<PycString>();
|
||||
if (m_value == strObj->m_value)
|
||||
return true;
|
||||
return (strcmp(m_value, strObj->m_value) == 0);
|
||||
}
|
||||
|
||||
|
||||
void OutputString(PycRef<PycString> str, QuoteStyle style, FILE* F)
|
||||
{
|
||||
|
Reference in New Issue
Block a user