More work on the parser and Entry/Group data structures.

This commit is contained in:
Felix Geyer 2010-08-12 21:38:59 +02:00
parent 3e3c23e4ad
commit dae532d659
14 changed files with 851 additions and 136 deletions

View File

@ -28,8 +28,75 @@ Database::Database(const QString& filename)
}
Group* Database::rootGroup()
{
return m_rootGroup;
}
void Database::setRootGroup(Group* group)
{
m_rootGroup = group;
group->setParent(this);
}
Metadata* Database::metadata()
{
return m_metadata;
}
void Database::open()
{
Parser* parser = new Parser(this);
parser->parse(m_filename);
}
QImage Database::icon(int number)
{
// TODO implement
return QImage();
}
QImage Database::customIcon(const Uuid& uuid)
{
return m_customIcons[uuid];
}
Entry* Database::resolveEntry(const Uuid& uuid)
{
return recFindEntry(uuid, m_rootGroup);
}
Entry* Database::recFindEntry(const Uuid& uuid, Group* group)
{
Q_FOREACH (Entry* entry, group->entries()) {
if (entry->uuid() == uuid)
return entry;
}
Q_FOREACH (Group* child, group->children()) {
Entry* result = recFindEntry(uuid, child);
if (result)
return result;
}
return 0;
}
Group* Database::resolveGroup(const Uuid& uuid)
{
return recFindGroup(uuid, m_rootGroup);
}
Group* Database::recFindGroup(const Uuid& uuid, Group* group)
{
if (group->uuid() == uuid)
return group;
Q_FOREACH (Group* child, group->children()) {
Group* result = recFindGroup(uuid, child);
if (result)
return result;
}
return 0;
}

View File

@ -27,20 +27,30 @@
class Metadata;
class Database
class Database : public QObject
{
Q_OBJECT
public:
Database(const QString& filename);
Group* rootGroup();
void setRootGroup(Group* group);
Metadata* metadata();
static QImage icon(int number);
QImage customIcon(const Uuid& uuid);
Entry* resolveEntry(const Uuid& uuid);
Group* resolveGroup(const Uuid& uuid);
private:
void open();
Entry* recFindEntry(const Uuid& uuid, Group* group);
Group* recFindGroup(const Uuid& uuid, Group* group);
QString m_filename;
Metadata* m_metadata;
Group* m_rootGroup;
QHash<Uuid, QImage> customImages;
DbAttribute unhandledAttirbute;
QHash<Uuid, QImage> m_customIcons;
DbAttribute m_unhandledAttirbute;
};
#endif // KEEPASSX_DATABASE_H

View File

@ -17,6 +17,145 @@
#include "Entry.h"
Entry::Entry()
#include "Group.h"
Entry::Entry() : m_group(0)
{
}
Uuid Entry::uuid() const
{
return m_uuid;
}
QImage Entry::icon() const
{
// TODO implement
}
QColor Entry::foregroundColor() const
{
return m_foregroundColor;
}
QColor Entry::backgroundColor() const
{
return m_backgroundColor;
}
QString Entry::overrideUrl() const
{
return m_overrideUrl;
}
TimeInfo Entry::timeInfo() const
{
return m_timeInfo;
}
bool Entry::autoTypeEnabled() const
{
return m_autoTypeEnabled;
}
int Entry::autoTypeObfuscation() const
{
return m_autoTypeObfuscation;
}
QString Entry::defaultAutoTypeSequence() const
{
return m_defaultAutoTypeSequence;
}
const QList<AutoTypeAssociation>& Entry::autoTypeAssociations() const
{
return m_autoTypeAssociations;
}
const QHash<QString, QString>& Entry::attributes() const
{
return m_attributes;
}
const QHash<QString, QByteArray>& Entry::attachments() const
{
return m_binaries;
}
void Entry::setUuid(const Uuid& uuid)
{
m_uuid = uuid;
}
void Entry::setIcon(int iconNumber)
{
m_iconNumber = iconNumber;
m_customIcon = Uuid();
}
void Entry::setIcon(const Uuid& uuid)
{
m_iconNumber = 0;
m_customIcon = uuid;
}
void Entry::setForegroundColor(const QColor& color)
{
m_foregroundColor = color;
}
void Entry::setBackgroundColor(const QColor& color)
{
m_backgroundColor = color;
}
void Entry::setOverrideUrl(const QString& url)
{
m_overrideUrl = url;
}
void Entry::setTimeInfo(const TimeInfo& timeInfo)
{
m_timeInfo = timeInfo;
}
void Entry::setAutoTypeEnabled(bool enable)
{
m_autoTypeEnabled = enable;
}
void Entry::setAutoTypeObfuscation(int obfuscation)
{
m_autoTypeObfuscation = obfuscation;
}
void Entry::setDefaultAutoTypeSequence(const QString& sequence)
{
m_defaultAutoTypeSequence = sequence;
}
void Entry::addAutoTypeAssociation(const AutoTypeAssociation& assoc)
{
m_autoTypeAssociations << assoc;
}
void Entry::addAttribute(const QString& key, const QString& value)
{
m_attributes.insert(key, value);
}
void Entry::addAttachment(const QString& key, const QByteArray& value)
{
m_binaries.insert(key, value);
}
void Entry::setGroup(Group* group)
{
if (m_group) {
group->removeEntry(this);
}
group->addEntry(this);
m_group = group;
QObject::setParent(group);
}

