/* This file is part of the KDE project * Copyright (C) 2002 Matthias Witzgall * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ /* further informations about the dvi file format could be downloaded from: http://www.rpi.edu/~sofkam/DVI/archive/standards/dvistd0.dvi */ #include "tdefile_dvi.h" #include #include #include #include #include #include #include #include #include #include // preprocessormacro K_EXPORT_COMPONENT_FACTORY loads shared library 'tdefile_dvi.so' dynamic if necessary typedef KGenericFactory DviFactory; K_EXPORT_COMPONENT_FACTORY(tdefile_dvi, DviFactory("tdefile_dvi")) KDviPlugin::KDviPlugin (TQObject * parent, const char * name, const TQStringList & preferredItems) : KFilePlugin(parent, name, preferredItems) { kdDebug(7034) << "dvi plugin" << endl; // set up our mime type KFileMimeTypeInfo * info = this->addMimeTypeInfo("application/x-dvi"); KFileMimeTypeInfo::GroupInfo * group = this->addGroupInfo(info, "General", "General"); this->addItemInfo(group, "3_Created", i18n("Created"), TQVariant::String); this->addItemInfo(group, "6_Comment", i18n("Comment"), TQVariant::String); this->addItemInfo(group, "7_Pages", i18n("Pages"), TQVariant::UInt); } bool KDviPlugin::readInfo (KFileMetaInfo & info, uint /* what (unused in this plugin) */) { if ( info.path().isEmpty() ) return false; KFileMetaInfoGroup GeneralGroup = appendGroup(info, "General"); TQFile f(info.path()); TQFileInfo f_info; TQ_UINT16 bytes_to_read; TQ_UINT8 comment_length; TQString comment; TQ_UINT16 pages; TQ_UINT8 buffer[270]; // buffer for reading data; no data is read with more than 270 bytes TQ_UINT32 ptr; int i; // running index // open file and try to get the comment f.open(IO_ReadOnly); if ( f.isOpen() == false ){ kdDebug(7034) << "cannot open file" << endl; return false; } f_info.setFile(f); // create fileinfoobject bytes_to_read = TQMIN(f_info.size(), 270); // check, if the file size is smaller than 270 bytes // (if the comment is as large as possible, we don't have to // read more than 270 bytes) if ( f.readBlock((char *)buffer, bytes_to_read) != bytes_to_read ){ // cast to (char *) is necessary kdDebug(7034) << "read error (1)" << endl; return false; } if ( (buffer[0] != 247) || (buffer[1] != 2) ){ // magic numbers are not right kdDebug(7034) << "wrong file format" << endl;; return false; } comment_length = buffer[14]; // set up length of comment comment.setLength(comment_length); // used to avoid permanent reallocation when extracting the comment from buffer for ( i = 15; i <= 14+comment_length; ++i ) // extract comment from buffer comment[i-15] = (char)buffer[i]; appendItem(GeneralGroup, "6_Comment", comment.simplifyWhiteSpace() ); // comment is ok, now get total number of pages f.at( f.size() - 13); if ( f.readBlock((char *)buffer, 13) != 13 ){ kdDebug(7034) << "read error (2)" << endl; return false; } i = 12; // reset running index i while ( buffer[i] == 223 ){ --i; } // skip all trailing bytes if ( (buffer[i] != 2) || (i > 8) || (i < 5) ){ kdDebug(7034) << "wrong file formatx" << endl; return false; } // now we know the position of the pointer to the beginning of the postamble and we can read it ptr = buffer[i-4]; ptr = (ptr << 8) | buffer[i-3]; ptr = (ptr << 8) | buffer[i-2]; ptr = (ptr << 8) | buffer[i-1]; // bytes for total number of pages have a offset of 27 to the beginning of the postamble f.at(ptr + 27); // now read total number of pages from file if ( f.readBlock((char *)buffer, 2) != 2 ){ kdDebug(7034) << "read error (3)" << endl; return false; } pages = buffer[0]; pages = (pages << 8) | buffer[1]; appendItem(GeneralGroup, "7_Pages", TQVariant(pages) ); f.close(); // now get and set up some basic informations about the file (same informations would be displayed, if there is no dvi-plugin) appendItem(GeneralGroup, "1_Type", TQVariant( i18n("TeX Device Independent file") ) ); // set up type of file appendItem(GeneralGroup, "4_Modified", TQVariant(f_info.lastModified().toString("yyyy-MM-dd hh:mm")) ); // ISO 8601 date format (without seconds) return true; } #include "tdefile_dvi.moc"