Пример #1
0
bool FirmwareInfo::ParseXml(QXmlStreamReader& xml)
{
	Clear();

	bool foundName = false;
	bool foundVersion = false;
	bool foundPlatform = false;
	bool foundDevelopers = false;
	bool foundUrl = false;
	bool foundDonateUrl = false;
	bool foundDevices = false;
	bool foundPit = false;
	bool foundRepartition = false;
	bool foundNoReboot = false;
	bool foundFiles = false;

	if (!xml.readNextStartElement())
	{
		Alerts::DisplayError("Failed to find <firmware> element.");
		return (false);
	}

	if (xml.name() != "firmware")
	{
		Alerts::DisplayError(QString("Expected <firmware> element but found <%1>.").arg(xml.name().toString()));
		return (false);
	}

	QString formatVersionString;
	formatVersionString += xml.attributes().value("version");

	if (formatVersionString.isEmpty())
	{
		Alerts::DisplayError("<firmware> is missing the version attribute.");
		return (false);
	}

	bool parsedVersion = false;
	int formatVersion = formatVersionString.toInt(&parsedVersion);

	if (!parsedVersion)
	{
		Alerts::DisplayError("<firmware> contains a malformed version.");
		return (false);
	}

	if (formatVersion > kVersion)
	{
		Alerts::DisplayError("Package is for a newer version of Heimdall Frontend.\nPlease download the latest version of Heimdall Frontend.");
		return (false);
	}

	while (!xml.atEnd())
	{
		QXmlStreamReader::TokenType nextToken = xml.readNext();

		if (nextToken == QXmlStreamReader::StartElement)
		{
			if (xml.name() == "name")
			{
				if (foundName)
				{
					Alerts::DisplayError("Found multiple <name> elements in <firmware>.");
					return (false);
				}

				foundName = true;
				name = xml.readElementText();
			}
			else if (xml.name() == "version")
			{
				if (foundVersion)
				{
					Alerts::DisplayError("Found multiple <version> elements in <firmware>.");
					return (false);
				}

				foundVersion = true;
				version = xml.readElementText();
			}
			else if (xml.name() == "platform")
			{
				if (foundPlatform)
				{
					Alerts::DisplayError("Found multiple <platform> elements in <firmware>.");
					return (false);
				}

				foundPlatform = true;

				if (!platformInfo.ParseXml(xml))
					return (false);
			}
			else if (xml.name() == "developers")
			{
				if (foundDevelopers)
				{
					Alerts::DisplayError("Found multiple <developers> elements in <firmware>.");
					return (false);
				}

				foundDevelopers = true;

				while (!xml.atEnd())
				{
					nextToken = xml.readNext();

					if (nextToken == QXmlStreamReader::StartElement)
					{
						if (xml.name() == "name")
						{
							developers.append(xml.readElementText());
						}
						else
						{
							Alerts::DisplayError(QString("<%1> is not a valid child of <developers>.").arg(xml.name().toString()));
							return (false);
						}
					}
					else if (nextToken == QXmlStreamReader::EndElement)
					{
						if (xml.name() == "developers")
							break;
					}
					else
					{
						if (!(nextToken == QXmlStreamReader::Characters && xml.isWhitespace()))
						{
							Alerts::DisplayError("Unexpected token found in <developers>.");
							return (false);
						}
					}
				}
			}
			else if (xml.name() == "url")
			{
				if (foundUrl)
				{
					Alerts::DisplayError("Found multiple <url> elements in <firmware>.");
					return (false);
				}

				foundUrl = true;

				url = xml.readElementText();
			}
			else if (xml.name() == "donateurl")
			{
				if (foundDonateUrl)
				{
					Alerts::DisplayError("Found multiple <donateurl> elements in <firmware>.");
					return (false);
				}

				foundDonateUrl = true;

				donateUrl = xml.readElementText();
			}
			else if (xml.name() == "devices")
			{
				if (foundDevices)
				{
					Alerts::DisplayError("Found multiple <devices> elements in <firmware>.");
					return (false);
				}

				foundDevices = true;

				while (!xml.atEnd())
				{
					nextToken = xml.readNext();

					if (nextToken == QXmlStreamReader::StartElement)
					{
						if (xml.name() == "device")
						{
							DeviceInfo deviceInfo;

							if (!deviceInfo.ParseXml(xml))
								return (false);

							deviceInfos.append(deviceInfo);
						}
						else
						{
							Alerts::DisplayError(QString("<%1> is not a valid child of <devices>.").arg(xml.name().toString()));
							return (false);
						}
					}
					else if (nextToken == QXmlStreamReader::EndElement)
					{
						if (xml.name() == "devices")
							break;
					}
					else
					{
						if (!(nextToken == QXmlStreamReader::Characters && xml.isWhitespace()))
						{
							Alerts::DisplayError("Unexpected token found in <devices>.");
							return (false);
						}
					}
				}
			}
			else if (xml.name() == "pit")
			{
				if (foundPit)
				{
					Alerts::DisplayError("Found multiple <pit> elements in <firmware>.");
					return (false);
				}

				foundPit = true;

				pitFilename = xml.readElementText();
			}
			else if (xml.name() == "repartition")
			{
				if (foundRepartition)
				{
					Alerts::DisplayError("Found multiple <repartition> elements in <firmware>.");
					return (false);
				}

				foundRepartition = true;

				repartition = (xml.readElementText().toInt() != 0);
			}
			else if (xml.name() == "noreboot")
			{
				if (foundNoReboot)
				{
					Alerts::DisplayError("Found multiple <noreboot> elements in <firmware>.");
					return (false);
				}

				foundNoReboot = true;

				noReboot = (xml.readElementText().toInt() != 0);
			}
			else if (xml.name() == "files")
			{
				if (foundFiles)
				{
					Alerts::DisplayError("Found multiple <files> elements in <firmware>.");
					return (false);
				}

				foundFiles = true;

				while (!xml.atEnd())
				{
					nextToken = xml.readNext();

					if (nextToken == QXmlStreamReader::StartElement)
					{
						if (xml.name() == "file")
						{
							FileInfo fileInfo;

							if (!fileInfo.ParseXml(xml))
								return (false);

							fileInfos.append(fileInfo);
						}
						else
						{
							Alerts::DisplayError(QString("<%1> is not a valid child of <files>.").arg(xml.name().toString()));
							return (false);
						}
					}
					else if (nextToken == QXmlStreamReader::EndElement)
					{
						if (xml.name() == "files")
							break;
					}
					else
					{
						if (!(nextToken == QXmlStreamReader::Characters && xml.isWhitespace()))
						{
							Alerts::DisplayError("Unexpected token found in <devices>.");
							return (false);
						}
					}
				}
			}
			else
			{
				Alerts::DisplayError(QString("<%1> is not a valid child of <firmware>.").arg(xml.name().toString()));
				return (false);
			}
		}
		else if (nextToken == QXmlStreamReader::EndElement)
		{
			if (xml.name() == "firmware")
			{
				if (!(foundName && foundVersion && foundPlatform && foundDevelopers && foundDevices && foundPit && foundRepartition && foundNoReboot && foundFiles))
				{
					Alerts::DisplayError("Required elements are missing from <firmware>.");
					return (false);
				}
				else
				{
					break;
				}
			}
		}
		else
		{
			if (!(nextToken == QXmlStreamReader::Characters && xml.isWhitespace()))
			{
				Alerts::DisplayError("Unexpected token found in <firmware>.");
				return (false);
			}
		}
	}

	// Read whitespaces at the end of the file (if there are any)
	xml.readNext();

	if (!xml.atEnd())
	{
		Alerts::DisplayError("Found data after </firmware>.");
		return (false);
	}
	
	return (true);
}