View File

@ -18,21 +18,73 @@
#ifndef KEEPASSX_ENTRY_H
#define KEEPASSX_ENTRY_H
#include <QtCore/QHash>
#include <QtCore/QUrl>
#include <QtGui/QColor>
#include <QtGui/QImage>
#include "TimeInfo.h"
#include "Uuid.h"
#include <QtCore/QHash>
class Group;
class Entry
struct AutoTypeAssociation
{
QString window;
QString sequence;
};
class Entry : public QObject
{
Q_OBJECT
public:
Entry();
Uuid uuid() const;
QImage icon() const;
QColor foregroundColor() const;
QColor backgroundColor() const;
QString overrideUrl() const;
TimeInfo timeInfo() const;
bool autoTypeEnabled() const;
int autoTypeObfuscation() const;
QString defaultAutoTypeSequence() const;
const QList<AutoTypeAssociation>& autoTypeAssociations() const;
const QHash<QString, QString>& attributes() const;
const QHash<QString, QByteArray>& attachments() const;
void setUuid(const Uuid& uuid);
void setIcon(int iconNumber);
void setIcon(const Uuid& uuid);
void setForegroundColor(const QColor& color);
void setBackgroundColor(const QColor& color);
void setOverrideUrl(const QString& url);
void setTimeInfo(const TimeInfo& timeInfo);
void setAutoTypeEnabled(bool enable);
void setAutoTypeObfuscation(int obfuscation);
void setDefaultAutoTypeSequence(const QString& sequence);
void addAutoTypeAssociation(const AutoTypeAssociation& assoc);
void addAttribute(const QString& key, const QString& value);
void addAttachment(const QString& key, const QByteArray& value);
void setGroup(Group* group);
private:
Uuid m_uuid;
int m_icon;
int m_iconNumber;
Uuid m_customIcon;
QColor m_foregroundColor;
QColor m_backgroundColor;
QString m_overrideUrl;
TimeInfo m_timeInfo;
bool m_autoTypeEnabled;
int m_autoTypeObfuscation;
QString m_defaultAutoTypeSequence;
QList<AutoTypeAssociation> m_autoTypeAssociations;
QHash<QString, QString> m_attributes;
QHash<QString, QByteArray> m_binaries;
Group* m_group;
};
#endif // KEEPASSX_ENTRY_H

View File

