2 * Copyright (C) 2004-2008 Geometer Plus <contact@geometerplus.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #include <ZLStringUtil.h>
21 #include <ZLUnicodeUtil.h>
23 #include "OEBDescriptionReader.h"
25 OEBDescriptionReader::OEBDescriptionReader(BookDescription
&description
) : myDescription(description
) {
26 myDescription
.clearAuthor();
27 myDescription
.title().erase();
30 static const std::string METADATA
= "metadata";
31 static const std::string DC_METADATA
= "dc-metadata";
32 static const std::string TITLE
= ":title";
33 static const std::string AUTHOR_TAG
= ":creator";
34 static const std::string AUTHOR_ROLE
= "aut";
36 void OEBDescriptionReader::characterDataHandler(const char *text
, int len
) {
37 switch (myReadState
) {
42 myCurrentAuthor
.append(text
, len
);
45 myDescription
.title().append(text
, len
);
50 static const std::string DC_SCHEME_PREFIX
= "http://purl.org/dc/elements";
52 void OEBDescriptionReader::startElementHandler(const char *tag
, const char **attributes
) {
53 const std::string tagString
= ZLUnicodeUtil::toLower(tag
);
54 if ((METADATA
== tagString
) || (DC_METADATA
== tagString
)) {
55 myDCMetadataTag
= tagString
;
56 myReadMetaData
= true;
57 } else if (myReadMetaData
) {
58 if (ZLStringUtil::stringEndsWith(tagString
, TITLE
)) {
59 const std::string namespaceId
= tagString
.substr(0, tagString
.length() - TITLE
.length());
60 const std::map
<std::string
,std::string
> &namespaceMap
= namespaces();
61 const std::map
<std::string
,std::string
>::const_iterator iter
= namespaceMap
.find(namespaceId
);
62 if ((iter
!= namespaceMap
.end()) && ZLStringUtil::stringStartsWith(iter
->second
, DC_SCHEME_PREFIX
)) {
63 myReadState
= READ_TITLE
;
65 } else if (ZLStringUtil::stringEndsWith(tagString
, AUTHOR_TAG
)) {
66 const std::string namespaceId
= tagString
.substr(0, tagString
.length() - AUTHOR_TAG
.length());
67 const std::map
<std::string
,std::string
> &namespaceMap
= namespaces();
68 const std::map
<std::string
,std::string
>::const_iterator iter
= namespaceMap
.find(namespaceId
);
69 if ((iter
!= namespaceMap
.end()) && ZLStringUtil::stringStartsWith(iter
->second
, DC_SCHEME_PREFIX
)) {
70 const char *role
= attributeValue(attributes
, "role");
72 myReadState
= READ_AUTHOR2
;
73 } else if (AUTHOR_ROLE
== role
) {
74 myReadState
= READ_AUTHOR
;
81 void OEBDescriptionReader::endElementHandler(const char *tag
) {
82 const std::string tagString
= ZLUnicodeUtil::toLower(tag
);
83 if (myDCMetadataTag
== tagString
) {
86 if (!myCurrentAuthor
.empty()) {
87 if (myReadState
== READ_AUTHOR
) {
88 myAuthorList
.push_back(myCurrentAuthor
);
89 } else /* if (myReadState == READ_AUTHOR2) */ {
90 myAuthorList2
.push_back(myCurrentAuthor
);
92 myCurrentAuthor
.erase();
94 myReadState
= READ_NONE
;
98 bool OEBDescriptionReader::processNamespaces() const {
102 bool OEBDescriptionReader::readDescription(const std::string
&fileName
) {
103 myReadMetaData
= false;
104 myReadState
= READ_NONE
;
105 bool code
= readDocument(fileName
);
107 if (!myAuthorList
.empty()) {
108 for (std::vector
<std::string
>::const_iterator it
= myAuthorList
.begin(); it
!= myAuthorList
.end(); ++it
) {
109 myDescription
.addAuthor(*it
);
112 for (std::vector
<std::string
>::const_iterator it
= myAuthorList2
.begin(); it
!= myAuthorList2
.end(); ++it
) {
113 myDescription
.addAuthor(*it
);