kviewshell
DjVmNav.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 #ifdef HAVE_CONFIG_H
00058 # include "config.h"
00059 #endif
00060 #if NEED_GNUG_PRAGMAS
00061 # pragma implementation
00062 #endif
00063
00064 #include <ctype.h>
00065
00066 #include "DjVuDocument.h"
00067 #include "DjVmNav.h"
00068 #include "BSByteStream.h"
00069 #include "GURL.h"
00070 #include "debug.h"
00071
00072 #ifdef HAVE_NAMESPACES
00073 namespace DJVU {
00074 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00075 }
00076 #endif
00077 #endif
00078
00079
00080 GP<DjVmNav::DjVuBookMark>
00081 DjVmNav::DjVuBookMark::create(void)
00082 {
00083 return new DjVuBookMark();
00084 }
00085
00086 GP<DjVmNav::DjVuBookMark>
00087 DjVmNav::DjVuBookMark::create(const unsigned short count,
00088 const GUTF8String &displayname,
00089 const GUTF8String &url)
00090 {
00091 DjVuBookMark *pvm=new DjVuBookMark();
00092 GP<DjVuBookMark> bookmark=pvm;
00093 pvm->count=count;
00094 pvm->displayname=displayname;
00095 pvm->url=url;
00096 return bookmark;
00097 }
00098
00099 DjVmNav::DjVuBookMark::DjVuBookMark(void)
00100 : count(0), displayname(), url()
00101 {
00102 }
00103
00104 GP<DjVmNav>
00105 DjVmNav::create(void)
00106 {
00107 return new DjVmNav;
00108 }
00109
00110
00111 void
00112 DjVmNav::DjVuBookMark::decode(const GP<ByteStream> &gstr)
00113 {
00114 int textsize=0, readsize=0;
00115 char *buffer=0;
00116 ByteStream &bs=*gstr;
00117 count = bs.read8();
00118 displayname.empty();
00119 #ifdef DJVMNAV_WITH_256LIMIT
00120 textsize = bs.read24();
00121 #else
00122 int counthi = bs.read8();
00123 count = (counthi<<8)+ count;
00124 textsize = bs.read16();
00125 #endif
00126 if (textsize)
00127 {
00128 buffer = displayname.getbuf(textsize);
00129 readsize = bs.read(buffer,textsize);
00130 buffer[readsize] = 0;
00131 }
00132 url.empty();
00133 textsize = bs.read24();
00134 if (textsize)
00135 {
00136 buffer = url.getbuf(textsize);
00137 readsize = bs.read(buffer,textsize);
00138 buffer[readsize] = 0;
00139 }
00140 }
00141
00142
00143 void
00144 DjVmNav::DjVuBookMark::encode(const GP<ByteStream> &gstr)
00145 {
00146 int textsize=0;
00147 ByteStream &bs=*gstr;
00148 #ifdef DJVMNAV_WITH_256LIMIT
00149 if (count>255)
00150 G_THROW("Excessive number of children in bookmark tree");
00151 bs.write8(count);
00152 textsize = displayname.length();
00153 bs.write24( textsize );
00154 #else
00155 if (count>65535)
00156 G_THROW("Excessive number of children in bookmark tree");
00157 bs.write8( count & 0xff );
00158 bs.write8( (count>>8) & 0xff );
00159 textsize = displayname.length();
00160 bs.write16( textsize );
00161 #endif
00162 bs.writestring(displayname);
00163 textsize = url.length();
00164 bs.write24( textsize );
00165 bs.writestring(url);
00166 }
00167
00168
00169 void
00170 DjVmNav::DjVuBookMark::dump(const GP<ByteStream> &gstr)
00171 {
00172 int textsize=0;
00173 ByteStream &bs=*gstr;
00174 bs.format("\n count=%d\n",count);
00175 textsize = displayname.length();
00176 bs.format(" (%d) %s\n",textsize, displayname.getbuf());
00177 textsize = url.length();
00178 bs.format(" (%d) %s\n",textsize, url.getbuf());
00179 }
00180
00181
00182 void
00183 DjVmNav::decode(const GP<ByteStream> &gstr)
00184 {
00185
00186 GP<ByteStream> gpBSByteStream = BSByteStream::create(gstr);
00187 GCriticalSectionLock lock(&class_lock);
00188 bookmark_list.empty();
00189 int nbookmarks=gpBSByteStream->read16();
00190 if (nbookmarks)
00191 {
00192 for(int bookmark=0;bookmark<nbookmarks;bookmark++)
00193 {
00194 GP<DjVuBookMark> pBookMark=DjVuBookMark::create();
00195 pBookMark->decode(gpBSByteStream);
00196 bookmark_list.append(pBookMark);
00197 }
00198 }
00199 }
00200
00201
00202 void
00203 DjVmNav::encode(const GP<ByteStream> &gstr)
00204 {
00205
00206 GP<ByteStream> gpBSByteStream = BSByteStream::create(gstr, 1024);
00207 GCriticalSectionLock lock(&class_lock);
00208 int nbookmarks=bookmark_list.size();
00209 gpBSByteStream->write16(nbookmarks);
00210 if (nbookmarks)
00211 {
00212 GPosition pos;
00213 int cnt=0;
00214 for (pos = bookmark_list; pos; ++pos)
00215 {
00216 bookmark_list[pos]->encode(gpBSByteStream);
00217 cnt++;
00218 }
00219 if (nbookmarks != cnt)
00220 {
00221 GUTF8String msg;
00222 msg.format("Corrupt bookmarks found during encode: %d of %d \n",
00223 cnt, nbookmarks);
00224 G_THROW (msg);
00225 }
00226 }
00227 }
00228
00229 int
00230 DjVmNav::getBookMarkCount()
00231 {
00232 return(bookmark_list.size());
00233 }
00234
00235 void
00236 DjVmNav::append (const GP<DjVuBookMark> &gpBookMark)
00237 {
00238 bookmark_list.append(gpBookMark);
00239 }
00240
00241 bool
00242 DjVmNav::getBookMark(GP<DjVuBookMark> &gpBookMark, int iPos)
00243 {
00244 GPosition pos = bookmark_list.nth(iPos);
00245 if (pos)
00246 gpBookMark = bookmark_list[pos];
00247 else
00248 gpBookMark = 0;
00249 return (gpBookMark?true:false);
00250 }
00251
00252
00253
00254 void
00255 DjVmNav::dump(const GP<ByteStream> &gstr)
00256 {
00257 ByteStream &str=*gstr;
00258 GCriticalSectionLock lock(&class_lock);
00259 int nbookmarks=bookmark_list.size();
00260 str.format("%d bookmarks:\n",nbookmarks);
00261 if (nbookmarks)
00262 {
00263 GPosition pos;
00264 int cnt=0;
00265 for (pos = bookmark_list; pos; ++pos)
00266 {
00267 bookmark_list[pos]->dump(&str);
00268 cnt++;
00269 }
00270 if (nbookmarks != cnt)
00271 {
00272 GUTF8String msg;
00273 msg.format("Corrupt bookmarks found during encode: %d of %d \n",
00274 cnt,nbookmarks);
00275 G_THROW (msg);
00276 }
00277 }
00278 }
00279
00280 bool
00281 DjVmNav::isValidBookmark()
00282 {
00283
00284
00285
00286
00287
00288 int bookmark_totalnum=getBookMarkCount();
00289 GP<DjVuBookMark> gpBookMark;
00290 int* count_array=(int*)malloc(sizeof(int)*bookmark_totalnum);
00291 for(int i=0;i<bookmark_totalnum;i++)
00292 {
00293 getBookMark(gpBookMark, i);
00294 count_array[i]=gpBookMark->count;
00295 }
00296 int index=0;
00297 int trees=0;
00298 int* treeSizes=(int*)malloc(sizeof(int)*bookmark_totalnum);
00299 while(index<bookmark_totalnum)
00300 {
00301 int treeSize=get_tree(index,count_array,bookmark_totalnum);
00302 if(treeSize>0)
00303 {
00304 index+=treeSize;
00305 treeSizes[trees++]=treeSize;
00306 }
00307 else
00308 break;
00309 }
00310 free(count_array);
00311 free(treeSizes);
00312 return true;
00313 }
00314
00315 int
00316 DjVmNav::get_tree(int index, int* count_array, int count_array_size)
00317 {
00318 int i=index;
00319 int accumulate_count=0;
00320 while(i<count_array_size)
00321 {
00322 accumulate_count+=count_array[i];
00323 if(accumulate_count==0)
00324 return 1;
00325 else if(accumulate_count == i-index)
00326 return accumulate_count;
00327 i++;
00328 }
00329 return 0;
00330 }
00331
00332
00333 #ifdef HAVE_NAMESPACES
00334 }
00335 # ifndef NOT_USING_DJVU_NAMESPACE
00336 using namespace DJVU;
00337 # endif
00338 #endif