@ -20,3 +20,139 @@
#include "Group.h"
#include "Database.h"
Group::Group() : m_parent(0)
{
}
Uuid Group::uuid() const
{
return m_uuid;
}
QString Group::name() const
{
return m_name;
}
QString Group::notes() const
{
return m_notes;
}
QImage Group::icon() const
{
if (m_iconNumber == 0)
return m_db->customIcon(m_customIcon);
else
return Database::icon(m_iconNumber);
}
TimeInfo Group::timeInfo() const
{
return m_timeInfo;
}
bool Group::isExpanded() const
{
return m_isExpanded;
}
QString Group::defaultAutoTypeSequence() const
{
return m_defaultAutoTypeSequence;
}
Entry* Group::lastTopVisibleEntry() const
{
return m_lastTopVisibleEntry;
}
void Group::setUuid(const Uuid& uuid)
{
m_uuid = uuid;
}
void Group::setName(const QString& name)
{
m_name = name;
}
void Group::setNotes(const QString& notes)
{
m_notes = notes;
}
void Group::setIcon(int iconNumber)
{
m_iconNumber = iconNumber;
m_customIcon = Uuid();
}
void Group::setIcon(const Uuid& uuid)
{
m_iconNumber = 0;
m_customIcon = uuid;
}
void Group::setTimeInfo(const TimeInfo& timeInfo)
{
m_timeInfo = timeInfo;
}
void Group::setExpanded(bool expanded)
{
m_isExpanded = expanded;
}
void Group::setDefaultAutoTypeSequence(const QString& sequence)
{
m_defaultAutoTypeSequence = sequence;
}
void Group::setLastTopVisibleEntry(Entry* entry)
{
m_lastTopVisibleEntry = entry;
}
void Group::setParent(Group* parent)
{
if (m_parent) {
m_parent->m_children.removeAll(this);
}
m_db = parent->m_db;
QObject::setParent(parent);
}
void Group::setParent(Database* db)
{
if (m_db) {
m_db->setRootGroup(0);
}
m_parent = 0;
m_db = db;
QObject::setParent(db);
}
QList<Group*> Group::children() const
{
return m_children;
}
QList<Entry*> Group::entries() const
{
return m_entries;
}
void Group::addEntry(Entry *entry)
{
m_entries << entry;
}
void Group::removeEntry(Entry* entry)
{
m_entries.removeAll(entry);
}

View File

