1
#include "leinputstream.h"
2
#include "leoutputstream.h"
3
#include "introspection.h"
4
#include "pole.h"
5
#include <QBuffer>
6
#include <QCoreApplication>
7
#include <QDebug>
8
#include <QFile>
9
#include <QVariant>
10
#include <cstdio>
11
12
const Introspectable* parse(const QString& key, LEInputStream& in);
13
void serialize(const Introspectable* i, const QString& key, LEOutputStream& out);
14
15
using namespace std;
16
17
void
18
write(const QString& name, const QByteArray& data) {
19
    QFile out(name);
20
    out.open(QIODevice::WriteOnly);
21
    out.write(data);
22
    out.close();
23
}
24
25
bool
26
parse(const QString& file) {
27
    try {
28
        POLE::Storage storage(file.toLocal8Bit());
29
        if (!storage.open()) {
30
            qDebug() << "Cannot open file " << file << ".";
31
            return false;
32
        }
33
34
        string prefix;
35
        if (storage.isDirectory("PP97_DUALSTORAGE")) {
36
            prefix = "PP97_DUALSTORAGE/";
37
        } else {
38
            prefix = "/";
39
        }
40
41
        list<string> entries = storage.entries(prefix);
42
        for (list<string>::const_iterator i=entries.begin(); i!=entries.end(); ++i) {
43
            // if encrypted, do not report failure.
44
            if (*i == "EncryptedSummary") return true;
45
        }
46
        for (list<string>::const_iterator i=entries.begin(); i!=entries.end(); ++i) {
47
            if (!storage.isDirectory(prefix+*i)) {
48
                POLE::Stream stream(&storage, prefix+*i);
49
                QString streamname(QString::fromStdString(*i));
50
                QByteArray array;
51
                array.resize(stream.size());
52
                unsigned long read = stream.read((unsigned char*)array.data(), stream.size());
53
                if (read != stream.size()) {
54
                    qDebug() << "Error reading stream " << streamname;
55
                    return false;
56
                }
57
//                write("/tmp/"+streamname+".in", array);
58
                QBuffer buffer;
59
                buffer.setData(array);
60
                buffer.open(QIODevice::ReadOnly);
61
                LEInputStream listream(&buffer);
62
                qDebug() << "Parsing stream '" << streamname << "' of size "
63
                        << array.size();
64
                const Introspectable* i = parse(streamname, listream);
65
                if (listream.getPosition() != (qint64)stream.size()) {
66
                    qDebug() << stream.size() - listream.getPosition()
67
                        << "trailing bytes in stream " << streamname
68
                        << ", so probably an error at position "
69
                        << listream.getMaxPosition();
70
                    return false;
71
                }
72
                buffer.close();
73
74
                buffer.buffer().clear();
75
                buffer.open(QIODevice::WriteOnly);
76
                LEOutputStream lostream(&buffer);
77
                serialize(i, streamname, lostream);
78
//                write("/tmp/"+streamname+".out", buffer.data());
79
                if (array != buffer.data()) {
80
                    qDebug() << "Serialized data different from original in "
81
                        << streamname;
82
                    return false;
83
                }
84
85
86
                delete i;
87
            }
88
        }
89
    } catch (IOException& e) {
90
        qDebug() << "Error: " << e.msg;
91
        return false;
92
    }
93
    return true;
94
}
95
96
int
97
main(int argc, char** argv) {
98
    QCoreApplication app(argc, argv);
99
    if (argc < 2) return -1;
100
101
    for (int i=1; i<argc; ++i) {
102
        QString file(argv[i]);
103
        qDebug() << "Parsing of " << file;
104
        if (parse(file)) {
105
            qDebug() << "Parsing of " << file << " succeedded.";
106
        } else {
107
            qDebug() << "Parsing of " << file << " failed.";
108
        }
109
    }
110
111
    return 0;
112
}