Remove usage of QtXml from rcc, add test

Ported from QDom to QXmlStreamReader. This enables removal of QtXml
classes from bootstrap.

A new rcc test was added, copying the data from the
QResourceFileEngine test. The new test runs rcc to create binary
resources, dynamically loads them under various locales and checks
that they do contain the expected files.

Change-Id: I15d23dfda45de851a421156951ce2a60af4c1f7f
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
Giuseppe D'Angelo 2012-02-26 21:04:57 +00:00 committed by Qt by Nokia
parent a27d5be4dc
commit 84984af0e1
46 changed files with 923 additions and 133 deletions

View File

@ -50,8 +50,7 @@
#include <QtCore/QIODevice>
#include <QtCore/QLocale>
#include <QtCore/QStack>
#include <QtXml/QDomDocument>
#include <QtCore/QXmlStreamReader>
QT_BEGIN_NAMESPACE
@ -356,6 +355,12 @@ RCCResourceLibrary::~RCCResourceLibrary()
delete m_root;
}
enum RCCXmlTag {
RccTag,
ResourceTag,
FileTag
};
bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
const QString &fname, QString currentPath, bool ignoreErrors)
{
@ -364,98 +369,168 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
if (!currentPath.isEmpty() && !currentPath.endsWith(slash))
currentPath += slash;
QDomDocument document;
{
QString errorMsg;
int errorLine = 0;
int errorColumn = 0;
if (!document.setContent(inputDevice, &errorMsg, &errorLine, &errorColumn)) {
if (ignoreErrors)
return true;
const QString msg = QString::fromUtf8("RCC Parse Error: '%1' Line: %2 Column: %3 [%4]\n").arg(fname).arg(errorLine).arg(errorColumn).arg(errorMsg);
m_errorDevice->write(msg.toUtf8());
return false;
}
}
QXmlStreamReader reader(inputDevice);
QStack<RCCXmlTag> tokens;
QDomElement domRoot = document.firstChildElement(m_strings.TAG_RCC).toElement();
if (!domRoot.isNull() && domRoot.tagName() == m_strings.TAG_RCC) {
for (QDomNode node = domRoot.firstChild(); !node.isNull(); node = node.nextSibling()) {
if (!node.isElement())
continue;
QString prefix;
QLocale::Language language = QLocale::c().language();
QLocale::Country country = QLocale::c().country();
QString alias;
int compressLevel = m_compressLevel;
int compressThreshold = m_compressThreshold;
QDomElement child = node.toElement();
if (!child.isNull() && child.tagName() == m_strings.TAG_RESOURCE) {
QLocale::Language language = QLocale::c().language();
QLocale::Country country = QLocale::c().country();
while (!reader.atEnd()) {
QXmlStreamReader::TokenType t = reader.readNext();
switch (t) {
case QXmlStreamReader::StartElement:
if (reader.name() == m_strings.TAG_RCC) {
if (!tokens.isEmpty())
reader.raiseError(QLatin1String("expected <RCC> tag"));
else
tokens.push(RccTag);
} else if (reader.name() == m_strings.TAG_RESOURCE) {
if (tokens.isEmpty() || tokens.top() != RccTag) {
reader.raiseError(QLatin1String("unexpected <RESOURCE> tag"));
} else {
tokens.push(ResourceTag);
if (child.hasAttribute(m_strings.ATTRIBUTE_LANG)) {
QString attribute = child.attribute(m_strings.ATTRIBUTE_LANG);
QLocale lang = QLocale(attribute);
language = lang.language();
if (2 == attribute.length()) {
// Language only
country = QLocale::AnyCountry;
} else {
country = lang.country();
QXmlStreamAttributes attributes = reader.attributes();
language = QLocale::c().language();
country = QLocale::c().country();
if (attributes.hasAttribute(m_strings.ATTRIBUTE_LANG)) {
QString attribute = attributes.value(m_strings.ATTRIBUTE_LANG).toString();
QLocale lang = QLocale(attribute);
language = lang.language();
if (2 == attribute.length()) {
// Language only
country = QLocale::AnyCountry;
} else {
country = lang.country();
}
}
prefix.clear();
if (attributes.hasAttribute(m_strings.ATTRIBUTE_PREFIX))
prefix = attributes.value(m_strings.ATTRIBUTE_PREFIX).toString();
if (!prefix.startsWith(slash))
prefix.prepend(slash);
if (!prefix.endsWith(slash))
prefix += slash;
}
} else if (reader.name() == m_strings.TAG_FILE) {
if (tokens.isEmpty() || tokens.top() != ResourceTag) {
reader.raiseError(QLatin1String("unexpected <FILE> tag"));
} else {
tokens.push(FileTag);
QXmlStreamAttributes attributes = reader.attributes();
alias.clear();
if (attributes.hasAttribute(m_strings.ATTRIBUTE_ALIAS))
alias = attributes.value(m_strings.ATTRIBUTE_ALIAS).toString();
compressLevel = m_compressLevel;
if (attributes.hasAttribute(m_strings.ATTRIBUTE_COMPRESS))
compressLevel = attributes.value(m_strings.ATTRIBUTE_COMPRESS).toString().toInt();
compressThreshold = m_compressThreshold;
if (attributes.hasAttribute(m_strings.ATTRIBUTE_THRESHOLD))
compressThreshold = attributes.value(m_strings.ATTRIBUTE_THRESHOLD).toString().toInt();
// Special case for -no-compress. Overrides all other settings.
if (m_compressLevel == -2)
compressLevel = 0;
}
} else {
reader.raiseError(QString(QLatin1String("unexpected tag: %1")).arg(reader.name().toString()));
}
break;
case QXmlStreamReader::EndElement:
if (reader.name() == m_strings.TAG_RCC) {
if (!tokens.isEmpty() && tokens.top() == RccTag)
tokens.pop();
else
reader.raiseError(QLatin1String("unexpected closing tag"));
} else if (reader.name() == m_strings.TAG_RESOURCE) {
if (!tokens.isEmpty() && tokens.top() == ResourceTag)
tokens.pop();
else
reader.raiseError(QLatin1String("unexpected closing tag"));
} else if (reader.name() == m_strings.TAG_FILE) {
if (!tokens.isEmpty() && tokens.top() == FileTag)
tokens.pop();
else
reader.raiseError(QLatin1String("unexpected closing tag"));
}
break;
case QXmlStreamReader::Characters:
if (reader.isWhitespace())
break;
if (tokens.isEmpty() || tokens.top() != FileTag) {
reader.raiseError(QLatin1String("unexpected text"));
} else {
QString fileName = reader.text().toString();
if (fileName.isEmpty()) {
const QString msg = QString::fromLatin1("RCC: Warning: Null node in XML of '%1'\n").arg(fname);
m_errorDevice->write(msg.toUtf8());
}
QString prefix;
if (child.hasAttribute(m_strings.ATTRIBUTE_PREFIX))
prefix = child.attribute(m_strings.ATTRIBUTE_PREFIX);
if (!prefix.startsWith(slash))
prefix.prepend(slash);
if (!prefix.endsWith(slash))
prefix += slash;
if (alias.isNull())
alias = fileName;
for (QDomNode res = child.firstChild(); !res.isNull(); res = res.nextSibling()) {
if (res.isElement() && res.toElement().tagName() == m_strings.TAG_FILE) {
alias = QDir::cleanPath(alias);
while (alias.startsWith(QLatin1String("../")))
alias.remove(0, 3);
alias = QDir::cleanPath(m_resourceRoot) + prefix + alias;
QString fileName(res.firstChild().toText().data());
if (fileName.isEmpty()) {
const QString msg = QString::fromUtf8("RCC: Warning: Null node in XML of '%1'\n").arg(fname);
m_errorDevice->write(msg.toUtf8());
}
QString alias;
if (res.toElement().hasAttribute(m_strings.ATTRIBUTE_ALIAS))
alias = res.toElement().attribute(m_strings.ATTRIBUTE_ALIAS);
else
alias = fileName;
int compressLevel = m_compressLevel;
if (res.toElement().hasAttribute(m_strings.ATTRIBUTE_COMPRESS))
compressLevel = res.toElement().attribute(m_strings.ATTRIBUTE_COMPRESS).toInt();
int compressThreshold = m_compressThreshold;
if (res.toElement().hasAttribute(m_strings.ATTRIBUTE_THRESHOLD))
compressThreshold = res.toElement().attribute(m_strings.ATTRIBUTE_THRESHOLD).toInt();
// Special case for -no-compress. Overrides all other settings.
if (m_compressLevel == -2)
compressLevel = 0;
alias = QDir::cleanPath(alias);
while (alias.startsWith(QLatin1String("../")))
alias.remove(0, 3);
alias = QDir::cleanPath(m_resourceRoot) + prefix + alias;
QString absFileName = fileName;
if (QDir::isRelativePath(absFileName))
absFileName.prepend(currentPath);
QFileInfo file(absFileName);
if (!file.exists()) {
m_failedResources.push_back(absFileName);
const QString msg = QString::fromUtf8("RCC: Error in '%1': Cannot find file '%2'\n").arg(fname).arg(fileName);
m_errorDevice->write(msg.toUtf8());
if (ignoreErrors)
continue;
else
return false;
} else if (file.isFile()) {
QString absFileName = fileName;
if (QDir::isRelativePath(absFileName))
absFileName.prepend(currentPath);
QFileInfo file(absFileName);
if (!file.exists()) {
m_failedResources.push_back(absFileName);
const QString msg = QString::fromLatin1("RCC: Error in '%1': Cannot find file '%2'\n").arg(fname).arg(fileName);
m_errorDevice->write(msg.toUtf8());
if (ignoreErrors)
continue;
else
return false;
} else if (file.isFile()) {
const bool arc =
addFile(alias,
RCCFileInfo(alias.section(slash, -1),
file,
language,
country,
RCCFileInfo::NoFlags,
compressLevel,
compressThreshold)
);
if (!arc)
m_failedResources.push_back(absFileName);
} else {
QDir dir;
if (file.isDir()) {
dir.setPath(file.filePath());
} else {
dir.setPath(file.path());
dir.setNameFilters(QStringList(file.fileName()));
if (alias.endsWith(file.fileName()))
alias = alias.left(alias.length()-file.fileName().length());
}
if (!alias.endsWith(slash))
alias += slash;
QDirIterator it(dir, QDirIterator::FollowSymlinks|QDirIterator::Subdirectories);
while (it.hasNext()) {
it.next();
QFileInfo child(it.fileInfo());
if (child.fileName() != QLatin1String(".") && child.fileName() != QLatin1String("..")) {
const bool arc =
addFile(alias,
RCCFileInfo(alias.section(slash, -1),
file,
addFile(alias + child.fileName(),
RCCFileInfo(child.fileName(),
child,
language,
country,
RCCFileInfo::NoFlags,
@ -463,44 +538,29 @@ bool RCCResourceLibrary::interpretResourceFile(QIODevice *inputDevice,
compressThreshold)
);
if (!arc)
m_failedResources.push_back(absFileName);
} else {
QDir dir;
if (file.isDir()) {
dir.setPath(file.filePath());
} else {
dir.setPath(file.path());
dir.setNameFilters(QStringList(file.fileName()));
if (alias.endsWith(file.fileName()))
alias = alias.left(alias.length()-file.fileName().length());
}
if (!alias.endsWith(slash))
alias += slash;
QDirIterator it(dir, QDirIterator::FollowSymlinks|QDirIterator::Subdirectories);
while (it.hasNext()) {
it.next();
QFileInfo child(it.fileInfo());
if (child.fileName() != QLatin1String(".") && child.fileName() != QLatin1String("..")) {
const bool arc =
addFile(alias + child.fileName(),
RCCFileInfo(child.fileName(),
child,
language,
country,
RCCFileInfo::NoFlags,
compressLevel,
compressThreshold)
);
if (!arc)
m_failedResources.push_back(child.fileName());
}
}
m_failedResources.push_back(child.fileName());
}
}
}
}
break;
default:
break;
}
}
if (reader.hasError()) {
if (ignoreErrors)
return true;
int errorLine = reader.lineNumber();
int errorColumn = reader.columnNumber();
QString errorMessage = reader.errorString();
QString msg = QString::fromLatin1("RCC Parse Error: '%1' Line: %2 Column: %3 [%4]\n").arg(fname).arg(errorLine).arg(errorColumn).arg(errorMessage);
m_errorDevice->write(msg.toUtf8());
return false;
}
if (m_root == 0) {
const QString msg = QString::fromUtf8("RCC: Warning: No resources in '%1'.\n").arg(fname);
m_errorDevice->write(msg.toUtf8());

View File

@ -1 +1,2 @@
tst_rcc
data/binary/*.rcc

View File

@ -0,0 +1 @@
"This is a korean text file"

View File

@ -0,0 +1,322 @@
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

View File

@ -0,0 +1,4 @@
currentdir.txt currentdir.txt
alias.txt currentdir2.txt
otheralias.txt blahblah.txt
alias3 ../parentdir.txt

View File

@ -0,0 +1,10 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>currentdir.txt</file>
<file alias="alias.txt">currentdir2.txt</file>
<file alias="otheralias.txt">blahblah.txt</file>
</qresource>
<qresource>
<file alias="alias3">../parentdir.txt</file>
</qresource>
</RCC>

View File

@ -0,0 +1,13 @@
/test/abc/123/+++/currentdir.txt currentdir.txt
/test/abc/123/+++/currentdir2.txt ./currentdir2.txt
/test/abc/123/+++/parentdir.txt ../parentdir.txt
/test/abc/123/+++/subdir/subdir.txt subdir/subdir.txt
/search_file.txt search_file.txt
/searchpath1/search_file.txt searchpath1/search_file.txt
/searchpath2/search_file.txt searchpath2/search_file.txt
test/testdir.txt test/testdir.txt
otherdir/otherdir.txt otherdir/otherdir.txt
aliasdir/aliasdir.txt test/german.txt
test/test/test1.txt test/test/test1.txt
test/test/test2.txt test/test/test2.txt
withoutslashes/blahblah.txt blahblah.txt

View File

@ -0,0 +1,13 @@
/test/abc/123/+++/currentdir.txt currentdir.txt
/test/abc/123/+++/currentdir2.txt ./currentdir2.txt
/test/abc/123/+++/parentdir.txt ../parentdir.txt
/test/abc/123/+++/subdir/subdir.txt subdir/subdir.txt
/search_file.txt search_file.txt
/searchpath1/search_file.txt searchpath1/search_file.txt
/searchpath2/search_file.txt searchpath2/search_file.txt
test/testdir.txt test/testdir.txt
otherdir/otherdir.txt otherdir/otherdir.txt
aliasdir/aliasdir.txt aliasdir/compressme.txt
test/test/test1.txt test/test/test1.txt
test/test/test2.txt test/test/test2.txt
withoutslashes/blahblah.txt blahblah.txt

View File

@ -0,0 +1,13 @@
/test/abc/123/+++/currentdir.txt currentdir.txt
/test/abc/123/+++/currentdir2.txt ./currentdir2.txt
/test/abc/123/+++/parentdir.txt ../parentdir.txt
/test/abc/123/+++/subdir/subdir.txt subdir/subdir.txt
/search_file.txt search_file.txt
/searchpath1/search_file.txt searchpath1/search_file.txt
/searchpath2/search_file.txt searchpath2/search_file.txt
test/testdir.txt test/testdir.txt
otherdir/otherdir.txt otherdir/otherdir.txt
aliasdir/aliasdir.txt test/testdir2.txt
test/test/test1.txt test/test/test1.txt
test/test/test2.txt test/test/test2.txt
withoutslashes/blahblah.txt blahblah.txt

View File

@ -0,0 +1,13 @@
/test/abc/123/+++/currentdir.txt currentdir.txt
/test/abc/123/+++/currentdir2.txt ./currentdir2.txt
/test/abc/123/+++/parentdir.txt ../parentdir.txt
/test/abc/123/+++/subdir/subdir.txt subdir/subdir.txt
/search_file.txt search_file.txt
/searchpath1/search_file.txt searchpath1/search_file.txt
/searchpath2/search_file.txt searchpath2/search_file.txt
test/testdir.txt test/testdir.txt
otherdir/otherdir.txt otherdir/otherdir.txt
aliasdir/aliasdir.txt aliasdir/aliasdir.txt
test/test/test1.txt test/test/test1.txt
test/test/test2.txt test/test/test2.txt
withoutslashes/blahblah.txt blahblah.txt

View File

@ -0,0 +1,3 @@
ko
de_CH
de

View File

@ -0,0 +1,30 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/test/abc/123/+++">
<file>currentdir.txt</file>
<file>./currentdir2.txt</file>
<file>../parentdir.txt</file>
<file>subdir/subdir.txt</file>
</qresource>
<qresource prefix="/">
<file>searchpath1/search_file.txt</file>
<file>searchpath2/search_file.txt</file>
<file>search_file.txt</file>
</qresource>
<qresource><file>test/testdir.txt</file>
<file>otherdir/otherdir.txt</file>
<file alias="aliasdir/aliasdir.txt">test/testdir2.txt</file>
<file>test/test</file>
</qresource>
<qresource lang="ko">
<file>aliasdir/aliasdir.txt</file>
</qresource>
<qresource lang="de_CH">
<file alias="aliasdir/aliasdir.txt" compress="9" threshold="30">aliasdir/compressme.txt</file>
</qresource>
<qresource lang="de">
<file alias="aliasdir/aliasdir.txt">test/german.txt</file>
</qresource>
<qresource prefix="withoutslashes">
<file>blahblah.txt</file>
</qresource>
</RCC>

View File

@ -0,0 +1 @@
qwerty

View File

@ -0,0 +1 @@
"This is the current dir"

View File

@ -0,0 +1 @@
"This is also the current dir"

View File

@ -0,0 +1,5 @@
currentdir.txt currentdir.txt
currentdir2.txt currentdir2.txt
search_file.txt search_file.txt
/root/test/testdir.txt test/testdir.txt
test/testdir2.txt test/testdir2.txt

View File

@ -0,0 +1,6 @@
currentdir.txt blahblah.txt
currentdir2.txt currentdir2.txt
search_file.txt search_file.txt
/root/test/testdir.txt test/testdir.txt
test/testdir2.txt test/testdir2.txt
parentdir.txt ../parentdir.txt

View File

@ -0,0 +1,4 @@
currentdir.txt currentdir.txt
search_file.txt search_file.txt
/root/test/testdir.txt test/testdir.txt
test/testdir2.txt test/testdir2.txt

View File

@ -0,0 +1,6 @@
currentdir.txt currentdir.txt
search_file.txt search_file.txt
/root/test/testdir.txt test/testdir.txt
test/testdir2.txt test/testdir2.txt
/root/otherdir/otherdir.txt otherdir/otherdir.txt
/root/currentdir.txt subdir/subdir.txt

View File

@ -0,0 +1,3 @@
de
de_CH
it

View File

@ -0,0 +1,30 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>currentdir.txt</file>
</qresource>
<qresource lang="de"> <file>currentdir2.txt</file> </qresource>
<qresource lang="de_CH"> <file>../parentdir.txt</file>
<file alias="currentdir.txt">blahblah.txt</file>
</qresource>
<qresource><file>search_file.txt</file></qresource>
<qresource prefix="/root/">
<file>test/testdir.txt</file>
</qresource>
<qresource>
<file>test/testdir2.txt</file>
</qresource>
<qresource prefix="/root/" lang="it">
<file>otherdir/otherdir.txt</file>
<file alias="currentdir.txt">subdir/subdir.txt</file>
</qresource>
</RCC>

View File

@ -0,0 +1,5 @@
blahblah.txt blahblah.txt
currentdir.txt currentdir.txt
currentdir2.txt currentdir2.txt
subdir/subdir.txt subdir/subdir.txt
otherdir/otherdir.txt otherdir/otherdir.txt

View File

@ -0,0 +1,10 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>blahblah.txt</file>
<file>currentdir.txt</file>
<file>currentdir2.txt</file>
</qresource>
<qresource><file>subdir/subdir.txt</file></qresource>
<qresource><file>otherdir/</file>
</qresource>
</RCC>

View File

@ -0,0 +1 @@
"This is the other dir"

View File

@ -0,0 +1,6 @@
blahblah.txt blahblah.txt
/myroot/currentdir.txt currentdir.txt
/myroot/currentdir2.txt currentdir2.txt
/anotherroot/aliased.txt search_file.txt
/anotherroot/parentdir.txt ../parentdir.txt
/myroot/subdir/subdir.txt subdir/subdir.txt

View File

@ -0,0 +1,21 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>blahblah.txt</file>
</qresource>
<qresource prefix="/myroot/">
<file>currentdir.txt</file>
<file>currentdir2.txt</file>
</qresource>
<qresource prefix="/anotherroot/">
<file alias="aliased.txt">search_file.txt</file>
<file>../parentdir.txt</file></qresource>
<qresource prefix="/myroot"><file>subdir/subdir.txt</file></qresource>
</RCC>

View File

@ -0,0 +1 @@
root

View File

@ -0,0 +1 @@
path1

View File

@ -0,0 +1 @@
path2

View File

@ -0,0 +1,3 @@
blahblah.txt blahblah.txt
currentdir.txt currentdir.txt
currentdir2.txt currentdir2.txt

View File

@ -0,0 +1,7 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>blahblah.txt</file>
<file>currentdir.txt</file>
<file>currentdir2.txt</file>
</qresource>
</RCC>

View File

@ -0,0 +1 @@
"This is in the sub directory"

View File

@ -0,0 +1 @@
Deutsch

View File

@ -0,0 +1 @@
abc

View File

@ -0,0 +1 @@
def

View File

@ -0,0 +1 @@
"This is in the test directory"

View File

@ -0,0 +1 @@
"This is another file in this directory"

View File

Before

Width:  |  Height:  |  Size: 165 B

After

Width:  |  Height:  |  Size: 165 B

View File

Before

Width:  |  Height:  |  Size: 94 B

After

Width:  |  Height:  |  Size: 94 B

View File

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 170 B

View File

@ -0,0 +1 @@
abcdefgihklmnopqrstuvwxyz

View File

@ -3,10 +3,3 @@ QT = core testlib
TARGET = tst_rcc
SOURCES += tst_rcc.cpp
wince* {
DEFINES += SRCDIR=\\\"\\\"
} else {
DEFINES += SRCDIR=\\\"$$PWD/\\\"
}

View File

@ -1,5 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2012 Giuseppe D'Angelo <dangelog@gmail.com>
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
@ -39,28 +40,34 @@
**
****************************************************************************/
#include <QtTest/QtTest>
#include <QtCore/QString>
#include <QtCore/QCoreApplication>
#include <QtCore/QByteArray>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QProcess>
#include <QtCore/QTimer>
#include <QtTest/QtTest>
#include <QtCore/QDirIterator>
#include <QtCore/QMap>
#include <QtCore/QList>
#include <QtCore/QResource>
#include <QtCore/QLocale>
typedef QMap<QString, QString> QStringMap;
Q_DECLARE_METATYPE(QStringMap)
class tst_rcc : public QObject
{
Q_OBJECT
public:
tst_rcc() {}
private slots:
void rcc_data();
void rcc();
};
void binary_data();
void binary();
void cleanupTestCase();
};
QString findExpectedFile(const QString &base)
{
@ -95,14 +102,16 @@ static QString doCompare(const QStringList &actual, const QStringList &expected)
return ba;
}
void tst_rcc::rcc_data()
{
QTest::addColumn<QString>("directory");
QTest::addColumn<QString>("qrcfile");
QTest::addColumn<QString>("expected");
QTest::newRow("images") << SRCDIR "data" << "images.qrc" << "images.expected";
QString dataPath = QFINDTESTDATA("data/images/");
if (dataPath.isEmpty())
QFAIL("data path not found");
QTest::newRow("images") << dataPath << "images.qrc" << "images.expected";
}
void tst_rcc::rcc()
@ -157,6 +166,191 @@ void tst_rcc::rcc()
static void createRccBinaryData(const QString &baseDir, const QString &qrcFileName, const QString &rccFileName)
{
QString currentDir = QDir::currentPath();
QDir::setCurrent(baseDir);
QProcess rccProcess;
rccProcess.start("rcc", QStringList() << "-binary" << "-o" << rccFileName << qrcFileName);
bool ok = rccProcess.waitForFinished();
if (!ok) {
QString errorString = QString::fromLatin1("Could not start rcc (is it in PATH?): %1").arg(rccProcess.errorString());
QFAIL(qPrintable(errorString));
}
QByteArray output = rccProcess.readAllStandardOutput();
if (!output.isEmpty()) {
QString errorMessage = QString::fromLatin1("rcc stdout: %1").arg(QString::fromLocal8Bit(output));
QWARN(qPrintable(errorMessage));
}
output = rccProcess.readAllStandardError();
if (!output.isEmpty()) {
QString errorMessage = QString::fromLatin1("rcc stderr: %1").arg(QString::fromLocal8Bit(output));
QWARN(qPrintable(errorMessage));
}
QDir::setCurrent(currentDir);
}
static QStringList readLinesFromFile(const QString &fileName)
{
QFile file(fileName);
bool ok = file.open(QIODevice::ReadOnly | QIODevice::Text);
if (!ok)
QWARN(qPrintable(QString::fromLatin1("Could not open testdata file %1: %2").arg(fileName, file.errorString())));
QStringList lines = QString::fromUtf8(file.readAll()).split(QLatin1Char('\n'), QString::SkipEmptyParts);
return lines;
}
static QStringMap readExpectedFiles(const QString &fileName)
{
QStringMap expectedFiles;
QStringList lines = readLinesFromFile(fileName);
foreach (const QString &line, lines) {
QString resourceFileName = line.section(QLatin1Char(' '), 0, 0, QString::SectionSkipEmpty);
QString actualFileName = line.section(QLatin1Char(' '), 1, 1, QString::SectionSkipEmpty);
expectedFiles[resourceFileName] = actualFileName;
}
return expectedFiles;
}
/*
The following test looks for all *.qrc files under data/binary/. For each
.qrc file found, these files are processed (assuming the file found is
called "base.qrc"):
- base.qrc : processed by rcc; creates base.rcc
- base.locale : (optional) list of locales to test, one per line
- base.expected : list of pairs (file path in resource, path to real file),
one per line; the pair separated by a whitespace; the paths to real files
relative to data/binary/ (for testing the C locale)
- base.localeName.expected : for each localeName in the base.locale file,
as the above .expected file
*/
void tst_rcc::binary_data()
{
QTest::addColumn<QString>("resourceFile");
QTest::addColumn<QLocale>("locale");
QTest::addColumn<QString>("baseDirectory");
QTest::addColumn<QStringMap>("expectedFiles");
QString dataPath = QFINDTESTDATA("data/binary/");
if (dataPath.isEmpty())
QFAIL("data path not found");
QDirIterator iter(dataPath, QStringList() << QLatin1String("*.qrc"));
while (iter.hasNext())
{
iter.next();
QFileInfo qrcFileInfo = iter.fileInfo();
QString absoluteBaseName = QFileInfo(qrcFileInfo.absolutePath(), qrcFileInfo.baseName()).absoluteFilePath();
QString rccFileName = absoluteBaseName + QLatin1String(".rcc");
createRccBinaryData(dataPath, qrcFileInfo.absoluteFilePath(), rccFileName);
QString localeFileName = absoluteBaseName + QLatin1String(".locale");
QFile localeFile(localeFileName);
if (localeFile.exists()) {
QStringList locales = readLinesFromFile(localeFileName);
foreach (const QString &locale, locales) {
QString expectedFileName = QString::fromLatin1("%1.%2.%3").arg(absoluteBaseName, locale, QLatin1String("expected"));
QStringMap expectedFiles = readExpectedFiles(expectedFileName);
QTest::newRow(qPrintable(qrcFileInfo.baseName() + QLatin1Char('_') + locale)) << rccFileName
<< QLocale(locale)
<< dataPath
<< expectedFiles;
}
}
// always test for the C locale as well
QString expectedFileName = absoluteBaseName + QLatin1String(".expected");
QStringMap expectedFiles = readExpectedFiles(expectedFileName);
QTest::newRow(qPrintable(qrcFileInfo.baseName() + QLatin1String("_C"))) << rccFileName
<< QLocale::c()
<< dataPath
<< expectedFiles;
}
}
void tst_rcc::binary()
{
QFETCH(QString, baseDirectory);
QFETCH(QString, resourceFile);
QFETCH(QLocale, locale);
QFETCH(QStringMap, expectedFiles);
const QString rootPrefix = QLatin1String("/test_root/");
const QString resourceRootPrefix = QLatin1Char(':') + rootPrefix;
QLocale oldDefaultLocale;
QLocale::setDefault(locale);
QVERIFY(QFile::exists(resourceFile));
QVERIFY(QResource::registerResource(resourceFile, rootPrefix));
{ // need to destroy the iterators on the resource, in order to be able to unregister it
// read all the files inside the resources
QDirIterator iter(resourceRootPrefix, QDir::Files, QDirIterator::Subdirectories);
QList<QString> filesFound;
while (iter.hasNext())
filesFound << iter.next();
// add the test root prefix to the expected file names
QList<QString> expectedFileNames = expectedFiles.keys();
for (QList<QString>::iterator i = expectedFileNames.begin(); i < expectedFileNames.end(); ++i) {
// poor man's canonicalPath, which doesn't work with resources
if ((*i).startsWith(QLatin1Char('/')))
(*i).remove(0, 1);
*i = resourceRootPrefix + *i;
}
// check that we have all (and only) the expected files
qSort(filesFound);
qSort(expectedFileNames);
QCOMPARE(filesFound, expectedFileNames);
// now actually check the file contents
QDir directory(baseDirectory);
for (QStringMap::const_iterator i = expectedFiles.constBegin(); i != expectedFiles.constEnd(); ++i) {
QString resourceFileName = i.key();
QString actualFileName = i.value();
QFile resourceFile(resourceRootPrefix + resourceFileName);
QVERIFY(resourceFile.open(QIODevice::ReadOnly));
QByteArray resourceData = resourceFile.readAll();
resourceFile.close();
QFile actualFile(QFileInfo(directory, actualFileName).absoluteFilePath());
QVERIFY(actualFile.open(QIODevice::ReadOnly));
QByteArray actualData = actualFile.readAll();
actualFile.close();
QCOMPARE(resourceData, actualData);
}
}
QVERIFY(QResource::unregisterResource(resourceFile, rootPrefix));
QLocale::setDefault(oldDefaultLocale);
}
void tst_rcc::cleanupTestCase()
{
QString dataPath = QFINDTESTDATA("data/binary/");
if (dataPath.isEmpty())
return;
QDir dataDir(dataPath);
QFileInfoList entries = dataDir.entryInfoList(QStringList() << QLatin1String("*.rcc"));
foreach (const QFileInfo &entry, entries)
QFile::remove(entry.absoluteFilePath());
}
QTEST_APPLESS_MAIN(tst_rcc)
#include "tst_rcc.moc"