@ -18,19 +18,62 @@
#ifndef KEEPASSX_GROUP_H
#define KEEPASSX_GROUP_H
#include <QtGui/QImage>
#include "Entry.h"
#include "TimeInfo.h"
#include "Uuid.h"
class Group {
class Database;
class Group : public QObject
{
Q_OBJECT
public:
Group();
Uuid uuid() const;
QString name() const;
QString notes() const;
QImage icon() const;
TimeInfo timeInfo() const;
bool isExpanded() const;
QString defaultAutoTypeSequence() const;
Entry* lastTopVisibleEntry() const;
void setUuid(const Uuid& uuid);
void setName(const QString& name);
void setNotes(const QString& notes);
void setIcon(int iconNumber);
void setIcon(const Uuid& uuid);
void setTimeInfo(const TimeInfo& timeInfo);
void setExpanded(bool expanded);
void setDefaultAutoTypeSequence(const QString& sequence);
void setLastTopVisibleEntry(Entry* entry);
void setParent(Group* parent);
void setParent(Database* db);
QList<Group*> children() const;
QList<Entry*> entries() const;
void addEntry(Entry* entry);
void removeEntry(Entry* entry);
private:
Database* m_db;
Uuid m_uuid;
QString m_name;
QString m_notes;
int m_icon;
int m_iconNumber;
Uuid m_customIcon;
TimeInfo m_timeInfo;
bool m_isExpanded;
QString m_defaultAutoTypeSequence;
Entry* m_lastTopVisibleEntry;
QList<Group*> m_children;
QList<Entry*> m_entries;
QList<Entry> m_children;
Group* m_parent;
};
#endif // KEEPASSX_GROUP_H

View File

@ -24,112 +24,117 @@ Metadata::Metadata()
QString Metadata::generator() const
{
return m_generator;
};
}
QString Metadata::name() const
{
return m_name;
};
}
QDateTime Metadata::nameChanged() const
{
return m_nameChanged;
};
}
QString Metadata::description() const
{
return m_description;
};
}
QDateTime Metadata::descriptionChanged() const
{
return m_descriptionChanged;
};
}
QString Metadata::defaultUserName() const
{
return m_defaultUserName;
};
}
QDateTime Metadata::defaultUserNameChanged() const
{
return m_defaultUserNameChanged;
}
int Metadata::maintenanceHistoryDays() const
{
return m_maintenanceHistoryDays;
};
}
bool Metadata::protectTitle() const
{
return m_protectTitle;
};
}
bool Metadata::protectUsername() const
{
return m_protectUsername;
};
}
bool Metadata::protectPassword() const
{
return m_protectPassword;
};
}
bool Metadata::protectUrl() const
{
return m_protectUrl;
};
}
bool Metadata::protectNotes() const
{
return m_protectNotes;
};
}
bool Metadata::autoEnableVisualHiding() const
{
return m_autoEnableVisualHiding;
};
}
QHash<Uuid, QImage> Metadata::customIcons() const
{
return m_customIcons;
};
}
bool Metadata::recycleBinEnabled() const
{
return m_recycleBinEnabled;
};
}
Uuid Metadata::recycleBinUuid() const
{
return m_recycleBinUuid;
};
}
QDateTime Metadata::recycleBinChanged() const
{
return m_recycleBinChanged;
};
}
Uuid Metadata::entryTemplatesGroup() const
{
return m_entryTemplatesGroup;
};
}
QDateTime Metadata::entryTemplatesGroupChanged() const
{
return m_entryTemplatesGroupChanged;
};
}
Uuid Metadata::lastSelectedGroup() const
{
return m_lastSelectedGroup;
};
}
Uuid Metadata::lastTopVisibleGroup() const
{
return m_lastTopVisibleGroup;
};
}
QHash<QString, QString> Metadata::customFields() const
{
return m_customFields;
};
}
void Metadata::setGenerator(const QString& value)
{
@ -161,6 +166,11 @@ void Metadata::setDefaultUserName(const QString& value)
m_defaultUserName = value;
}
void Metadata::setDefaultUserNameChanged(const QDateTime& value)
{
m_defaultUserNameChanged = value;
}
void Metadata::setMaintenanceHistoryDays(int value)
{
m_maintenanceHistoryDays = value;

View File

@ -35,6 +35,7 @@ public:
QString description() const;
QDateTime descriptionChanged() const;
QString defaultUserName() const;
QDateTime defaultUserNameChanged() const;
int maintenanceHistoryDays() const;
bool protectTitle() const;
bool protectUsername() const;
@ -58,6 +59,7 @@ public:
void setDescription(const QString& value);
void setDescriptionChanged(const QDateTime& value);
void setDefaultUserName(const QString& value);
void setDefaultUserNameChanged(const QDateTime& value);
void setMaintenanceHistoryDays(int value);
void setProtectTitle(bool value);
void setProtectUsername(bool value);
@ -84,6 +86,7 @@ private:
QString m_description;
QDateTime m_descriptionChanged;
QString m_defaultUserName;
QDateTime m_defaultUserNameChanged;
int m_maintenanceHistoryDays;
bool m_protectTitle;

View File

@ -19,9 +19,13 @@
#include <QtCore/QFile>
#include "Database.h"
#include "Metadata.h"
Parser::Parser(Database* db)
{
m_db = db;
m_meta = db->metadata();
}
bool Parser::parse(const QString& filename)
@ -30,16 +34,22 @@ bool Parser::parse(const QString& filename)
file.open(QIODevice::ReadOnly | QIODevice::Text);
m_xml.setDevice(&file);
m_tmpParent = new Group();
if (m_xml.readNextStartElement()) {
if (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "KeePassFile") {
parseKeePassFile();
}
else {
m_xml.raiseError(tr("Invalid database file"));
raiseError();
}
}
if (!m_tmpParent->children().isEmpty()) {
delete m_tmpParent;
raiseError();
}
return !m_xml.error();
}
@ -47,7 +57,7 @@ void Parser::parseKeePassFile()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "KeePassFile");
while (m_xml.readNextStartElement()) {
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Meta") {
parseMeta();
}
@ -55,7 +65,7 @@ void Parser::parseKeePassFile()
parseRoot();
}
else {
m_xml.raiseError(tr("Invalid database file"));
m_xml.skipCurrentElement();
}
}
}
@ -64,30 +74,30 @@ void Parser::parseMeta()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Meta");
while (m_xml.readNextStartElement()) {
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Generator") {
m_meta->setGenerator(readString());
}
else if (m_xml.name() == "DatabaseName") {
m_meta->setName(readString());
}
else if (m_xml.name() == "DatabaseNameChanged") {
m_meta->setNameChanged(readDateTime());
}
else if (m_xml.name() == "DatabaseDescription") {
m_meta->setDescription(readString());
}
else if (m_xml.name() == "DatabaseDescriptionChanged") {
m_meta->setDescriptionChanged(readDateTime());
}
else if (m_xml.name() == "DefaultUserName") {
m_meta->setDefaultUserName(readString());
}
else if (m_xml.name() == "DefaultUserNameChanged") {
m_meta->setDefaultUserNameChanged(readDateTime());
}
else if (m_xml.name() == "MaintenanceHistoryDays") {
m_meta->setMaintenanceHistoryDays(readNumber());
}
else if (m_xml.name() == "MemoryProtection") {
parseMemoryProtection();
@ -96,25 +106,25 @@ void Parser::parseMeta()
parseCustomIcons();
}
else if (m_xml.name() == "RecycleBinEnabled") {
m_meta->setRecycleBinEnabled(readBool());
}
else if (m_xml.name() == "RecycleBinUUID") {
m_meta->setRecycleBinUuid(readUuid());
}
else if (m_xml.name() == "RecycleBinChanged") {
m_meta->setRecycleBinChanged(readDateTime());
}
else if (m_xml.name() == "EntryTemplatesGroup") {
m_meta->setEntryTemplatesGroup(readUuid());
}
else if (m_xml.name() == "EntryTemplatesGroupChanged") {
m_meta->setEntryTemplatesGroupChanged(readDateTime());
}
else if (m_xml.name() == "LastSelectedGroup") {
m_meta->setLastSelectedGroup(readUuid());
}
else if (m_xml.name() == "LastTopVisibleGroup") {
m_meta->setLastTopVisibleGroup(readUuid());
}
else if (m_xml.name() == "CustomData") {
parseCustomData();
@ -129,24 +139,24 @@ void Parser::parseMemoryProtection()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "MemoryProtection");
while (m_xml.readNextStartElement()) {
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "ProtectTitle") {
m_meta->setProtectTitle(readBool());
}
else if (m_xml.name() == "ProtectUserName") {
m_meta->setProtectUsername(readBool());
}
else if (m_xml.name() == "ProtectPassword") {
m_meta->setProtectPassword(readBool());
}
else if (m_xml.name() == "ProtectURL") {
m_meta->setProtectUrl(readBool());
}
else if (m_xml.name() == "ProtectNotes") {
m_meta->setProtectNotes(readBool());
}
else if (m_xml.name() == "AutoEnableVisualHiding") {
m_meta->setAutoEnableVisualHiding(readBool());
}
else {
m_xml.skipCurrentElement();
@ -158,7 +168,7 @@ void Parser::parseCustomIcons()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "CustomIcons");
while (m_xml.readNextStartElement()) {
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Icon") {
parseIcon();
}
@ -172,12 +182,15 @@ void Parser::parseIcon()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Icon");
while (m_xml.readNextStartElement()) {
Uuid uuid;
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "UUID") {
uuid = readUuid();
}
else if (m_xml.name() == "Data") {
QImage image;
image.loadFromData(readBinary());
m_meta->addCustomIcon(uuid, image);
}
else {
m_xml.skipCurrentElement();
@ -196,12 +209,15 @@ void Parser::parseRoot()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Root");
while (m_xml.readNextStartElement()) {
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Group") {
parseGroup();
Group* rootGroup = parseGroup();
if (rootgroup) {
rootGroup->setParent(m_db);
}
}
else if (m_xml.name() == "DeletedObjects") {
// ?????????????????
// TODO implement
}
else {
m_xml.skipCurrentElement();
@ -209,87 +225,125 @@ void Parser::parseRoot()
}
}
void Parser::parseGroup()
Group* Parser::parseGroup()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Group");
while (m_xml.readNextStartElement()) {
Group* group = 0;
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "UUID") {
Uuid uuid = readUuid();
if (uuid.isNull()) {
raiseError();
}
else {
group = getGroup(uuid);
}
}
else if (m_xml.name() == "Name") {
group->setName(readString());
}
else if (m_xml.name() == "Notes") {
group->setNotes(readString());
}
else if (m_xml.name() == "IconID") {
int iconId = readNumber();
if (iconId != 0)
group->setIcon(iconId);
}
else if (m_xml.name() == "CustomIconUUID") {
Uuid uuid = readUuid();
if (!uuid.isNull()) {
group->setIcon(uuid);
}
}
else if (m_xml.name() == "Times") {
parseTimes();
group->setTimeInfo(parseTimes());
}
else if (m_xml.name() == "IsExpanded") {
group->setExpanded(readBool());
}
else if (m_xml.name() == "DefaultAutoTypeSequence") {
group->setDefaultAutoTypeSequence(readString());
}
else if (m_xml.name() == "EnableAutoType") {
// TODO implement
}
else if (m_xml.name() == "EnableSearching") {
// TODO implement
}
else if (m_xml.name() == "LastTopVisibleEntry") {
Uuid uuid = readUuid();
if (uuid.isNull())
group->setLastTopVisibleEntry(0);
else
group->setLastTopVisibleEntry(getEntry(uuid));
}
else if (m_xml.name() == "Group") {
parseGroup();
Group* newGroup = parseGroup();
if (newGroup) {
newGroup->setParent(group);
}
}
else if (m_xml.name() == "Entry") {
parseEntry();
Entry* newEntry = parseEntry();
if (newEntry) {
newEntry->setGroup(group);
}
}
else {
m_xml.skipCurrentElement();
}
}
return group;
}
void Parser::parseEntry()
Entry* Parser::parseEntry()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Entry");
while (m_xml.readNextStartElement()) {
Entry* entry = 0;
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "UUID") {
Uuid uuid = readUuid();
if (uuid.isNull()) {
raiseError();
}
else {
entry = getEntry(uuid);
}
}
else if (m_xml.name() == "IconID") {
int iconId = readNumber();
if (iconId != 0)
entry->setIcon(iconId);
}
else if (m_xml.name() == "CustomIconUUID") {
Uuid uuid = readUuid();
if (!uuid.isNull())
entry->setIcon(uuid);
}
else if (m_xml.name() == "ForegroundColor") {
entry->setForegroundColor(readColor());
}
else if (m_xml.name() == "BackgroundColor") {
entry->setBackgroundColor(readColor());
}
else if (m_xml.name() == "OverrideURL") {
entry->setOverrideUrl(readString());
}
else if (m_xml.name() == "Times") {
parseTimes();
entry->setTimeInfo(parseTimes());
}
else if (m_xml.name() == "String") {
parseEntryString();
parseEntryString(entry);
}
else if (m_xml.name() == "Binary") {
parseEntryBinary();
parseEntryBinary(entry);
}
else if (m_xml.name() == "AutoType") {
parseAutoType();
parseAutoType(entry);
}
else if (m_xml.name() == "History") {
parseEntryHistory();
@ -300,16 +354,17 @@ void Parser::parseEntry()
}
}
void Parser::parseEntryString()
void Parser::parseEntryString(Entry *entry)
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "String");
while (m_xml.readNextStartElement()) {
QString key;
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Key") {
key = readString();
}
else if (m_xml.name() == "Value") {
entry->addAttribute(key, readString());
}
else {
m_xml.skipCurrentElement();
@ -317,16 +372,17 @@ void Parser::parseEntryString()
}
}
void Parser::parseEntryBinary()
void Parser::parseEntryBinary(Entry *entry)
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Binary");
while (m_xml.readNextStartElement()) {
QString key;
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Key") {
key = readString();
}
else if (m_xml.name() == "Value") {
entry->addAttachment(key, readBinary());
}
else {
m_xml.skipCurrentElement();
@ -334,19 +390,22 @@ void Parser::parseEntryBinary()
}
}
void Parser::parseAutoType()
void Parser::parseAutoType(Entry* entry)
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "AutoType");
while (m_xml.readNextStartElement()) {
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Enabled") {
entry->setAutoTypeEnabled(readBool());
}
else if (m_xml.name() == "DataTransferObfuscation") {
entry->setAutoTypeObfuscation(readNumber());
}
else if (m_xml.name() == "DefaultSequence") {
entry->setDefaultAutoTypeSequence(readString());
}
else if (m_xml.name() == "Association") {
parseAutoTypeAssoc();
parseAutoTypeAssoc(entry);
}
else {
m_xml.skipCurrentElement();
@ -354,16 +413,18 @@ void Parser::parseAutoType()
}
}
void Parser::parseAutoTypeAssoc()
void Parser::parseAutoTypeAssoc(Entry *entry)
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Association");
while (m_xml.readNextStartElement()) {
AutoTypeAssociation assoc;
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Window") {
assoc.window = readString();
}
else if (m_xml.name() == "KeystrokeSequence") {
assoc.sequence = readString();
entry->addAutoTypeAssociation(assoc);
}
else {
m_xml.skipCurrentElement();
@ -375,9 +436,9 @@ void Parser::parseEntryHistory()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "History");
while (m_xml.readNextStartElement()) {
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "Entry") {
parseEntry();
// TODO implement
}
else {
m_xml.skipCurrentElement();
@ -385,36 +446,39 @@ void Parser::parseEntryHistory()
}
}
void Parser::parseTimes()
TimeInfo Parser::parseTimes()
{
Q_ASSERT(m_xml.isStartElement() && m_xml.name() == "Times");
while (m_xml.readNextStartElement()) {
TimeInfo timeInfo;
while (!m_xml.error() && m_xml.readNextStartElement()) {
if (m_xml.name() == "LastModificationTime") {
timeInfo.setLastModificationTime(readDateTime());
}
else if (m_xml.name() == "CreationTime") {
timeInfo.setCreationTime(readDateTime());
}
else if (m_xml.name() == "LastAccessTime") {
timeInfo.setLastAccessTime(readDateTime());
}
else if (m_xml.name() == "ExpiryTime") {
timeInfo.setExpiryTime(readDateTime());
}
else if (m_xml.name() == "Expires") {
timeInfo.setExpires(readBool());
}
else if (m_xml.name() == "UsageCount") {
timeInfo.setUsageCount(readNumber());
}
else if (m_xml.name() == "LocationChanged") {
timeInfo.setLocationChanged(readDateTime());
}
else {
m_xml.skipCurrentElement();
}
}
return timeInfo;
}
QString Parser::readString()
@ -433,7 +497,7 @@ bool Parser::readBool()
return false;
}
else {
// TODO error
raiseError();
}
}
@ -443,23 +507,102 @@ QDateTime Parser::readDateTime()
QDateTime dt = QDateTime::fromString(str, Qt::ISODate);
if (!dt.isValid()) {
// TODO error
raiseError();
}
return dt;
}
int Parser::readInt()
QColor Parser::readColor()
{
// TODO
QString colorStr = readString();
if (colorStr.length() != 7 || colorStr[0] != '#') {
raiseError();
return QColor();
}
QColor color;
for (int i=0; i<= 2; i++) {
QString rgbPartStr = colorStr.mid(1 + 2*i, 2);
bool ok;
int rgbPart = rgbPartStr.toInt(&ok);
if (!ok || rgbPart > 255) {
raiseError();
return QColor();
}
if (i == 0) {
color.setRed(rgbPart);
}
else if (i == 1) {
color.setGreen(rgbPart);
}
else {
color.setBlue(rgbPart);
}
}
return color;
}
int Parser::readNumber()
{
bool ok;
int result = readString().toInt(&ok);
if (!ok) {
raiseError();
}
return result;
}
Uuid Parser::readUuid()
{
// TODO
QByteArray uuidBin = readBinary();
if (uuidBin.length() != Uuid::length) {
raiseError();
return Uuid();
}
else {
return Uuid(readBinary());
}
}
QByteArray Parser::readBinary()
{
// TODO
return QByteArray::fromBase64(readString().toAscii());
}
Group* Parser::getGroup(const Uuid& uuid)
{
Q_FOREACH (Group* group, m_groups) {
if (group->uuid() == uuid) {
return group;
}
}
Group* group = new Group();
group->setUuid(uuid);
group->setParent(m_tmpParent);
m_groups << group;
return group;
}
Entry* Parser::getEntry(const Uuid& uuid)
{
Q_FOREACH (Entry* entry, m_entries) {
if (entry->uuid() == uuid) {
return entry;
}
}
Entry* entry = new Entry();
entry->setUuid(uuid);
entry->setGroup(m_tmpParent);
m_entries << entry;
return entry;
}
void Parser::raiseError()
{
m_xml.raiseError(tr("Invalid database file"));
}

