Files
Pyarmor-Static-Unpack-1shot/pyc_sequence.cpp

157 lines
3.6 KiB
C++
Raw Normal View History

2011-10-23 17:48:10 -07:00
#include "pyc_sequence.h"
#include "pyc_module.h"
2009-07-24 08:35:21 +00:00
#include "data.h"
#include <stdexcept>
2009-07-24 08:35:21 +00:00
/* PycTuple */
void PycTuple::load(PycData* stream, PycModule* mod)
{
if (type() == TYPE_SMALL_TUPLE)
m_size = stream->getByte();
else
m_size = stream->get32();
2009-07-24 08:35:21 +00:00
m_values.resize(m_size);
for (int i=0; i<m_size; i++)
m_values[i] = LoadObject(stream, mod);
}
2009-07-24 21:15:51 +00:00
bool PycTuple::isEqual(PycRef<PycObject> obj) const
{
if (type() != obj.type())
return false;
2009-07-24 21:15:51 +00:00
PycRef<PycTuple> tupleObj = obj.cast<PycTuple>();
if (m_size != tupleObj->m_size)
return false;
2022-12-01 11:35:14 -08:00
auto it1 = m_values.cbegin();
auto it2 = tupleObj->m_values.cbegin();
while (it1 != m_values.cend()) {
2009-07-24 21:15:51 +00:00
if (!(*it1)->isEqual(*it2))
return false;
++it1, ++it2;
}
return true;
}
2009-07-24 08:35:21 +00:00
/* PycList */
void PycList::load(PycData* stream, PycModule* mod)
{
m_size = stream->get32();
for (int i=0; i<m_size; i++)
m_values.push_back(LoadObject(stream, mod));
}
2009-07-24 21:15:51 +00:00
bool PycList::isEqual(PycRef<PycObject> obj) const
{
if (type() != obj.type())
return false;
2009-07-24 21:15:51 +00:00
PycRef<PycList> listObj = obj.cast<PycList>();
if (m_size != listObj->m_size)
return false;
2022-12-01 11:35:14 -08:00
auto it1 = m_values.cbegin();
auto it2 = listObj->m_values.cbegin();
while (it1 != m_values.cend()) {
2009-07-24 21:15:51 +00:00
if (!(*it1)->isEqual(*it2))
return false;
++it1, ++it2;
}
return true;
}
/* PycDict */
void PycDict::load(PycData* stream, PycModule* mod)
{
2009-07-24 21:39:51 +00:00
PycRef<PycObject> key, val;
for (;;) {
key = LoadObject(stream, mod);
if (key == NULL)
2009-07-24 21:39:51 +00:00
break;
val = LoadObject(stream, mod);
m_keys.push_back(key);
m_values.push_back(val);
}
2009-07-24 21:15:51 +00:00
}
bool PycDict::isEqual(PycRef<PycObject> obj) const
{
if (type() != obj.type())
return false;
2009-07-24 21:15:51 +00:00
PycRef<PycDict> dictObj = obj.cast<PycDict>();
if (m_size != dictObj->m_size)
return false;
2022-12-01 11:35:14 -08:00
auto ki1 = m_keys.cbegin();
auto ki2 = dictObj->m_keys.cbegin();
while (ki1 != m_keys.cend()) {
2009-07-24 21:15:51 +00:00
if (!(*ki1)->isEqual(*ki2))
return false;
++ki1, ++ki2;
}
2022-12-01 11:35:14 -08:00
auto vi1 = m_values.cbegin();
auto vi2 = dictObj->m_values.cbegin();
while (vi1 != m_values.cend()) {
2009-07-24 21:15:51 +00:00
if (!(*vi1)->isEqual(*vi2))
return false;
++vi1, ++vi2;
}
return true;
}
PycRef<PycObject> PycDict::get(PycRef<PycObject> key) const
{
2022-12-01 11:35:14 -08:00
auto ki = m_keys.cbegin();
auto vi = m_values.cbegin();
while (ki != m_keys.cend()) {
2009-07-24 21:15:51 +00:00
if ((*ki)->isEqual(key))
return *vi;
++ki, ++vi;
}
2022-12-01 11:35:14 -08:00
return NULL; // Disassembly shouldn't get non-existent keys
2009-07-24 21:15:51 +00:00
}
PycRef<PycObject> PycDict::get(int idx) const
{
if (idx < 0)
throw std::out_of_range("Dict index out of range");
2022-12-01 11:35:14 -08:00
auto it = m_values.cbegin();
while (idx-- && it != m_values.cend())
++it;
2022-12-01 11:35:14 -08:00
if (it == m_values.cend())
throw std::out_of_range("Dict index out of range");
return *it;
}
/* PycSet */
void PycSet::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 PycSet::isEqual(PycRef<PycObject> obj) const
{
if (type() != obj.type())
return false;
PycRef<PycSet> setObj = obj.cast<PycSet>();
if (m_size != setObj->m_size)
return false;
2022-12-01 11:35:14 -08:00
auto it1 = m_values.cbegin();
auto it2 = setObj->m_values.cbegin();
while (it1 != m_values.cend()) {
if (!(*it1)->isEqual(*it2))
return false;
++it1, ++it2;
}
return true;
}