Back to index

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