View File

@ -20,10 +20,14 @@
#include <QtCore/QDateTime>
#include <QtCore/QXmlStreamReader>
#include <QtGui/QColor>
#include "Uuid.h"
class Database;
class Entry;
class Group;
class Metadata;
class Parser : public QObject
{
@ -41,24 +45,33 @@ private:
void parseIcon();
void parseCustomData();
void parseRoot();
void parseGroup();
void parseEntry();
void parseEntryString();
void parseEntryBinary();
void parseAutoType();
void parseAutoTypeAssoc();
Group* parseGroup();
Entry* parseEntry();
void parseEntryString(Entry* entry);
void parseEntryBinary(Entry* entry);
void parseAutoType(Entry* entry);
void parseAutoTypeAssoc(Entry* entry);
void parseEntryHistory();
void parseTimes();
TimeInfo parseTimes();
QString readString();
bool readBool();
QDateTime readDateTime();
int readInt();
QColor readColor();
int readNumber();
Uuid readUuid();
QByteArray readBinary();
Group* getGroup(const Uuid& uuid);
Entry* getEntry(const Uuid& uuid);
void raiseError();
QXmlStreamReader m_xml;
Database* m_db;
Metadata* m_meta;
Group* m_tmpParent;
QList<Group*> m_groups;
QList<Entry*> m_entries;
};
#endif // KEEPASSX_PARSER_H

