1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-03 09:49:19 +02:00

CSS parser cache

This commit is contained in:
Nikolay Pultsin 2014-03-17 14:56:33 +02:00
parent e85d8481bb
commit f1043daea9
6 changed files with 141 additions and 85 deletions

View file

@ -1,5 +1,6 @@
===== 1.9.7 (Mar ??, 2014) =====
* Experimental video support
* CSS parsing optimization for ePubs (do not parse css files multiple times)
===== 1.9.6.1 (Feb 24, 2014) =====
* Fixed some config vaues reading (e.g. background)

View file

@ -26,51 +26,6 @@
#include "StyleSheetParser.h"
StyleSheetTableParser::StyleSheetTableParser(StyleSheetTable &table) : myTable(table) {
//ZLLogger::Instance().registerClass("CSS");
}
void StyleSheetTableParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) {
std::string s = selector;
ZLStringUtil::stripWhiteSpaces(s);
if (s.empty()) {
return;
}
if (s[0] == '@') {
processAtRule(s, map);
return;
}
const std::vector<std::string> ids = ZLStringUtil::split(s, ",");
for (std::vector<std::string>::const_iterator it = ids.begin(); it != ids.end(); ++it) {
std::string id = *it;
ZLStringUtil::stripWhiteSpaces(id);
if (!id.empty()) {
const std::size_t index = id.find('.');
if (index == std::string::npos) {
myTable.addMap(id, std::string(), map);
} else {
myTable.addMap(id.substr(0, index), id.substr(index + 1), map);
}
}
}
}
void StyleSheetTableParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map) {
if (name == "@font-face") {
}
}
shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char *text) {
myReadState = WAITING_FOR_ATTRIBUTE;
parse(text, std::strlen(text), true);
shared_ptr<ZLTextStyleEntry> control = StyleSheetTable::createControl(myMap);
reset();
return control;
}
StyleSheetParser::StyleSheetParser() {
reset();
}
@ -87,21 +42,6 @@ void StyleSheetParser::reset() {
myMap.clear();
}
void StyleSheetParser::parse(ZLInputStream &stream) {
if (stream.open()) {
char *buffer = new char[1024];
while (true) {
int len = stream.read(buffer, 1024);
if (len == 0) {
break;
}
parse(buffer, len);
}
delete[] buffer;
stream.close();
}
}
void StyleSheetParser::parse(const char *text, int len, bool final) {
const char *start = text;
const char *end = text + len;
@ -151,9 +91,6 @@ bool StyleSheetParser::isControlSymbol(const char symbol) {
void StyleSheetParser::storeData(const std::string&, const StyleSheetTable::AttributeMap&) {
}
void StyleSheetParser::processAtRule(const std::string&, const StyleSheetTable::AttributeMap&) {
}
void StyleSheetParser::processControl(const char control) {
switch (myReadState) {
case WAITING_FOR_SELECTOR:
@ -241,3 +178,77 @@ void StyleSheetParser::processWordWithoutComments(const std::string &word) {
}
}
}
shared_ptr<ZLTextStyleEntry> StyleSheetSingleStyleParser::parseString(const char *text) {
myReadState = WAITING_FOR_ATTRIBUTE;
parse(text, std::strlen(text), true);
shared_ptr<ZLTextStyleEntry> control = StyleSheetTable::createControl(myMap);
reset();
return control;
}
void StyleSheetMultiStyleParser::storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map) {
std::string s = selector;
ZLStringUtil::stripWhiteSpaces(s);
if (s.empty()) {
return;
}
if (s[0] == '@') {
processAtRule(s, map);
return;
}
const std::vector<std::string> ids = ZLStringUtil::split(s, ",");
for (std::vector<std::string>::const_iterator it = ids.begin(); it != ids.end(); ++it) {
std::string id = *it;
ZLStringUtil::stripWhiteSpaces(id);
if (!id.empty()) {
const std::size_t index = id.find('.');
if (index == std::string::npos) {
store(id, std::string(), map);
} else {
store(id.substr(0, index), id.substr(index + 1), map);
}
}
}
}
void StyleSheetMultiStyleParser::processAtRule(const std::string &name, const StyleSheetTable::AttributeMap&) {
if (name == "@font-face") {
}
}
void StyleSheetMultiStyleParser::parseStream(ZLInputStream &stream) {
if (stream.open()) {
char *buffer = new char[1024];
while (true) {
int len = stream.read(buffer, 1024);
if (len == 0) {
break;
}
parse(buffer, len);
}
delete[] buffer;
stream.close();
}
}
StyleSheetTableParser::StyleSheetTableParser(StyleSheetTable &table) : myTable(table) {
}
void StyleSheetTableParser::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
myTable.addMap(tag, aClass, map);
}
void StyleSheetParserWithCache::store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) {
myEntries.push_back(new Entry(tag, aClass, map));
}
void StyleSheetParserWithCache::applyToTable(StyleSheetTable &table) const {
for (std::list<shared_ptr<Entry> >::const_iterator it = myEntries.begin(); it != myEntries.end(); ++it) {
const Entry &entry = **it;
table.addMap(entry.Tag, entry.Class, entry.Map);
}
}

