Scribus Developer Documentation - API
logo-pen

Scribus Developer Documentation - API

pdbim.cpp

Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 #include <QFile>
00008 #include <QFileInfo>
00009 #include <QString>
00010 #include <QStringList>
00011 #include <QTextCodec>
00012 #include <QCursor>
00013 
00014 #include "pdbim.h"
00015 #include "gtwriter.h"
00016 #include "gtparagraphstyle.h"
00017 #include "scribusstructs.h"
00018 #include "scribuscore.h"
00019 
00020 
00024 static void _zero_fill(  Byte *p,  int len )
00025 {
00026     while ( len-- > 0 )
00027         *p++ = '\0';
00028 }
00029 
00030 QString FileFormatName()
00031 {
00032     return QObject::tr("Palm PDB Documents", "PDB Importer");
00033 }
00034 
00035 QStringList FileExtensions()
00036 {
00037     return QStringList("pdb");
00038 }
00039 
00040 void GetText(QString filename, QString encoding, bool /* textOnly */, gtWriter *writer)
00041 {
00042     if (filename.isNull())
00043         return;
00044     qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
00045     ScCore->primaryMainWindow()->mainWindowProgressBar->reset();
00046     PdbIm *im = new PdbIm(filename, encoding, writer);
00047     im->write();
00048     delete im;
00049     ScCore->primaryMainWindow()->mainWindowProgressBar->reset();
00050     qApp->restoreOverrideCursor();
00051 }
00052 
00053 
00054 PdbIm::PdbIm(const QString& fname, const QString& enc, gtWriter *w)
00055 {
00056     m_buf = new buffer;
00057     _zero_fill(m_buf->buf, BUFFER_SIZE);
00058     m_buf->len = BUFFER_SIZE;
00059     m_buf->position = 0;
00060     writer = w;
00061     encoding = enc;
00062     selectSwap();
00063     loadFile(fname);
00064 }
00065 
00066 void PdbIm::write()
00067 {
00068     QTextCodec *codec;
00069     if (encoding.isEmpty())
00070         codec = QTextCodec::codecForLocale();
00071     else
00072         codec = QTextCodec::codecForName(encoding.toLocal8Bit());
00073     data = codec->toUnicode(data.toLocal8Bit());
00074     gtParagraphStyle *pstyle = new gtParagraphStyle(*(writer->getDefaultStyle()));
00075     pstyle->setName(writer->getFrameName() + "-" + QObject::tr("PDB_data", "PDB Importer"));
00076     writer->append(data, pstyle);
00077     delete pstyle;
00078 }
00079 
00080 void PdbIm::loadFile(QString fname)
00081 {
00082     FILE *m_pdfp = fopen(fname.toLocal8Bit(), "rb");
00083     pdb_header m_header;
00084     DWord file_size, offset;
00085     doc_record0 m_rec0;
00086 
00087     if (!m_pdfp)
00088     {
00089         QMessageBox::warning(ScCore->primaryMainWindow(), QObject::tr("PDB Import", "PDB Importer"),
00090                              "<qt>" + QObject::tr("Could not open file %1", "PDB Importer").arg(fname) + "</qt>",
00091                              QMessageBox::Ok, QMessageBox::NoButton);
00092         return;
00093     }
00094     fread( &m_header, PDB_HEADER_SIZE, 1, m_pdfp );
00095     if (strncmp(m_header.type, DOC_TYPE, sizeof(m_header.type) ) ||
00096         strncmp( m_header.creator, DOC_CREATOR, sizeof(m_header.creator)))
00097     {
00098         QMessageBox::warning(ScCore->primaryMainWindow(), QObject::tr("PDB Import", "PDB Importer"),
00099                              "<qt>" + QObject::tr("This file is not recognized as a PDB document. Please, report this as a bug if you are sure it is one.", "PDB Importer") + "</qt>",
00100                              QMessageBox::Ok, QMessageBox::NoButton);
00101         return;
00102     }
00103 
00104     // progressbar
00105     int num_records = swap_Word( m_header.numRecords ) - 1;
00106     ScCore->primaryMainWindow()->mainWindowProgressBar->setMaximum(num_records);
00107     fseek(m_pdfp, PDB_HEADER_SIZE, SEEK_SET);
00108     GET_DWord(m_pdfp, offset);
00109     fseek(m_pdfp, offset, SEEK_SET);
00110     fread(&m_rec0, sizeof(m_rec0), 1, m_pdfp);
00111 
00112     if (swap_Word( m_rec0.version ) == 2 )
00113         bCompressed = true;
00114 
00115     fseek( m_pdfp, 0, SEEK_END );
00116     file_size = ftell( m_pdfp );
00117     for (int rec_num = 1; rec_num <= num_records; ++rec_num )
00118     {
00119         DWord next_offset;
00120 
00121         ScCore->primaryMainWindow()->mainWindowProgressBar->setValue(rec_num);
00122         fseek( m_pdfp, PDB_HEADER_SIZE + PDB_RECORD_HEADER_SIZE * rec_num, SEEK_SET);
00123         GET_DWord( m_pdfp, offset );
00124         if( rec_num < num_records )
00125         {
00126             fseek( m_pdfp, PDB_HEADER_SIZE + PDB_RECORD_HEADER_SIZE * (rec_num + 1), SEEK_SET);
00127             GET_DWord( m_pdfp, next_offset );
00128         }
00129         else
00130             next_offset = file_size;
00131         fseek( m_pdfp, offset, SEEK_SET );
00132         // be overly cautious here
00133         _zero_fill (m_buf->buf, BUFFER_SIZE);
00134         m_buf->position = fread( m_buf->buf, 1, next_offset - offset, m_pdfp );
00135 
00136         if ( bCompressed )
00137             uncompress( m_buf );
00138 
00139         m_buf->position = 0;
00140         while ( (m_buf->position) < (m_buf->len) )
00141         {
00142             if (m_buf->buf[m_buf->position] == '\0')
00143             {
00144                 ++m_buf->position;
00145                 continue;
00146             }
00147             data += m_buf->buf[m_buf->position];
00148             ++m_buf->position;
00149         } 
00150     }
00151 }
00152 
00153 void PdbIm::selectSwap()
00154 {
00155     union { char c[2];  Word n; }  w;
00156     strncpy(  w.c, "\1\2",     2 );
00157 
00158     if ( w.n == 0x0201 )
00159         m_littlendian = true;
00160     else
00161         m_littlendian = false;
00162 
00163 }  
00164 
00165 Word PdbIm::swap_Word( Word r )
00166 {
00167     if (m_littlendian)
00168         return (r >> 8) | (r << 8);
00169     else
00170         return r;
00171 }
00172 
00173 DWord PdbIm::swap_DWord( DWord r )
00174 {
00175     if (m_littlendian)
00176         return ( (r >> 24) & 0x00FF ) | (r << 24) | ( (r >> 8) & 0xFF00 ) | ( (r << 8) & 0xFF0000 );
00177     else
00178         return r;
00179 }
00180 
00181 void PdbIm::uncompress( buffer *m_buf )
00182 {
00183     buffer *m_new_buf = new buffer;
00184     UT_uint16 i, j;
00185     Byte c;
00186 
00187     _zero_fill (m_new_buf->buf, BUFFER_SIZE);
00188 
00189     for (i = j = 0; i < m_buf->position && j < BUFFER_SIZE; )
00190     {
00191         c = m_buf->buf[ i++ ];
00192 
00193         if ( c >= 1 && c <= 8 )
00194             while ( c-- && j < BUFFER_SIZE-1)
00195                 m_new_buf->buf[ j++ ] = m_buf->buf[ i++ ];
00196 
00197         else if ( c <= 0x7F )
00198             m_new_buf->buf[ j++ ] = c;
00199 
00200         else if ( c >= 0xC0 && j < BUFFER_SIZE-2)
00201         {
00202             m_new_buf->buf[ j++ ] = ' ';
00203             m_new_buf->buf[ j++ ] = c ^ 0x80;
00204         }
00205         else
00206         {
00207             int di, n;
00208             unsigned int temp_c = c;
00209             // c--> temp_c //tomy 2001.11.13 
00210             temp_c = (temp_c << 8) ;
00211             temp_c = temp_c + m_buf->buf[ i++ ];
00212             di = (temp_c & 0x3FFF) >> COUNT_BITS;
00213             for (n = (temp_c & ((1 << COUNT_BITS) - 1)) + 3; n-- && j < BUFFER_SIZE; ++j )
00214                 m_new_buf->buf[ j ] = m_new_buf->buf[ j - di ];
00215             temp_c = 0;
00216         }
00217     }
00218     //UT_ASSERT(j <= BUFFER_SIZE);
00219 
00220     memcpy( static_cast<void *>(m_buf->buf), static_cast<void *>(m_new_buf->buf), static_cast<size_t>(j) );
00221 
00222     m_buf->position = j;
00223     delete( m_new_buf );
00224 }
Created with personalized Doxygen. This is documentation for GPL software Scribus - Open Source Desktop Publishing.