View File

@ -20,3 +20,72 @@
TimeInfo::TimeInfo()
{
}
QDateTime TimeInfo::lastModificationTime() const
{
return m_lastModificationTime;
}
QDateTime TimeInfo::creationTime() const
{
return m_creationTime;
}
QDateTime TimeInfo::lastAccessTime() const
{
return m_lastAccessTime;
}
QDateTime TimeInfo::expiryTime() const
{
return m_expiryTime;
}
bool TimeInfo::expires() const
{
return m_expires;
}
int TimeInfo::usageCount() const
{
return m_usageCount;
}
QDateTime TimeInfo::locationChanged() const
{
return m_locationChanged;
}
void TimeInfo::setLastModificationTime(const QDateTime& dateTime)
{
m_lastModificationTime = dateTime;
}
void TimeInfo::setCreationTime(const QDateTime& dateTime)
{
m_creationTime = dateTime;
}
void TimeInfo::setLastAccessTime(const QDateTime& dateTime)
{
m_lastAccessTime = dateTime;
}
void TimeInfo::setExpiryTime(const QDateTime& dateTime)
{
m_expiryTime = dateTime;
}
void TimeInfo::setExpires(bool expires)
{
m_expires = expires;
}
void TimeInfo::setUsageCount(int count)
{
m_usageCount = count;
}
void TimeInfo::setLocationChanged(const QDateTime& dateTime)
{
m_locationChanged = dateTime;
}

