summaryrefslogtreecommitdiff
authorpohly <pohly>2005-05-08 16:12:13 (UTC)
committer pohly <pohly>2005-05-08 16:12:13 (UTC)
commit2ccb0ad8b77eb3c62914f5df5b1bba3becb83617 (patch) (side-by-side diff)
treea75b6a2da7ab019dac3c078830d24bc491692d3d
parent21a9e96cebeb6e729d129cd75544ac54ae4d09f4 (diff)
downloadopie-2ccb0ad8b77eb3c62914f5df5b1bba3becb83617.zip
opie-2ccb0ad8b77eb3c62914f5df5b1bba3becb83617.tar.gz
opie-2ccb0ad8b77eb3c62914f5df5b1bba3becb83617.tar.bz2
bugfix by tim: off-by-one error when returning to a document (previous page)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-reader/plucker_base.cpp3
1 files changed, 2 insertions, 1 deletions
diff --git a/noncore/apps/opie-reader/plucker_base.cpp b/noncore/apps/opie-reader/plucker_base.cpp
index 51c7fa7..81614f5 100644
--- a/noncore/apps/opie-reader/plucker_base.cpp
+++ b/noncore/apps/opie-reader/plucker_base.cpp
@@ -1,692 +1,693 @@
#include <stdio.h>
#include <string.h>
#include <qmessagebox.h>
#include <qpixmap.h>
#ifdef USEQPE
#include <qpe/qcopenvelope_qws.h>
#endif /* USEQPE */
#ifdef LOCALPICTURES
#include <qscrollview.h>
#endif
#ifdef USEQPE
#include <qpe/global.h>
#endif /* USEQPE */
#include <qclipboard.h>
#ifndef USEQPE
#include <qapplication.h>
#else /* USEQPE */
#include <qpe/qpeapplication.h>
#endif /* USEQPE */
#include <qimage.h>
#include "plucker_base.h"
#include "Aportis.h"
#include "hrule.h"
#include "decompress.h"
const UInt8 CPlucker_base::continuation_bit = 1;
CPlucker_base::CPlucker_base() :
#ifdef LOCALPICTURES
m_viewer(NULL),
m_picture(NULL),
#endif
expandedtextbuffer(NULL),
compressedtextbuffer(NULL),
bufferrec(-1),
m_offset(0)
//, urls(NULL)
{ /*printf("constructing:%x\n",fin);*/ }
void CPlucker_base::Expand(UInt32 reclen, UInt8 type, UInt8* buffer, UInt32 buffersize)
{
unsuspend();
if ((type%2 == 0) && (type != 14))
{
fread(buffer, reclen, sizeof(char), fin);
}
else
{
UInt8* readbuffer = NULL;
if (reclen > compressedbuffersize)
{
readbuffer = new UInt8[reclen];
}
else
{
readbuffer = compressedtextbuffer;
}
if (readbuffer != NULL)
{
fread(readbuffer, reclen, sizeof(char), fin);
(*m_decompress)(readbuffer, reclen, buffer, buffersize);
if (reclen > compressedbuffersize)
{
delete [] readbuffer;
}
}
}
}
void CPlucker_base::sizes(unsigned long& _file, unsigned long& _text)
{
_file = file_length;
if (textlength == 0)
{
for (int recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++)
{
gotorecordnumber(recptr);
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size;
UInt8 thishdr_type, thishdr_reserved;
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
if (thishdr_type < 2) textlength += thishdr_size;
}
}
_text = textlength;
//ntohl(hdr0.size);
}
char* CPlucker_base::geturl(UInt16 tgt)
{
char * pRet = NULL;
gotorecordnumber(0);
fread(&hdr0, 1, 6, fin);
unsigned int nrecs = ntohs(hdr0.nRecords);
//qDebug("Version %u, no. recs %u", ntohs(hdr0.version), nrecs);
UInt16 urlid = 0;
bool urlsfound = false;
char* urls = NULL;
size_t urlsize = 0;
for (unsigned int i = 0; i < nrecs; i++)
{
UInt16 id, name;
fread(&name, 1, sizeof(name), fin);
fread(&id, 1, sizeof(id), fin);
//qDebug("N:%d, I:%d", ntohs(name), ntohs(id));
if (ntohs(name) == 2)
{
urlsfound = true;
urlid = id;
//qDebug("Found url index:%d", ntohs(urlid));
}
// //qDebug("%x", id);
}
if (urlsfound)
{
unsigned short recptr = finduid(ntohs(urlid));
if (recptr != 0)
{
gotorecordnumber(recptr);
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size;
UInt8 thishdr_type, thishdr_reserved;
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
UInt16 urlctr = 0;
while (1)
{
UInt16 tctr;
fread(&tctr, 1, sizeof(tctr), fin);
fread(&urlid, 1, sizeof(urlid), fin);
tctr = ntohs(tctr);
//qDebug("tgt:%u urlctr:%u tctr:%u", tgt, urlctr, tctr);
if (tctr >= tgt)
{
break;
}
urlctr = tctr;
}
//qDebug("urls are in %d", ntohs(urlid));
recptr = finduid(ntohs(urlid));
if (recptr != 0)
{
UInt32 reclen = recordlength(recptr) - HeaderSize();
gotorecordnumber(recptr);
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
//qDebug("Found urls:%x",thishdr_type);
urlsize = thishdr_size;
urls = new char[urlsize];
Expand(reclen, thishdr_type, (UInt8*)urls, urlsize);
char* ptr = urls;
int rn = urlctr+1;
while (ptr - urls < urlsize)
{
if (rn == tgt)
{
//qDebug("URL:%s", ptr);
int len = strlen(ptr)+1;
pRet = new char[len];
memcpy(pRet, ptr, len);
break;
}
ptr += strlen(ptr)+1;
rn++;
}
delete [] urls;
}
}
}
else
{
pRet = NULL;
}
return pRet;
}
CPlucker_base::~CPlucker_base()
{
if (expandedtextbuffer != NULL) delete [] expandedtextbuffer;
if (compressedtextbuffer != NULL) delete [] compressedtextbuffer;
#ifdef LOCALPICTURES
if (m_viewer != NULL) delete m_viewer;
#endif
}
int CPlucker_base::getch() { return getch(false); }
void CPlucker_base::getch(tchar& ch, CStyle& sty, unsigned long& pos)
{
pos = locate();
ch = getch(false);
sty = mystyle;
}
unsigned int CPlucker_base::locate()
{
return currentpos;
/*
UInt16 thisrec = 1;
unsigned long locpos = 0;
gotorecordnumber(thisrec);
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size;
UInt8 thishdr_type, thishdr_reserved;
while (thisrec < bufferrec)
{
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
if (thishdr_type < 2) locpos += thishdr_size;
thisrec++;
gotorecordnumber(thisrec);
}
return locpos+bufferpos;
*/
}
void CPlucker_base::locate(unsigned int n)
{
// clock_t start = clock();
if (n >= currentpos-bufferpos && n < currentpos - bufferpos + buffercontent)
{
currentpos -= bufferpos;
expand(bufferrec);
while (currentpos < n && bufferpos < buffercontent) getch_base(true);
return;
}
/*
UInt32 textlength = currentpos - bufferpos;
UInt16 recptr = bufferrec;
if (n < textlength/2)
{
textlength = 0;
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size = buffercontent;
UInt8 thishdr_type, thishdr_reserved;
for (recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++)
{
gotorecordnumber(recptr);
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
if (thishdr_type < 2)
{
textlength += thishdr_size;
if (textlength > n)
{
textlength -= thishdr_size;
break;
}
}
}
}
else if (n < textlength)
{
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size;
UInt8 thishdr_type, thishdr_reserved;
while (n < textlength && recptr > 1)
{
recptr--;
gotorecordnumber(recptr);
//qDebug("recptr:%u", recptr);
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
if (thishdr_type < 2)
{
textlength -= thishdr_size;
}
}
}
else
{
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size = buffercontent;
UInt8 thishdr_type, thishdr_reserved;
while (n > textlength + thishdr_size && recptr < ntohs(head.recordList.numRecords)-1)
{
textlength += thishdr_size;
recptr++;
gotorecordnumber(recptr);
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
if (!(thishdr_type < 2))
{
thishdr_size = 0;
}
}
}
*/
UInt16 thisrec = 0;
unsigned long locpos = 0;
unsigned long bs = 0;
+ unsigned int np1 = n+1;
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size;
UInt8 thishdr_type, thishdr_reserved;
do
{
thisrec++;
locpos += bs;
gotorecordnumber(thisrec);
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
if (thishdr_type < 2)
{
bs = thishdr_size;
}
else
{
bs = 0;
}
- } while (locpos + bs < n);
+ } while (locpos + bs < np1);
// qDebug("Time(2): %u", clock()-start);
/*
if (recptr != thisrec)
{
qDebug("Disaster:recptr:%u thisrec:%u", recptr, thisrec);
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size = buffercontent;
UInt8 thishdr_type, thishdr_reserved;
for (recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++)
{
gotorecordnumber(recptr);
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
// qDebug("UID:%u Paras:%u Size:%u Type:%u Reserved:%u", thishdr_uid, thishdr_nParagraphs, thishdr_size, (unsigned int)thishdr_type, (unsigned int)thishdr_reserved);
}
// QApplication::exit ( 100 );
}
*/
currentpos = locpos;
expand(thisrec);
while (currentpos < n && bufferpos < buffercontent) getch_base(true);
/* // This is faster but the alignment attribute doesn't get set 8^(
bufferpos = n-locpos;
currentpos = n;
while (bufferpos >= m_nextPara && m_nextPara >= 0)
{
UInt16 attr = m_ParaAttrs[m_nextParaIndex];
m_nextParaIndex++;
if (m_nextParaIndex == m_nParas)
{
m_nextPara = -1;
}
else
{
m_nextPara += m_ParaOffsets[m_nextParaIndex];
}
}
*/
}
bool CPlucker_base::expand(int thisrec)
{
mystyle.unset();
if (bufferrec != thisrec)
{
size_t reclen = recordlength(thisrec);
gotorecordnumber(thisrec);
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size;
UInt8 thishdr_type, thishdr_reserved;
while (1)
{
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
//qDebug("This (%d) type is %d, uid is %u", thisrec, thishdr_type, thishdr_uid);
if (thishdr_type < 2) break;
//qDebug("Skipping paragraph of type %d", thishdr_type);
if (++thisrec >= ntohs(head.recordList.numRecords) - 1) return false;
reclen = recordlength(thisrec);
gotorecordnumber(thisrec);
}
m_nParas = thishdr_nParagraphs;
m_bufferisreserved = (thishdr_reserved != 0);
//qDebug("It has %u paragraphs and is %u bytes", thishdr_nParagraphs, thishdr_size);
uid = thishdr_uid;
// gotorecordnumber(thisrec);
// fread(expandedtextbuffer,1,10,fin);
for (int i = 0; i < m_nParas; i++)
{
UInt16 ubytes, attrs;
fread(&ubytes, 1, sizeof(ubytes), fin);
fread(&attrs, 1, sizeof(attrs), fin);
m_ParaOffsets[i] = ntohs(ubytes);
m_ParaAttrs[i] = ntohs(attrs);
// //qDebug("Bytes %u, Attr %x", ntohs(ubytes), ntohs(attrs));
}
reclen -= HeaderSize()+4*m_nParas;
buffercontent = thishdr_size;
if (thishdr_size > buffersize)
{
delete [] expandedtextbuffer;
buffersize = thishdr_size;
expandedtextbuffer = new UInt8[buffersize];
}
Expand(reclen, thishdr_type, expandedtextbuffer, buffercontent);
bufferrec = thisrec;
}
if (m_nParas > 0)
{
m_nextPara = m_ParaOffsets[0];
//qDebug("First offset = %u", m_nextPara);
m_nextParaIndex = 0;
}
else
{
m_nextPara = -1;
}
bufferpos = 0;
//qDebug("BC:%u, HS:%u", buffercontent, thishdr_size);
return true;
}
/*
void CPlucker_base::UnZip(UInt8* compressedbuffer, size_t reclen, UInt8* tgtbuffer, size_t bsize)
{
z_stream zstream;
memset(&zstream,sizeof(zstream),0);
zstream.next_in = compressedbuffer;
zstream.next_out = tgtbuffer;
zstream.avail_out = bsize;
zstream.avail_in = reclen;
int keylen = 0;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.opaque = Z_NULL;
// printf("Initialising\n");
inflateInit(&zstream);
int err = 0;
do {
if ( zstream.avail_in == 0 && 0 < keylen ) {
zstream.next_in = compressedbuffer + keylen;
zstream.avail_in = reclen - keylen;
keylen = 0;
}
zstream.next_out = tgtbuffer;
zstream.avail_out = bsize;
err = inflate( &zstream, Z_SYNC_FLUSH );
// //qDebug("err:%d - %u", err, zstream.avail_in);
} while ( err == Z_OK );
inflateEnd(&zstream);
}
*/
size_t CPlucker_base::UnDoc(UInt8* compressedbuffer, size_t reclen, UInt8* tgtbuffer, size_t bsize)
{
// UInt16 headerSize;
UInt16 docSize;
UInt16 i;
UInt16 j;
UInt16 k;
UInt8 *inBuf = compressedbuffer;
UInt8 *outBuf = tgtbuffer;
// headerSize = sizeof( Header ) + record->paragraphs * sizeof( Paragraph );
docSize = reclen;
j = 0;
k = 0;
while ( j < docSize ) {
i = 0;
while ( i < bsize && j < docSize ) {
UInt16 c;
c = (UInt16) inBuf[ j++ ];
if ( 0 < c && c < 9 ) {
while ( 0 < c-- )
outBuf[ i++ ] = inBuf[ j++ ];
}
else if ( c < 0x80 )
outBuf[ i++ ] = c;
else if ( 0xc0 <= c ) {
outBuf[ i++ ] = ' ';
outBuf[ i++ ] = c ^ 0x80;
}
else {
Int16 m;
Int16 n;
c <<= 8;
c += inBuf[ j++ ];
m = ( c & 0x3fff ) >> COUNT_BITS;
n = c & ( ( 1 << COUNT_BITS ) - 1 );
n += 2;
do {
outBuf[ i ] = outBuf[ i - m ];
i++;
} while ( 0 < n-- );
}
}
k += bsize;
}
return i;
}
void CPlucker_base::home()
{
currentpos = 0;
expand(1);
}
CList<Bkmk>* CPlucker_base::getbkmklist()
{
/*
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size;
UInt8 thishdr_type, thishdr_reserved;
for (int i = 1; i < ntohs(head.recordList.numRecords); i++)
{
gotorecordnumber(i);
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
if (thishdr_type == 8)
{
UInt16 n;
fread(&n, 1, sizeof(n), fin);
n = ntohs(n);
//qDebug("Found %u bookmarks", n);
}
//qDebug("Found:%d, %u", i , thishdr_type);
}
*/
return NULL;
}
#include <qnamespace.h>
QImage* CPlucker_base::expandimg(UInt16 tgt, bool border)
{
QImage* qimage = getimg(tgt);
QImage* ret;
if (qimage == NULL) return NULL;
if (border)
{
QPixmap* image = new QPixmap(0,0);
image->convertFromImage(*qimage);
delete qimage;
QPixmap* pret = new QPixmap(image->width()+4, image->height()+4);
pret->fill(Qt::red);
bitBlt(pret, 2, 2, image, 0, 0, -1, -1);//, Qt::RasterOp::CopyROP);
delete image;
ret = new QImage(pret->convertToImage());
}
else
{
ret = qimage;
}
return ret;
}
#ifdef _BUFFERPICS
#include <qmap.h>
#endif
QImage* CPlucker_base::getPicture(unsigned long tgt)
{
#ifdef _BUFFERPICS
static QMap<unsigned long, QPixmap> pix;
QMap<unsigned long, QPixmap>::Iterator t = pix.find(tgt);
if (t == pix.end())
{
pix[tgt] = *expandimg(tgt);
return &pix[tgt];
}
else
return &(t.data());
#else
return expandimg(tgt >> 16);
#endif
}
#ifdef LOCALPICTURES
#include <unistd.h>
#include <qpe/global.h>
void CPlucker_base::showimg(UInt16 tgt)
{
//qDebug("Crassssssh!");
QPixmap* qimage = expandimg(tgt);
m_picture->setFixedSize(qimage->size());
m_picture->setBackgroundPixmap(*qimage);
delete qimage;
m_viewer->show();
/*
char tmp[] = "uqtreader.XXXXXX";
QImage* qimage = getimg(tgt);
QPixmap* image = new QPixmap(0,0);
// //qDebug("New image");
image->convertFromImage(*qimage);
delete qimage;
char tmpfile[sizeof(tmp)+1];
strcpy(tmpfile,tmp);
int f = mkstemp(tmpfile);
close(f);
//qDebug("TMPFILE:%s", tmpfile);
if (image->save(tmpfile,"PNG"))
{
QCopEnvelope e("QPE/Application/showimg", "setDocument(QString)");
e << QString(tmpfile);
}
Global::statusMessage("Opening image");
sleep(5);
delete image;
unlink(tmpfile);
*/
}
#endif
unsigned short CPlucker_base::finduid(unsigned short urlid)
{
// //qDebug("Finding %u", urlid);
unsigned short jmin = 1, jmax = ntohs(head.recordList.numRecords);
unsigned short jmid = (jmin+jmax) >> 1;
while (jmax - jmin > 1)
{
gotorecordnumber(jmid);
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size;
UInt8 thishdr_type, thishdr_reserved;
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
unsigned short luid = thishdr_uid;
// //qDebug("%u %u %u : %u", jmin, jmid, jmax, urlid);
if (luid == urlid)
{
return jmid;
}
if (luid < urlid)
{
jmin = jmid;
}
else
{
jmax = jmid;
}
jmid = (jmin+jmax) >> 1;
}
gotorecordnumber(jmin);
UInt16 thishdr_uid, thishdr_nParagraphs;
UInt32 thishdr_size;
UInt8 thishdr_type, thishdr_reserved;
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
unsigned short luid = thishdr_uid;
//qDebug("jmin at end:%u,%u", jmin, luid);
if (luid == urlid)
{
return jmin;
}
gotorecordnumber(jmax);
GetHeader(thishdr_uid, thishdr_nParagraphs, thishdr_size, thishdr_type, thishdr_reserved);
luid = thishdr_uid;
//qDebug("jmax at end:%u,%u", jmax, luid);
if (luid == urlid)
{
return jmax;
}
//qDebug("Couldn't find %u", urlid);
return 0; // Not found!
}
#include <qnamespace.h>
void CPlucker_base::setSaveData(unsigned char*& data, unsigned short& len, unsigned char* src, unsigned short srclen)
{
unsigned short sz = 0;
for (CList<unsigned long>::iterator it = visited.begin(); it != visited.end(); it++)
{
sz++;
}
size_t newlen = srclen+sizeof(sz)+sz*sizeof(unsigned long);
unsigned char* newdata = new unsigned char[newlen];
unsigned char* pdata = newdata;
memcpy(newdata, src, srclen);
newdata += srclen;
memcpy(newdata, &sz, sizeof(sz));
newdata += sizeof(sz);
#ifdef _WINDOWS
for (it = visited.begin(); it != visited.end(); it++)
#else
for (CList<unsigned long>::iterator it = visited.begin(); it != visited.end(); it++)
#endif