View file

@ -20,6 +20,8 @@
#ifndef __STYLESHEETPARSER_H__
#define __STYLESHEETPARSER_H__
#include <list>
#include "StyleSheetTable.h"
class ZLInputStream;
@ -32,12 +34,10 @@ protected:
public:
virtual ~StyleSheetParser();
void reset();
void parse(ZLInputStream &stream);
void parse(const char *text, int len, bool final = false);
protected:
virtual void storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map);
virtual void processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map);
private:
bool isControlSymbol(const char symbol);
@ -62,23 +62,59 @@ private:
friend class StyleSheetSingleStyleParser;
};
class StyleSheetTableParser : public StyleSheetParser {
public:
StyleSheetTableParser(StyleSheetTable &table);
private:
void storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map);
void processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map);
private:
StyleSheetTable &myTable;
};
class StyleSheetSingleStyleParser : public StyleSheetParser {
public:
shared_ptr<ZLTextStyleEntry> parseString(const char *text);
};
class StyleSheetMultiStyleParser : public StyleSheetParser {
public:
void parseStream(ZLInputStream &stream);
protected:
virtual void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) = 0;
private:
void storeData(const std::string &selector, const StyleSheetTable::AttributeMap &map);
void processAtRule(const std::string &name, const StyleSheetTable::AttributeMap &map);
};
class StyleSheetTableParser : public StyleSheetMultiStyleParser {
public:
StyleSheetTableParser(StyleSheetTable &table);
private:
void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
private:
StyleSheetTable &myTable;
};
class StyleSheetParserWithCache : public StyleSheetMultiStyleParser {
private:
struct Entry {
const std::string Tag;
const std::string Class;
const StyleSheetTable::AttributeMap Map;
Entry(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
};
public:
void applyToTable(StyleSheetTable &table) const;
private:
void store(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map);
private:
std::list<shared_ptr<Entry> > myEntries;
};
inline StyleSheetParserWithCache::Entry::Entry(const std::string &tag, const std::string &aClass, const StyleSheetTable::AttributeMap &map) : Tag(tag), Class(aClass), Map(map) {
}
#endif /* __STYLESHEETPARSER_H__ */

View file

@ -64,6 +64,7 @@ private:
std::map<Key,bool> myPageBreakAfterMap;
friend class StyleSheetTableParser;
friend class StyleSheetParserWithCache;
};
inline StyleSheetTable::Key::Key(const std::string &tag, const std::string &aClass) : TagName(tag), ClassName(aClass) {

View file

@ -260,15 +260,21 @@ void XHTMLTagLinkAction::doAtStart(XHTMLReader &reader, const char **xmlattribut
}
const std::string cssFilePath = reader.myPathPrefix + MiscUtil::decodeHtmlURL(href);
//ZLLogger::Instance().registerClass("CSS");
ZLLogger::Instance().println("CSS", "style file: " + cssFilePath);
shared_ptr<ZLInputStream> cssStream = ZLFile(cssFilePath).inputStream(reader.myEncryptionMap);
if (cssStream.isNull()) {
return;
const ZLFile cssFile(cssFilePath);
shared_ptr<StyleSheetParserWithCache> parser = reader.myFileParsers[cssFile.path()];
if (parser.isNull()) {
parser = new StyleSheetParserWithCache();
reader.myFileParsers[cssFile.path()] = parser;
ZLLogger::Instance().println("CSS", "creating stream");
shared_ptr<ZLInputStream> cssStream = ZLFile(cssFilePath).inputStream(reader.myEncryptionMap);
if (!cssStream.isNull()) {
ZLLogger::Instance().println("CSS", "parsing file");
parser->parseStream(*cssStream);
}
}
ZLLogger::Instance().println("CSS", "parsing file");
StyleSheetTableParser parser(reader.myStyleSheetTable);
parser.parse(*cssStream);
//reader.myStyleSheetTable.dump();
parser->applyToTable(reader.myStyleSheetTable);
}
void XHTMLTagLinkAction::doAtEnd(XHTMLReader&) {

View file

@ -112,6 +112,7 @@ private:
bool myCurrentParagraphIsEmpty;
shared_ptr<StyleSheetSingleStyleParser> myStyleParser;
shared_ptr<StyleSheetTableParser> myTableParser;
std::map<std::string,shared_ptr<StyleSheetParserWithCache> > myFileParsers;
XHTMLReadingState myReadState;
int myBodyCounter;
bool myMarkNextImageAsCover;