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:
parent
e85d8481bb
commit
f1043daea9
6 changed files with 141 additions and 85 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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&) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue