Esempio n. 1
0
Container::Container(const std::string& path) : _archive(Archive::Open(path))
{
    if ( _archive == nullptr )
        throw std::invalid_argument("Path does not point to a recognised archive file: '" + path + "'");

    // TODO: Initialize lazily? Doing so would make initialization faster, but require
    // PackageLocations() to become non-const, like Packages().
    ArchiveXmlReader reader(_archive->ReaderAtPath(gContainerFilePath));
    _ocf = reader.xmlReadDocument(gContainerFilePath, nullptr, XML_PARSE_RECOVER|XML_PARSE_NOENT|XML_PARSE_DTDATTR);
    if ( _ocf == nullptr )
        throw std::invalid_argument(std::string(__PRETTY_FUNCTION__) + ": No container.xml in " + path);

    XPathWrangler xpath(_ocf, {{"ocf", "urn:oasis:names:tc:opendocument:xmlns:container"}});
    xmlNodeSetPtr nodes = xpath.Nodes(reinterpret_cast<const xmlChar*>(gRootfilesXPath));

    if ( nodes == nullptr || nodes->nodeNr == 0 )
        throw std::invalid_argument(std::string(__PRETTY_FUNCTION__) + ": No rootfiles in " + path);

    for ( int i = 0; i < nodes->nodeNr; i++ )
    {
        xmlNodePtr n = nodes->nodeTab[i];

        const xmlChar * _type = xmlGetProp(n, reinterpret_cast<const xmlChar*>("media-type"));
        std::string type((_type == nullptr ? "" : reinterpret_cast<const char*>(_type)));

        const xmlChar * _path = xmlGetProp(n, reinterpret_cast<const xmlChar*>("full-path"));
        if ( _path == nullptr )
            continue;

        _packages.push_back(new Package(_archive, _path, type));
    }

    LoadEncryption();
}
bool Container::Open(const string& path)
{
	_archive = Archive::Open(path.stl_str());
	if (_archive == nullptr)
		throw std::invalid_argument(_Str("Path does not point to a recognised archive file: '", path, "'"));
	_path = path;

	// TODO: Initialize lazily? Doing so would make initialization faster, but require
	// PackageLocations() to become non-const, like Packages().
	ArchiveXmlReader reader(_archive->ReaderAtPath(gContainerFilePath));
	if (!reader) {
		throw std::invalid_argument(_Str("Path does not point to a recognised archive file: '", path, "'"));
	}
#if EPUB_USE(LIBXML2)
	_ocf = reader.xmlReadDocument(gContainerFilePath, nullptr, XML_PARSE_RECOVER|XML_PARSE_NOENT|XML_PARSE_DTDATTR);
#else
	decltype(_ocf) __tmp(reader.ReadDocument(gContainerFilePath, nullptr, /*RESOLVE_EXTERNALS*/ 1));
	_ocf = __tmp;
#endif
	if (!((bool)_ocf))
		return false;

#if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS)
	XPathWrangler xpath(_ocf, { { "ocf", "urn:oasis:names:tc:opendocument:xmlns:container" } });
#else
	XPathWrangler::NamespaceList __ns;
	__ns["ocf"] = OCFNamespaceURI;
	XPathWrangler xpath(_ocf, __ns);
#endif
	xml::NodeSet nodes = xpath.Nodes(gRootfilesXPath);

	if (nodes.empty())
		return false;

	LoadEncryption();

	for (auto n : nodes)
	{
		string type = _getProp(n, "media-type");

		string path = _getProp(n, "full-path");
		if (path.empty())
			continue;

		auto pkg = Package::New(Ptr(), type);
		if (pkg->Open(path))
			_packages.push_back(pkg);
	}

    auto fm = FilterManager::Instance();
	for (auto& pkg : _packages)
	{
        auto fc = fm->BuildFilterChainForPackage(pkg);
		pkg->SetFilterChain(fc);
	}

	return true;
}
Esempio n. 3
0
bool Container::Open(const string& path)
{
    ContainerPtr sharedThis(shared_from_this());
    _archive = std::move(Archive::Open(path.stl_str()));
    if ( _archive == nullptr )
        throw std::invalid_argument(_Str("Path does not point to a recognised archive file: '", path, "'"));
    
    // TODO: Initialize lazily? Doing so would make initialization faster, but require
    // PackageLocations() to become non-const, like Packages().
    ArchiveXmlReader reader(_archive->ReaderAtPath(gContainerFilePath));
    _ocf = reader.xmlReadDocument(gContainerFilePath, nullptr, XML_PARSE_RECOVER|XML_PARSE_NOENT|XML_PARSE_DTDATTR);
    if ( _ocf == nullptr )
        return false;

#if EPUB_COMPILER_SUPPORTS(CXX_INITIALIZER_LISTS)
    XPathWrangler xpath(_ocf, {{"ocf", "urn:oasis:names:tc:opendocument:xmlns:container"}});
#else
    XPathWrangler::NamespaceList __ns;
    __ns["ocf"] = OCFNamespaceURI;
    XPathWrangler xpath(_ocf, __ns);
#endif
    xmlNodeSetPtr nodes = xpath.Nodes(reinterpret_cast<const xmlChar*>(gRootfilesXPath));
    
    if ( nodes == nullptr || nodes->nodeNr == 0 )
        return false;
    
    for ( int i = 0; i < nodes->nodeNr; i++ )
    {
        xmlNodePtr n = nodes->nodeTab[i];
        
        const xmlChar * _type = xmlGetProp(n, reinterpret_cast<const xmlChar*>("media-type"));
        std::string type((_type == nullptr ? "" : reinterpret_cast<const char*>(_type)));
        
        const xmlChar * _path = xmlGetProp(n, reinterpret_cast<const xmlChar*>("full-path"));
        if ( _path == nullptr )
            continue;
        
        auto pkg = std::make_shared<Package>(sharedThis, type);
        if ( pkg->Open(_path) )
            _packages.push_back(pkg);
    }

    LoadEncryption();
    return true;
}