1 /* 2 * Copyright (C) 2009 Tommi Maekitalo 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of the 7 * License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied 11 * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and 12 * NON-INFRINGEMENT. See the GNU General Public License for more details. 13 * 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 St, Fifth Floor, Boston, MA 02110-1301 USA 17 * 18 */ 19 20 #ifndef ZIM_WRITER_DIRENT_H 21 #define ZIM_WRITER_DIRENT_H 22 23 #include "cluster.h" 24 25 #include "debug.h" 26 27 namespace zim 28 { 29 namespace writer { 30 class Dirent; 31 struct DirectInfo { DirectInfoDirectInfo32 DirectInfo() : 33 clusterNumber(0), 34 blobNumber(0) 35 {}; 36 cluster_index_t clusterNumber; 37 blob_index_t blobNumber; 38 }; 39 40 struct RedirectInfo { 41 const Dirent* redirectDirent = nullptr; 42 }; 43 44 union DirentInfo { 45 DirectInfo d; 46 RedirectInfo r; 47 }; 48 49 class Dirent 50 { 51 static const uint16_t redirectMimeType = 0xffff; 52 static const uint16_t linktargetMimeType = 0xfffe; 53 static const uint16_t deletedMimeType = 0xfffd; 54 static const uint32_t version = 0; 55 56 uint16_t mimeType; 57 DirentInfo info {}; 58 Url url; 59 std::string title; 60 Cluster* cluster = nullptr; 61 Url redirectUrl; 62 article_index_t idx = article_index_t(0); 63 offset_t offset; 64 65 public: Dirent()66 Dirent() 67 : mimeType(0), 68 url(), 69 title(), 70 redirectUrl() 71 { 72 info.d.clusterNumber = cluster_index_t(0); 73 info.d.blobNumber = blob_index_t(0); 74 } 75 Dirent(Url url_)76 explicit Dirent(Url url_ ) 77 : Dirent() 78 { url = url_; } 79 getNamespace()80 char getNamespace() const { return url.getNs(); } getTitle()81 const std::string& getTitle() const { return title.empty() ? url.getUrl() : title; } setTitle(const std::string & title_)82 void setTitle(const std::string& title_) { title = title_; } getUrl()83 const std::string& getUrl() const { return url.getUrl(); } getFullUrl()84 const Url& getFullUrl() const { return url; } setUrl(Url url_)85 void setUrl(Url url_) { 86 url = url_; 87 } 88 getVersion()89 uint32_t getVersion() const { return version; } 90 setRedirectUrl(Url redirectUrl_)91 void setRedirectUrl(Url redirectUrl_) { redirectUrl = redirectUrl_; } getRedirectUrl()92 const Url& getRedirectUrl() const { return redirectUrl; } setRedirect(const Dirent * target)93 void setRedirect(const Dirent* target) { 94 info.r.redirectDirent = target; 95 mimeType = redirectMimeType; 96 } getRedirectIndex()97 article_index_t getRedirectIndex() const { return isRedirect() ? info.r.redirectDirent->getIdx() : article_index_t(0); } 98 setMimeType(uint16_t mime)99 void setMimeType(uint16_t mime) 100 { 101 mimeType = mime; 102 } 103 setLinktarget()104 void setLinktarget() 105 { 106 ASSERT(mimeType, ==, 0); 107 mimeType = linktargetMimeType; 108 } 109 setDeleted()110 void setDeleted() 111 { 112 ASSERT(mimeType, ==, 0); 113 mimeType = deletedMimeType; 114 } 115 116 setIdx(article_index_t idx_)117 void setIdx(article_index_t idx_) { idx = idx_; } getIdx()118 article_index_t getIdx() const { return idx; } 119 120 setCluster(zim::writer::Cluster * _cluster)121 void setCluster(zim::writer::Cluster* _cluster) 122 { 123 ASSERT(isArticle(), ==, true); 124 cluster = _cluster; 125 info.d.blobNumber = _cluster->count(); 126 } 127 getClusterNumber()128 cluster_index_t getClusterNumber() const { 129 return cluster ? cluster->getClusterIndex() : info.d.clusterNumber; 130 } getBlobNumber()131 blob_index_t getBlobNumber() const { 132 return isRedirect() ? blob_index_t(0) : info.d.blobNumber; 133 } 134 isRedirect()135 bool isRedirect() const { return mimeType == redirectMimeType; } isLinktarget()136 bool isLinktarget() const { return mimeType == linktargetMimeType; } isDeleted()137 bool isDeleted() const { return mimeType == deletedMimeType; } isArticle()138 bool isArticle() const { return !isRedirect() && !isLinktarget() && !isDeleted(); } getMimeType()139 uint16_t getMimeType() const { return mimeType; } getDirentSize()140 size_t getDirentSize() const 141 { 142 size_t ret = (isRedirect() ? 12 : 16) + url.getUrl().size() + 2; 143 if (title != url.getUrl()) 144 ret += title.size(); 145 return ret; 146 } 147 getOffset()148 offset_t getOffset() const { return offset; } setOffset(offset_t o)149 void setOffset(offset_t o) { offset = o; } 150 setArticle(uint16_t mimeType_,cluster_index_t clusterNumber_,blob_index_t blobNumber_)151 void setArticle(uint16_t mimeType_, cluster_index_t clusterNumber_, blob_index_t blobNumber_) 152 { 153 ASSERT(mimeType, ==, 0); 154 mimeType = mimeType_; 155 info.d.clusterNumber = clusterNumber_; 156 info.d.blobNumber = blobNumber_; 157 } 158 159 void write(int out_fd) const; 160 161 friend bool compareUrl(const Dirent* d1, const Dirent* d2); 162 friend inline bool compareTitle(const Dirent* d1, const Dirent* d2); 163 }; 164 165 compareUrl(const Dirent * d1,const Dirent * d2)166 inline bool compareUrl(const Dirent* d1, const Dirent* d2) 167 { 168 return d1->url < d2->url; 169 } compareTitle(const Dirent * d1,const Dirent * d2)170 inline bool compareTitle(const Dirent* d1, const Dirent* d2) 171 { 172 return d1->url.getNs() < d2->url.getNs() 173 || (d1->url.getNs() == d2->url.getNs() && d1->getTitle() < d2->getTitle()); 174 } 175 } 176 } 177 178 #endif // ZIM_WRITER_DIRENT_H 179 180