/* * Copyright (C) 2004-2012 Geometer Plus * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include #include #include "../NetworkLink.h" #include "LitResGenre.h" #include "LitResUtil.h" #include "LitResAuthorsParser.h" static const std::string TAG_CATALOG = "catalit-persons"; static const std::string TAG_SUBJECT = "subject"; static const std::string TAG_TITLE = "title"; static const std::string TAG_MAIN = "main"; static const std::string TAG_FIRST_NAME = "first-name"; static const std::string TAG_MIDDLE_NAME = "middle-name"; static const std::string TAG_LAST_NAME = "last-name"; std::string LitResAuthorsParser::stringAttributeValue(const char **attributes, const char *name) { if (attributes == 0) { return std::string(); } const char *value = attributeValue(attributes, name); return value != 0 ? value : std::string(); } LitResAuthorsParser::LitResAuthorsParser(AuthorsList &authors) : myAuthors(authors) { myState = START; } void LitResAuthorsParser::startElementHandler(const char *tag, const char **attributes) { processState(tag, false, attributes); myState = getNextState(tag, false); myBuffer.clear(); } void LitResAuthorsParser::endElementHandler(const char *tag) { processState(tag, true, 0); myState = getNextState(tag, true); myBuffer.clear(); } void LitResAuthorsParser::characterDataHandler(const char *data, std::size_t len) { myBuffer.append(data, len); } void LitResAuthorsParser::processState(const std::string &tag, bool closed, const char **attributes) { switch(myState) { case START: break; case CATALOG: if (!closed && TAG_SUBJECT == tag) { myAuthorId = stringAttributeValue(attributes, "id"); } break; case SUBJECT: if (closed && TAG_SUBJECT == tag) { LitresAuthorData litresAuthor; litresAuthor.Id = myAuthorId; litresAuthor.DisplayName = myAuthorDisplayName; litresAuthor.FirstName = myAuthorFirstName; litresAuthor.MiddleName = myAuthorMiddleName; litresAuthor.LastName = myAuthorLastName; litresAuthor.SortKey = ZLUnicodeUtil::toLower(myAuthorLastName); myAuthors.push_back(litresAuthor); myAuthorId.clear(); myAuthorDisplayName.clear(); myAuthorFirstName.clear(); myAuthorMiddleName.clear(); myAuthorLastName.clear(); } break; case TITLE: break; case MAIN: if (closed && TAG_MAIN == tag) { ZLUnicodeUtil::utf8Trim(myBuffer); myAuthorDisplayName = myBuffer; } break; case FIRST_NAME: if (closed && TAG_FIRST_NAME == tag) { ZLUnicodeUtil::utf8Trim(myBuffer); myAuthorFirstName = myBuffer; } break; case MIDDLE_NAME: if (closed && TAG_MIDDLE_NAME == tag) { ZLUnicodeUtil::utf8Trim(myBuffer); myAuthorMiddleName = myBuffer; } break; case LAST_NAME: if (closed && TAG_LAST_NAME == tag) { ZLUnicodeUtil::utf8Trim(myBuffer); myAuthorLastName = myBuffer; } break; } } LitResAuthorsParser::State LitResAuthorsParser::getNextState(const std::string &tag, bool closed) { switch(myState) { case START: if (!closed && TAG_CATALOG == tag) { return CATALOG; } break; case CATALOG: if (!closed) { if (TAG_SUBJECT == tag) { return SUBJECT; } } else { if (TAG_CATALOG == tag) { return START; } } break; case SUBJECT: if (!closed) { if (TAG_TITLE == tag) { return TITLE; } } else { if (TAG_SUBJECT == tag) { return CATALOG; } } break; case TITLE: if (!closed) { if (TAG_MAIN == tag) { return MAIN; } } else { if (TAG_TITLE == tag) { return FIRST_NAME; } } break; case MAIN: if (closed && TAG_MAIN == tag) { return TITLE; } break; case FIRST_NAME: if (closed && TAG_FIRST_NAME == tag) { return MIDDLE_NAME; } break; case MIDDLE_NAME: if (closed && TAG_MIDDLE_NAME == tag) { return LAST_NAME; } break; case LAST_NAME: if (closed && TAG_LAST_NAME == tag) { return SUBJECT; } break; } return myState; }