View File

@ -18,10 +18,37 @@
#ifndef KEEPASSX_DBTIMEINFO_H
#define KEEPASSX_DBTIMEINFO_H
#include <QtCore/QDateTime>
class TimeInfo
{
public:
TimeInfo();
QDateTime lastModificationTime() const;
QDateTime creationTime() const;
QDateTime lastAccessTime() const;
QDateTime expiryTime() const;
bool expires() const;
int usageCount() const;
QDateTime locationChanged() const;
void setLastModificationTime(const QDateTime& dateTime);
void setCreationTime(const QDateTime& dateTime);
void setLastAccessTime(const QDateTime& dateTime);
void setExpiryTime(const QDateTime& dateTime);
void setExpires(bool expires);
void setUsageCount(int count);
void setLocationChanged(const QDateTime& dateTime);
private:
QDateTime m_lastModificationTime;
QDateTime m_creationTime;
QDateTime m_lastAccessTime;
QDateTime m_expiryTime;
bool m_expires;
int m_usageCount;
QDateTime m_locationChanged;
};
#endif // KEEPASSX_DBTIMEINFO_H

View File

@ -17,11 +17,13 @@
#include "Uuid.h"
Uuid::Uuid() : m_data(16, 0)
const int Uuid::length = 16;
Uuid::Uuid() : m_data(length, 0)
{
}
Uuid::Uuid(bool generate) : m_data(16, 0)
Uuid::Uuid(bool generate) : m_data(length, 0)
{
if (generate) {
while (isNull()) {

View File

@ -32,6 +32,7 @@ public:
bool isNull() const;
bool operator==(const Uuid& other) const;
bool operator!=(const Uuid& other) const;
static const int length;
private:
QByteArray m_data;