|
Packit |
df99a1 |
//C- -*- C++ -*-
|
|
Packit |
df99a1 |
//C- -------------------------------------------------------------------
|
|
Packit |
df99a1 |
//C- DjVuLibre-3.5
|
|
Packit |
df99a1 |
//C- Copyright (c) 2002 Leon Bottou and Yann Le Cun.
|
|
Packit |
df99a1 |
//C- Copyright (c) 2001 AT&T
|
|
Packit |
df99a1 |
//C-
|
|
Packit |
df99a1 |
//C- This software is subject to, and may be distributed under, the
|
|
Packit |
df99a1 |
//C- GNU General Public License, either Version 2 of the license,
|
|
Packit |
df99a1 |
//C- or (at your option) any later version. The license should have
|
|
Packit |
df99a1 |
//C- accompanied the software or you may obtain a copy of the license
|
|
Packit |
df99a1 |
//C- from the Free Software Foundation at http://www.fsf.org .
|
|
Packit |
df99a1 |
//C-
|
|
Packit |
df99a1 |
//C- This program is distributed in the hope that it will be useful,
|
|
Packit |
df99a1 |
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
df99a1 |
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
df99a1 |
//C- GNU General Public License for more details.
|
|
Packit |
df99a1 |
//C-
|
|
Packit |
df99a1 |
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
|
|
Packit |
df99a1 |
//C- Lizardtech Software. Lizardtech Software has authorized us to
|
|
Packit |
df99a1 |
//C- replace the original DjVu(r) Reference Library notice by the following
|
|
Packit |
df99a1 |
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
|
|
Packit |
df99a1 |
//C-
|
|
Packit |
df99a1 |
//C- ------------------------------------------------------------------
|
|
Packit |
df99a1 |
//C- | DjVu (r) Reference Library (v. 3.5)
|
|
Packit |
df99a1 |
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
|
|
Packit |
df99a1 |
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
|
|
Packit |
df99a1 |
//C- | 6,058,214 and patents pending.
|
|
Packit |
df99a1 |
//C- |
|
|
Packit |
df99a1 |
//C- | This software is subject to, and may be distributed under, the
|
|
Packit |
df99a1 |
//C- | GNU General Public License, either Version 2 of the license,
|
|
Packit |
df99a1 |
//C- | or (at your option) any later version. The license should have
|
|
Packit |
df99a1 |
//C- | accompanied the software or you may obtain a copy of the license
|
|
Packit |
df99a1 |
//C- | from the Free Software Foundation at http://www.fsf.org .
|
|
Packit |
df99a1 |
//C- |
|
|
Packit |
df99a1 |
//C- | The computer code originally released by LizardTech under this
|
|
Packit |
df99a1 |
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
|
|
Packit |
df99a1 |
//C- | ORIGINAL CODE." Subject to any third party intellectual property
|
|
Packit |
df99a1 |
//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
|
|
Packit |
df99a1 |
//C- | non-exclusive license to make, use, sell, or otherwise dispose of
|
|
Packit |
df99a1 |
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
|
|
Packit |
df99a1 |
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
|
|
Packit |
df99a1 |
//C- | General Public License. This grant only confers the right to
|
|
Packit |
df99a1 |
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
|
|
Packit |
df99a1 |
//C- | the extent such infringement is reasonably necessary to enable
|
|
Packit |
df99a1 |
//C- | recipient to make, have made, practice, sell, or otherwise dispose
|
|
Packit |
df99a1 |
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
|
|
Packit |
df99a1 |
//C- | any greater extent that may be necessary to utilize further
|
|
Packit |
df99a1 |
//C- | modifications or combinations.
|
|
Packit |
df99a1 |
//C- |
|
|
Packit |
df99a1 |
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
|
|
Packit |
df99a1 |
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
Packit |
df99a1 |
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
|
|
Packit |
df99a1 |
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit |
df99a1 |
//C- +------------------------------------------------------------------
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
df99a1 |
# include "config.h"
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
#if NEED_GNUG_PRAGMAS
|
|
Packit |
df99a1 |
# pragma implementation
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#include <ctype.h>
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#include "DjVuDocument.h"
|
|
Packit |
df99a1 |
#include "DjVmNav.h"
|
|
Packit |
df99a1 |
#include "BSByteStream.h"
|
|
Packit |
df99a1 |
#include "GURL.h"
|
|
Packit |
df99a1 |
#include "debug.h"
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#ifdef HAVE_NAMESPACES
|
|
Packit |
df99a1 |
namespace DJVU {
|
|
Packit |
df99a1 |
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVmNav::DjVuBookMark>
|
|
Packit |
df99a1 |
DjVmNav::DjVuBookMark::create(void)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return new DjVuBookMark();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVmNav::DjVuBookMark>
|
|
Packit |
df99a1 |
DjVmNav::DjVuBookMark::create(const unsigned short count,
|
|
Packit |
df99a1 |
const GUTF8String &displayname,
|
|
Packit |
df99a1 |
const GUTF8String &url)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuBookMark *pvm=new DjVuBookMark();
|
|
Packit |
df99a1 |
GP<DjVuBookMark> bookmark=pvm;
|
|
Packit |
df99a1 |
pvm->count=count;
|
|
Packit |
df99a1 |
pvm->displayname=displayname;
|
|
Packit |
df99a1 |
pvm->url=url;
|
|
Packit |
df99a1 |
return bookmark;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
DjVmNav::DjVuBookMark::DjVuBookMark(void)
|
|
Packit |
df99a1 |
: count(0), displayname(), url()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVmNav>
|
|
Packit |
df99a1 |
DjVmNav::create(void)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return new DjVmNav;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Decode the input bytestream and populate this object
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVmNav::DjVuBookMark::decode(const GP<ByteStream> &gstr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int textsize=0, readsize=0;
|
|
Packit |
df99a1 |
char *buffer=0;
|
|
Packit |
df99a1 |
ByteStream &bs=*gstr;
|
|
Packit |
df99a1 |
count = bs.read8();
|
|
Packit |
df99a1 |
displayname.empty();
|
|
Packit |
df99a1 |
#ifdef DJVMNAV_WITH_256LIMIT
|
|
Packit |
df99a1 |
textsize = bs.read24();
|
|
Packit |
df99a1 |
#else
|
|
Packit |
df99a1 |
int counthi = bs.read8();
|
|
Packit |
df99a1 |
count = (counthi<<8)+ count;
|
|
Packit |
df99a1 |
textsize = bs.read16();
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
if (textsize)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
buffer = displayname.getbuf(textsize);
|
|
Packit |
df99a1 |
readsize = bs.read(buffer,textsize);
|
|
Packit |
df99a1 |
buffer[readsize] = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
url.empty();
|
|
Packit |
df99a1 |
textsize = bs.read24();
|
|
Packit |
df99a1 |
if (textsize)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
buffer = url.getbuf(textsize);
|
|
Packit |
df99a1 |
readsize = bs.read(buffer,textsize);
|
|
Packit |
df99a1 |
buffer[readsize] = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Serialize this object to the output bytestream
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVmNav::DjVuBookMark::encode(const GP<ByteStream> &gstr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int textsize=0;
|
|
Packit |
df99a1 |
ByteStream &bs=*gstr;
|
|
Packit |
df99a1 |
#ifdef DJVMNAV_WITH_256LIMIT
|
|
Packit |
df99a1 |
if (count>255)
|
|
Packit |
df99a1 |
G_THROW("Excessive number of children in bookmark tree");
|
|
Packit |
df99a1 |
bs.write8(count);
|
|
Packit |
df99a1 |
textsize = displayname.length();
|
|
Packit |
df99a1 |
bs.write24( textsize );
|
|
Packit |
df99a1 |
#else
|
|
Packit |
df99a1 |
if (count>65535)
|
|
Packit |
df99a1 |
G_THROW("Excessive number of children in bookmark tree");
|
|
Packit |
df99a1 |
bs.write8( count & 0xff );
|
|
Packit |
df99a1 |
bs.write8( (count>>8) & 0xff );
|
|
Packit |
df99a1 |
textsize = displayname.length();
|
|
Packit |
df99a1 |
bs.write16( textsize );
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
bs.writestring(displayname);
|
|
Packit |
df99a1 |
textsize = url.length();
|
|
Packit |
df99a1 |
bs.write24( textsize );
|
|
Packit |
df99a1 |
bs.writestring(url);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Text dump of this object to the output bytestream
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVmNav::DjVuBookMark::dump(const GP<ByteStream> &gstr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int textsize=0;
|
|
Packit |
df99a1 |
ByteStream &bs=*gstr;
|
|
Packit |
df99a1 |
bs.format("\n count=%d\n",count);
|
|
Packit |
df99a1 |
textsize = displayname.length();
|
|
Packit |
df99a1 |
bs.format(" (%d) %s\n",textsize, displayname.getbuf());
|
|
Packit |
df99a1 |
textsize = url.length();
|
|
Packit |
df99a1 |
bs.format(" (%d) %s\n",textsize, url.getbuf());
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Decode the input bytestream and populate this object
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVmNav::decode(const GP<ByteStream> &gstr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
//ByteStream &str=*gstr;
|
|
Packit |
df99a1 |
GP<ByteStream> gpBSByteStream = BSByteStream::create(gstr);
|
|
Packit |
df99a1 |
GCriticalSectionLock lock(&class_lock);
|
|
Packit |
df99a1 |
bookmark_list.empty();
|
|
Packit |
df99a1 |
int nbookmarks=gpBSByteStream->read16();
|
|
Packit |
df99a1 |
if (nbookmarks)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for(int bookmark=0;bookmark
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuBookMark> pBookMark=DjVuBookMark::create();
|
|
Packit |
df99a1 |
pBookMark->decode(gpBSByteStream);
|
|
Packit |
df99a1 |
bookmark_list.append(pBookMark);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Serialize this object to the output stream
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVmNav::encode(const GP<ByteStream> &gstr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
//ByteStream &str=*gstr;
|
|
Packit |
df99a1 |
GP<ByteStream> gpBSByteStream = BSByteStream::create(gstr, 1024);
|
|
Packit |
df99a1 |
GCriticalSectionLock lock(&class_lock);
|
|
Packit |
df99a1 |
int nbookmarks=bookmark_list.size();
|
|
Packit |
df99a1 |
gpBSByteStream->write16(nbookmarks);
|
|
Packit |
df99a1 |
if (nbookmarks)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GPosition pos;
|
|
Packit |
df99a1 |
int cnt=0;
|
|
Packit |
df99a1 |
for (pos = bookmark_list; pos; ++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bookmark_list[pos]->encode(gpBSByteStream);
|
|
Packit |
df99a1 |
cnt++;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (nbookmarks != cnt)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GUTF8String msg;
|
|
Packit |
df99a1 |
msg.format("Corrupt bookmarks found during encode: %d of %d \n",
|
|
Packit |
df99a1 |
cnt, nbookmarks);
|
|
Packit |
df99a1 |
G_THROW (msg);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVmNav::getBookMarkCount()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return(bookmark_list.size());
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVmNav::append (const GP<DjVuBookMark> &gpBookMark)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bookmark_list.append(gpBookMark);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
DjVmNav::getBookMark(GP<DjVuBookMark> &gpBookMark, int iPos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GPosition pos = bookmark_list.nth(iPos);
|
|
Packit |
df99a1 |
if (pos)
|
|
Packit |
df99a1 |
gpBookMark = bookmark_list[pos];
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
gpBookMark = 0;
|
|
Packit |
df99a1 |
return (gpBookMark?true:false);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// A text dump of this object
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVmNav::dump(const GP<ByteStream> &gstr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ByteStream &str=*gstr;
|
|
Packit |
df99a1 |
GCriticalSectionLock lock(&class_lock);
|
|
Packit |
df99a1 |
int nbookmarks=bookmark_list.size();
|
|
Packit |
df99a1 |
str.format("%d bookmarks:\n",nbookmarks);
|
|
Packit |
df99a1 |
if (nbookmarks)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GPosition pos;
|
|
Packit |
df99a1 |
int cnt=0;
|
|
Packit |
df99a1 |
for (pos = bookmark_list; pos; ++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bookmark_list[pos]->dump(&str);
|
|
Packit |
df99a1 |
cnt++;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (nbookmarks != cnt)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GUTF8String msg;
|
|
Packit |
df99a1 |
msg.format("Corrupt bookmarks found during encode: %d of %d \n",
|
|
Packit |
df99a1 |
cnt,nbookmarks);
|
|
Packit |
df99a1 |
G_THROW (msg);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
DjVmNav::isValidBookmark()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
//test if the bookmark is properly given
|
|
Packit |
df99a1 |
//for example: (4, "A", urla)
|
|
Packit |
df99a1 |
// (0, "B", urlb)
|
|
Packit |
df99a1 |
// (0, "C", urlc)
|
|
Packit |
df99a1 |
//is not a bookmark since A suppose to have 4 decendents, it only get one.
|
|
Packit |
df99a1 |
int bookmark_totalnum=getBookMarkCount();
|
|
Packit |
df99a1 |
GP<DjVuBookMark> gpBookMark;
|
|
Packit |
df99a1 |
int* count_array=(int*)malloc(sizeof(int)*bookmark_totalnum);
|
|
Packit |
df99a1 |
for(int i=0;i
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
getBookMark(gpBookMark, i);
|
|
Packit |
df99a1 |
count_array[i]=gpBookMark->count;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
int index=0;
|
|
Packit |
df99a1 |
int trees=0;
|
|
Packit |
df99a1 |
int* treeSizes=(int*)malloc(sizeof(int)*bookmark_totalnum);
|
|
Packit |
df99a1 |
while(index
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int treeSize=get_tree(index,count_array,bookmark_totalnum);
|
|
Packit |
df99a1 |
if(treeSize>0) //is a tree
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
index+=treeSize;
|
|
Packit |
df99a1 |
treeSizes[trees++]=treeSize;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else //not a tree
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
free(count_array);
|
|
Packit |
df99a1 |
free(treeSizes);
|
|
Packit |
df99a1 |
return true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVmNav::get_tree(int index, int* count_array, int count_array_size)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int i=index;
|
|
Packit |
df99a1 |
int accumulate_count=0;
|
|
Packit |
df99a1 |
while(i
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
accumulate_count+=count_array[i];
|
|
Packit |
df99a1 |
if(accumulate_count==0)
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
else if(accumulate_count == i-index) //get a tree
|
|
Packit |
df99a1 |
return accumulate_count;
|
|
Packit |
df99a1 |
i++;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#ifdef HAVE_NAMESPACES
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
# ifndef NOT_USING_DJVU_NAMESPACE
|
|
Packit |
df99a1 |
using namespace DJVU;
|
|
Packit |
df99a1 |
# endif
|
|
Packit |
df99a1 |
#endif
|