diff --git a/src/common/base64.cpp b/src/common/base64.cpp new file mode 100644 index 000000000..522d0b028 --- /dev/null +++ b/src/common/base64.cpp @@ -0,0 +1,122 @@ +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ + +#include "base64.h" +#include + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + + +static inline bool is_base64(unsigned char c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { + std::string ret; + int i = 0; + int j = 0; + unsigned char char_array_3[3]; + unsigned char char_array_4[4]; + + while (in_len--) { + char_array_3[i++] = *(bytes_to_encode++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + + } + + return ret; + +} + +std::string base64_decode(std::string const& encoded_string) { + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + unsigned char char_array_4[4], char_array_3[3]; + std::string ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret += char_array_3[i]; + i = 0; + } + } + + if (i) { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; + } + + return ret; +} diff --git a/src/common/base64.h b/src/common/base64.h new file mode 100644 index 000000000..65d5db8b2 --- /dev/null +++ b/src/common/base64.h @@ -0,0 +1,4 @@ +#include + +std::string base64_encode(unsigned char const* , unsigned int len); +std::string base64_decode(std::string const& s); diff --git a/src/common/kiwix/indexer.cpp b/src/common/kiwix/indexer.cpp index beb038796..11fa515b0 100644 --- a/src/common/kiwix/indexer.cpp +++ b/src/common/kiwix/indexer.cpp @@ -134,10 +134,10 @@ namespace kiwix { /* snippet */ std::string snippet = std::string(this->htmlParser.dump, 0, 300); std::string::size_type last = snippet.find_last_of('.'); - if (last != snippet.npos) + if (last == snippet.npos) last = snippet.find_last_of(' '); if (last != snippet.npos) - snippet = snippet.substr(0, last+1); + snippet = snippet.substr(0, last); /* size */ stringstream sizeStringStream; diff --git a/src/common/kiwix/library.cpp b/src/common/kiwix/library.cpp index a99a587ae..7bd124aa3 100644 --- a/src/common/kiwix/library.cpp +++ b/src/common/kiwix/library.cpp @@ -37,7 +37,8 @@ namespace kiwix { articleCount(""), mediaCount(""), readOnly(false), - size("") { + size(""), + faviconMimeType("") { } /* Destructor */ diff --git a/src/common/kiwix/library.h b/src/common/kiwix/library.h index 8cd45e304..5ed65693a 100644 --- a/src/common/kiwix/library.h +++ b/src/common/kiwix/library.h @@ -25,7 +25,7 @@ #include #include -#define KIWIX_LIBRARY_VERSION "20110512" +#define KIWIX_LIBRARY_VERSION "20110514" using namespace std; @@ -56,6 +56,8 @@ namespace kiwix { string mediaCount; bool readOnly; string size; + string favicon; + string faviconMimeType; }; class Library { diff --git a/src/common/kiwix/manager.cpp b/src/common/kiwix/manager.cpp index 5589e3d69..31a8f4cd2 100644 --- a/src/common/kiwix/manager.cpp +++ b/src/common/kiwix/manager.cpp @@ -58,6 +58,8 @@ namespace kiwix { book.articleCount = bookNode.attribute("articleCount").value(); book.mediaCount = bookNode.attribute("mediaCount").value(); book.size = bookNode.attribute("size").value(); + book.favicon = bookNode.attribute("favicon").value(); + book.faviconMimeType = bookNode.attribute("faviconMimeType").value(); /* Update the book properties with the new importer */ if (libraryVersion.empty() || atoi(libraryVersion.c_str()) < atoi(KIWIX_LIBRARY_VERSION)) { @@ -162,6 +164,12 @@ namespace kiwix { if (itr->size != "") bookNode.append_attribute("size") = itr->size.c_str(); + + if (itr->favicon != "") + bookNode.append_attribute("favicon") = itr->favicon.c_str(); + + if (itr->faviconMimeType != "") + bookNode.append_attribute("faviconMimeType") = itr->faviconMimeType.c_str(); } } @@ -219,6 +227,12 @@ namespace kiwix { sprintf (csize, "%u", size); book.size = csize; + string favicon; + string faviconMimeType; + if (reader.getFavicon(favicon, faviconMimeType)) { + book.favicon = base64_encode(reinterpret_cast(favicon.c_str()), favicon.length()); + book.faviconMimeType = faviconMimeType; + } } catch (...) { return false; } diff --git a/src/common/kiwix/manager.h b/src/common/kiwix/manager.h index a8233112e..e7194e232 100644 --- a/src/common/kiwix/manager.h +++ b/src/common/kiwix/manager.h @@ -31,6 +31,7 @@ #include +#include #include #include diff --git a/src/common/kiwix/reader.cpp b/src/common/kiwix/reader.cpp index 5ace9cb17..a878d9d85 100644 --- a/src/common/kiwix/reader.cpp +++ b/src/common/kiwix/reader.cpp @@ -129,6 +129,20 @@ namespace kiwix { return url; } + bool Reader::getFavicon(string &content, string &mimeType) { + unsigned int contentLength = 0; + + this->getContentByUrl( "/-/favicon.png", content, + contentLength, mimeType); + + if (content.empty()) { + this->getContentByUrl( "/I/favicon.png", content, + contentLength, mimeType); + } + + return content.empty() ? false : true; + } + /* Return a metatag value */ bool Reader::getMetatag(const string &name, string &value) { unsigned int contentLength = 0; diff --git a/src/common/kiwix/reader.h b/src/common/kiwix/reader.h index 604bcaeca..14cbbf44e 100644 --- a/src/common/kiwix/reader.h +++ b/src/common/kiwix/reader.h @@ -51,6 +51,7 @@ namespace kiwix { string getLanguage(); string getDate(); string getCreator(); + bool getFavicon(string &content, string &mimeType); bool getPageUrlFromTitle(const string &title, string &url); bool getContentByUrl(const string &url, string &content, unsigned int &contentLength, string &contentType); bool searchSuggestions(const string &prefix, unsigned int suggestionsCount);