source: trunk/libdjvu/DjVmNav.cpp @ 81

Last change on this file since 81 was 17, checked in by Eugene Romanenko, 16 years ago

update makefiles, remove absolute paths, update djvulibre to version 3.5.17

File size: 9.5 KB
Line 
1//C-  -*- C++ -*-
2//C- -------------------------------------------------------------------
3//C- DjVuLibre-3.5
4//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
5//C- Copyright (c) 2001  AT&T
6//C-
7//C- This software is subject to, and may be distributed under, the
8//C- GNU General Public License, Version 2. The license should have
9//C- accompanied the software or you may obtain a copy of the license
10//C- from the Free Software Foundation at http://www.fsf.org .
11//C-
12//C- This program is distributed in the hope that it will be useful,
13//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
14//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15//C- GNU General Public License for more details.
16//C-
17//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
18//C- distributed by Lizardtech Software.  On July 19th 2002, Lizardtech
19//C- Software authorized us to replace the original DjVu(r) Reference
20//C- Library notice by the following text (see doc/lizard2002.djvu):
21//C-
22//C-  ------------------------------------------------------------------
23//C- | DjVu (r) Reference Library (v. 3.5)
24//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
25//C- | The DjVu Reference Library is protected by U.S. Pat. No.
26//C- | 6,058,214 and patents pending.
27//C- |
28//C- | This software is subject to, and may be distributed under, the
29//C- | GNU General Public License, Version 2. The license should have
30//C- | accompanied the software or you may obtain a copy of the license
31//C- | from the Free Software Foundation at http://www.fsf.org .
32//C- |
33//C- | The computer code originally released by LizardTech under this
34//C- | license and unmodified by other parties is deemed "the LIZARDTECH
35//C- | ORIGINAL CODE."  Subject to any third party intellectual property
36//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
37//C- | non-exclusive license to make, use, sell, or otherwise dispose of
38//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
39//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
40//C- | General Public License.   This grant only confers the right to
41//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
42//C- | the extent such infringement is reasonably necessary to enable
43//C- | recipient to make, have made, practice, sell, or otherwise dispose
44//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
45//C- | any greater extent that may be necessary to utilize further
46//C- | modifications or combinations.
47//C- |
48//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
49//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
50//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
51//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
52//C- +------------------------------------------------------------------
53//
54// $Id: DjVmNav.cpp,v 1.1 2005/05/25 17:36:53 leonb Exp $
55// $Name:  $
56
57#ifdef HAVE_CONFIG_H
58# include "config.h"
59#endif
60#if NEED_GNUG_PRAGMAS
61# pragma implementation
62#endif
63
64#include <ctype.h>
65
66#include "DjVuDocument.h"
67#include "DjVmNav.h"
68#include "BSByteStream.h"
69#include "GURL.h"
70#include "debug.h"
71
72#ifdef HAVE_NAMESPACES
73namespace DJVU {
74# ifdef NOT_DEFINED // Just to fool emacs c++ mode
75}
76#endif
77#endif
78
79
80GP<DjVmNav::DjVuBookMark>
81DjVmNav::DjVuBookMark::create(void)
82{
83  return new DjVuBookMark();
84}
85
86GP<DjVmNav::DjVuBookMark>
87DjVmNav::DjVuBookMark::create(const unsigned short count,
88                              const GUTF8String &displayname, 
89                              const GUTF8String &url)
90{
91  DjVuBookMark *pvm=new DjVuBookMark();
92  GP<DjVuBookMark> bookmark=pvm;
93  pvm->count=count;
94  pvm->displayname=displayname;
95  pvm->url=url;
96  return bookmark;
97}   
98
99DjVmNav::DjVuBookMark::DjVuBookMark(void)
100  : count(0), displayname(), url()
101{ 
102}
103
104GP<DjVmNav>
105DjVmNav::create(void)
106{
107  return new DjVmNav;
108}
109
110// Decode the input bytestream and populate this object
111void 
112DjVmNav::DjVuBookMark::decode(const GP<ByteStream> &gstr)
113{
114  int textsize=0, readsize=0;
115  char *buffer=0;
116  ByteStream &bs=*gstr;
117  count = bs.read8();
118  displayname.empty();
119#ifdef DJVMNAV_WITH_256LIMIT
120  textsize = bs.read24();
121#else
122  int counthi = bs.read8();
123  count = (counthi<<8)+ count;
124  textsize = bs.read16();
125#endif
126  if (textsize)
127    {
128      buffer = displayname.getbuf(textsize);
129      readsize = bs.read(buffer,textsize);
130      buffer[readsize] = 0;
131    }
132  url.empty();
133  textsize = bs.read24();
134  if (textsize)
135    {
136      buffer = url.getbuf(textsize);
137      readsize = bs.read(buffer,textsize);
138      buffer[readsize] = 0;
139    }
140}
141
142// Serialize this object to the output bytestream
143void 
144DjVmNav::DjVuBookMark::encode(const GP<ByteStream> &gstr) 
145{
146  int textsize=0;
147  ByteStream &bs=*gstr;
148#ifdef DJVMNAV_WITH_256LIMIT
149  if (count>255)
150    G_THROW("Excessive number of children in bookmark tree");
151  bs.write8(count);
152  textsize = displayname.length();
153  bs.write24( textsize );
154#else
155  if (count>65535)
156    G_THROW("Excessive number of children in bookmark tree");
157  bs.write8( count & 0xff );
158  bs.write8( (count>>8) & 0xff );
159  textsize = displayname.length();
160  bs.write16( textsize );
161#endif
162  bs.writestring(displayname);
163  textsize = url.length();
164  bs.write24( textsize );
165  bs.writestring(url);
166}
167
168// Text dump of this object to the output bytestream
169void 
170DjVmNav::DjVuBookMark::dump(const GP<ByteStream> &gstr) 
171{
172  int textsize=0;
173  ByteStream &bs=*gstr;
174  bs.format("\n  count=%d\n",count);
175  textsize = displayname.length();
176  bs.format("  (%d) %s\n",textsize, displayname.getbuf());
177  textsize = url.length();
178  bs.format("  (%d) %s\n",textsize, url.getbuf());
179}
180
181// Decode the input bytestream and populate this object
182void 
183DjVmNav::decode(const GP<ByteStream> &gstr)
184{
185  //ByteStream &str=*gstr;
186  GP<ByteStream> gpBSByteStream = BSByteStream::create(gstr);
187  GCriticalSectionLock lock(&class_lock);
188  bookmark_list.empty();
189  int nbookmarks=gpBSByteStream->read16();
190  if (nbookmarks)
191    {
192      for(int bookmark=0;bookmark<nbookmarks;bookmark++)
193        {
194          GP<DjVuBookMark> pBookMark=DjVuBookMark::create();
195          pBookMark->decode(gpBSByteStream);
196          bookmark_list.append(pBookMark); 
197        }
198    }
199}
200
201// Serialize this object to the output stream
202void 
203DjVmNav::encode(const GP<ByteStream> &gstr)
204{
205  //ByteStream &str=*gstr;
206  GP<ByteStream> gpBSByteStream = BSByteStream::create(gstr, 1024);
207  GCriticalSectionLock lock(&class_lock);
208  int nbookmarks=bookmark_list.size();
209  gpBSByteStream->write16(nbookmarks);
210  if (nbookmarks)
211    {
212      GPosition pos;
213      int cnt=0;
214      for (pos = bookmark_list; pos; ++pos)
215        {
216          bookmark_list[pos]->encode(gpBSByteStream);
217          cnt++;
218        }
219      if (nbookmarks != cnt)
220        {
221          GUTF8String msg;
222          msg.format("Corrupt bookmarks found during encode: %d of %d \n",
223                     cnt, nbookmarks);
224          G_THROW (msg);
225        }
226    }
227}
228
229int 
230DjVmNav::getBookMarkCount()
231{
232  return(bookmark_list.size());
233}
234
235void 
236DjVmNav::append (const GP<DjVuBookMark> &gpBookMark) 
237{
238  bookmark_list.append(gpBookMark);
239}
240
241bool 
242DjVmNav::getBookMark(GP<DjVuBookMark> &gpBookMark, int iPos)
243{
244  GPosition pos = bookmark_list.nth(iPos);
245  if (pos)
246    gpBookMark = bookmark_list[pos];
247  else
248    gpBookMark = 0;
249  return (gpBookMark?true:false);
250}
251
252
253// A text dump of this object
254void 
255DjVmNav::dump(const GP<ByteStream> &gstr)
256{
257  ByteStream &str=*gstr;
258  GCriticalSectionLock lock(&class_lock);
259  int nbookmarks=bookmark_list.size();
260  str.format("%d bookmarks:\n",nbookmarks);
261  if (nbookmarks)
262    {
263      GPosition pos;
264      int cnt=0;
265      for (pos = bookmark_list; pos; ++pos)
266        {
267          bookmark_list[pos]->dump(&str);
268          cnt++;
269        }
270      if (nbookmarks != cnt)
271        {
272          GUTF8String msg;
273          msg.format("Corrupt bookmarks found during encode: %d of %d \n",
274                     cnt,nbookmarks);
275          G_THROW (msg);
276        }
277    }
278}
279
280bool 
281DjVmNav::isValidBookmark()
282{
283  //test if the bookmark is properly given
284  //for example: (4, "A", urla)
285  //             (0, "B", urlb)
286  //             (0, "C", urlc)
287  //is not a bookmark since A suppose to have 4 decendents, it only get one.
288  int bookmark_totalnum=getBookMarkCount();
289  GP<DjVuBookMark> gpBookMark;
290  int* count_array=(int*)malloc(sizeof(int)*bookmark_totalnum);
291  for(int i=0;i<bookmark_totalnum;i++)
292    {
293      getBookMark(gpBookMark, i);
294      count_array[i]=gpBookMark->count;
295    }
296  int index=0;
297  int trees=0;
298  int* treeSizes=(int*)malloc(sizeof(int)*bookmark_totalnum);
299  while(index<bookmark_totalnum)
300    {
301      int treeSize=get_tree(index,count_array,bookmark_totalnum);
302      if(treeSize>0) //is a tree
303        {
304          index+=treeSize;
305          treeSizes[trees++]=treeSize;
306        }
307      else //not a tree
308        break;
309    }
310  free(count_array);
311  free(treeSizes);
312  return true;
313}
314
315int 
316DjVmNav::get_tree(int index, int* count_array, int count_array_size)
317{
318  int i=index;
319  int accumulate_count=0;
320  while(i<count_array_size)
321    {
322      accumulate_count+=count_array[i];
323      if(accumulate_count==0)
324        return 1;
325      else if(accumulate_count == i-index) //get a tree
326        return accumulate_count;
327      i++;
328    }
329  return 0;
330}
331
332
333#ifdef HAVE_NAMESPACES
334}
335# ifndef NOT_USING_DJVU_NAMESPACE
336using namespace DJVU;
337# endif
338#endif
Note: See TracBrowser for help on using the repository browser.