Example #1
0
bool DetectEpubFormat( LVStreamRef stream )
{


    LVContainerRef m_arc = LVOpenArchieve( stream );
    if ( m_arc.isNull() )
        return false; // not a ZIP archive

    //dumpZip( m_arc );

    // read "mimetype" file contents from root of archive
    lString16 mimeType;
    {
        LVStreamRef mtStream = m_arc->OpenStream(L"mimetype", LVOM_READ );
        if ( !mtStream.isNull() ) {
            int size = mtStream->GetSize();
            if ( size>4 && size<100 ) {
                LVArray<char> buf( size+1, '\0' );
                if ( mtStream->Read( buf.get(), size, NULL )==LVERR_OK ) {
                    for ( int i=0; i<size; i++ )
                        if ( buf[i]<32 || ((unsigned char)buf[i])>127 )
                            buf[i] = 0;
                    buf[size] = 0;
                    if ( buf[0] )
                        mimeType = Utf8ToUnicode( lString8( buf.get() ) );
                }
            }
        }
    }

    if ( mimeType != L"application/epub+zip" )
        return false;
    return true;
}
Example #2
0
 bool read( LVStreamRef stream ) {
     // TODO: byte order support
     lvsize_t bytesRead = 0;
     if ( stream->Read(this, sizeof(PDBHdr), &bytesRead )!=LVERR_OK )
         return false;
     if ( bytesRead!=sizeof(PDBHdr) )
         return false;
     lvByteOrderConv cnv;
     if ( cnv.lsf() )
     {
         cnv.rev(&attributes);
         cnv.rev(&version);
         cnv.rev(&creationDate);
         cnv.rev(&modificationDate);
         cnv.rev(&lastBackupDate);
         cnv.rev(&modificationNumber);
         cnv.rev(&appInfoID);
         cnv.rev(&sortInfoID);
         cnv.rev(&uniqueIDSeed);
         cnv.rev(&nextRecordList);
         cnv.rev(&recordCount);
         cnv.rev(&firstEntry);
     }
     return true;
 }
Example #3
0
lString8 readFileToString( const char * fname )
{
    lString8 buf;
    LVStreamRef stream = LVOpenFileStream(fname, LVOM_READ);
    if (!stream)
        return buf;
    int sz = stream->GetSize();
    if (sz>0)
    {
        buf.insert( 0, sz, ' ' );
        stream->Read( buf.modify(), sz, NULL );
    }
    return buf;
}
Example #4
0
 //lUInt8  uniqueID[3];
 bool read( LVStreamRef stream ) {
     // TODO: byte order support
     lvsize_t bytesRead = 0;
     if ( stream->Read(this, sizeof(PDBRecordEntry), &bytesRead )!=LVERR_OK )
         return false;
     if ( bytesRead!=sizeof(PDBRecordEntry) )
         return false;
     lvByteOrderConv cnv;
     if ( cnv.lsf() )
     {
         cnv.rev(&localChunkId);
     }
     return true;
 }
Example #5
0
jbyteArray CRJNIEnv::streamToJByteArray( LVStreamRef stream )
{
	if ( stream.isNull() )
		return NULL;
	unsigned sz = stream->GetSize();
	if ( sz<10 || sz>2000000 )
		return NULL;
    jbyteArray array = env->NewByteArray(sz); 
    lUInt8 * array_data = (lUInt8 *)env->GetByteArrayElements(array, 0);
    lvsize_t bytesRead = 0;
    stream->Read(array_data, sz, &bytesRead);
   	env->ReleaseByteArrayElements(array, (jbyte*)array_data, 0);
    if (bytesRead != sz)
    	return NULL;
    return array; 
}
Example #6
0
 bool read( LVStreamRef stream ) {
     // TODO: byte order support
     lvsize_t bytesRead = 0;
     if ( stream->Read(this, sizeof(MobiPreamble), &bytesRead )!=LVERR_OK )
         return false;
     if ( bytesRead!=sizeof(MobiPreamble) )
         return false;
     lvByteOrderConv cnv;
     if ( cnv.lsf() )
     {
         cnv.rev(&compression); // 2  Compression   1 == no compression, 2 = PalmDOC compression (see below)
         cnv.rev(&textLength);  // 4  text length  Uncompressed length of the entire text of the book
         cnv.rev(&recordCount); // 2  record count  Number of PDB records used for the text of the book.
         cnv.rev(&recordSize);  // 2  record size  Maximum size of each record containing text, always 4096
         cnv.rev(&mobiEncryption);// 2  Encryption Type	0 == no encryption, 1 = Old Mobipocket Encryption, 2 = Mobipocket Encryption
         cnv.rev(&hederLength); // 20	4	header length	the length of the MOBI header, including the previous 4 bytes
         cnv.rev(&mobiType);    //    24	4	Mobi type	The kind of Mobipocket file this is
         cnv.rev(&encoding); //    28	4	text Encoding	1252 = CP1252 (WinLatin1); 65001 = UTF-8
         cnv.rev(&uid); //    32	4	Unique-ID	Some kind of unique ID number (random?)
         cnv.rev(&fileVersion); //    36	4	File version	Version of the Mobipocket format used in this file.
         cnv.rev(&firstNonBookIndex); //    80	4	First Non-book index?	First record number (starting with 0) that's not the book's text
         cnv.rev(&fullNameOffset); //    84	4	Full Name Offset	Offset in record 0 (not from start of file) of the full name of the book
         cnv.rev(&fullNameLength); //    88	4	Full Name Length	Length in bytes of the full name of the book
         cnv.rev(&locale); //    92	4	Locale	Book locale code. Low byte is main language 09= English, next byte is dialect, 08 = British, 04 = US. Thus US English is 1033, UK English is 2057.
         cnv.rev(&inputLanguage); //    96	4	Input Language	Input language for a dictionary
         cnv.rev(&outputLanguage); //    100	4	Output Language	Output language for a dictionary
         cnv.rev(&minVersion); //    104	4	Min version	Minimum mobipocket version support needed to read this file.
         cnv.rev(&firstImageIndex); //    108	4	First Image index?	First record number (starting with 0) that contains an image. Image records should be sequential.
         cnv.rev(&huffmanRecordOffset); //    112	4	Huffman Record Offset	The record number of the first huffman compression record.
         cnv.rev(&huffmanRecordCount); //    116	4	Huffman Record Count	The number of huffman compression records.
         cnv.rev(&mobiFlags); //    128	4	EXTH flags	bitfield. if bit 6 (0x40) is set, then there's an EXTH record
         cnv.rev(&drmOffset); //    164	4	DRM Offset	Offset to DRM key info in DRMed files. 0xFFFFFFFF if no DRM
         cnv.rev(&drmCount); //    168	4	DRM Count	Number of entries in DRM info. 0xFFFFFFFF if no DRM
         cnv.rev(&drmSize); //    172	4	DRM Size	Number of bytes in DRM info.
         cnv.rev(&drmFlags); //    176	4	DRM Flags	Some flags concerning the DRM info.
     }
     if ( compression!=1 && compression!=2 )
         return false;
     if ( mobiType!=2 && mobiType!=3 && mobiType!=517 && mobiType!=518
              && mobiType!=257 && mobiType!=258 && mobiType!=259 )
         return false; // unsupported type
     if ( mobiEncryption!=0 )
         return false; // encryption is not supported
     return true;
 }
Example #7
0
 bool read( LVStreamRef stream ) {
     // TODO: byte order support
     lvsize_t bytesRead = 0;
     if ( stream->Read(this, sizeof(PalmDocPreamble), &bytesRead )!=LVERR_OK )
         return false;
     if ( bytesRead!=sizeof(PalmDocPreamble) )
         return false;
     lvByteOrderConv cnv;
     if ( cnv.lsf() )
     {
         cnv.rev(&compression); // 2  Compression   1 == no compression, 2 = PalmDOC compression (see below)
         cnv.rev(&textLength);  // 4  text length  Uncompressed length of the entire text of the book
         cnv.rev(&recordCount); // 2  record count  Number of PDB records used for the text of the book.
         cnv.rev(&recordSize);  // 2  record size  Maximum size of each record containing text, always 4096
     }
     if ( compression!=1 && compression!=2 )
         return false;
     return true;
 }
Example #8
0
static int getCoverPageImageData(lua_State *L) {
	CreDocument *doc = (CreDocument*) luaL_checkudata(L, 1, "credocument");

	LVStreamRef stream = doc->text_view->getCoverPageImageStream();
	if (!stream.isNull()) {
		unsigned size = stream->GetSize();
		lvsize_t read_size = 0;
		void *buffer = (void *)malloc(size);
		if (buffer != NULL) {
			stream->Read(buffer, size, &read_size);
			if (read_size == size) {
				lua_pushlightuserdata(L, buffer);
				lua_pushinteger(L, size);
				return 2;
			}
		}
	}
	return 0;
}
Example #9
0
void V3DocViewWin::showHelpDialog()
{
	LVStreamRef stream = LVOpenFileStream( _helpFile.c_str(), LVOM_READ );
	lString8 help;
    if ( stream.isNull() ) {
        // show warning
        lString8 body;
        body << "<title><p>" << _("No manual currently available for this language, sorry!") << "</p></title>";
        help = CRViewDialog::makeFb2Xml( body );
    } else {
        int len = stream->GetSize();
        if ( len>100 && len <1000000 ) {
            help.append( len, ' ' );
            stream->Read( help.modify(), len, NULL );
        }
    }
	//lString8 help = UnicodeToUtf8( LVReadTextFile( _helpFile ) );
	if ( !help.empty() ) {
		CRViewDialog * dlg = new CRViewDialog( _wm, lString16(_("Help")), help, lvRect(), true, true );
		_wm->activateWindow( dlg );
	}
}
Example #10
0
 bool read( LVStreamRef stream ) {
     lvsize_t bytesRead = 0;
     if ( stream->Read(this, sizeof(EReaderHeader), &bytesRead )!=LVERR_OK )
         return false;
     if ( bytesRead!=sizeof(EReaderHeader) )
         return false;
     lvByteOrderConv cnv;
     if ( cnv.lsf() )
     {
         cnv.rev(&compression);    //    0-2	compression	Specifies compression and drm. 2 = palmdoc, 10 = zlib. 260 and 272 = DRM
         cnv.rev(&encoding);       //    6-8	encoding	Always 25152 (0x6240). All text must be encoded as Latin-1 cp1252
         cnv.rev(&smallPageCount); //    8-10	Number of small pages	The number of small font pages. If page index is not build in then 0.
         cnv.rev(&largePageCount); //    10-12	Number of large pages	The number of large font pages. If page index is not build in then 0.
         cnv.rev(&nonTextRecordStart); //12-14	Non-Text record start	The location of the first non text records. record 1 to this value minus 1 are all text records
         cnv.rev(&numberOfChapters);//    14-16	Number of chapters	The number of chapter index records contained in the file
         cnv.rev(&smallPageRecordCount); //    16-18	Number of small index	The number of small font page index records contained in the file
         cnv.rev(&largePageRecordCount); //    18-20	Number of large index	The number of large font page index records contained in the file
         cnv.rev(&imageCount);        //    20-22	Number of images	The number of images contained in the file
         cnv.rev(&linkCount);         //    22-24	Number of links	The number of links contained in the file
         cnv.rev(&metadataAvailable); //    24-26	Metadata avaliable	Is there a metadata record in the file? 0 = None, 1 = There is a metadata record
         cnv.rev(&footnoteRecordsCount); //    28-30	Number of Footnotes	The number of footnote records in the file
         cnv.rev(&sidebarRecordsCount); //    30-32	Number of Sidebars	The number of sidebar records in the file
         cnv.rev(&chapterIndexStart); //    32-34	Chapter index record start	The location of chapter index records. If there are no chapters use the value for the Last data record.
         cnv.rev(&smallPageIndexStart); //    36-38	Small page index start	The location of small font page index records. If page table is not built in use the value for the Last data record.
         cnv.rev(&largePageIndexStart); //    38-40	Large page index start	The location of large font page index records. If page table is not built in use the value for the Last data record.
         cnv.rev(&imageDataRecordStart); //    40-42	Image data record start	The location of the first image record. If there are no images use the value for the Last data record.
         cnv.rev(&linksRecordStart); //    42-44	Links record start	The location of the first link index record. If there are no links use the value for the Last data record.
         cnv.rev(&metadataRecordStart); //    44-46	Metadata record start	The location of the metadata record. If there is no metadata use the value for the Last data record.
         cnv.rev(&footnoteRecordStart); //    48-50	Footnote record start	The location of the first footnote record. If there are no footnotes use the value for the Last data record.
         cnv.rev(&sidebarRecordStart); //    50-52	Sidebar record start	The location of the first sidebar record. If there are no sidebars use the value for the Last data record.
         cnv.rev(&lastDataRecord); //    52-54	Last data record	The location of the last data record
     }
     if ( compression!=1 && compression!=2 && compression!=10 )
         return false;
     return true;
 }
Example #11
0
bool TexHyph::load( LVStreamRef stream )
{
    int w = isCorrectHyphFile(stream.get());
    int patternCount = 0;
    if (w) {
        _hash = stream->crc32();
        int        i;
        lvsize_t   dw;

        lvByteOrderConv cnv;

        int hyph_count = w;
        thyph hyph;

        lvpos_t p = 78 + (hyph_count * 8 + 2);
        stream->SetPos(p);
        if ( stream->SetPos(p)!=p )
            return false;
        lChar16 charMap[256];
        unsigned char buf[0x10000];
        memset( charMap, 0, sizeof( charMap ) );
        // make char map table
        for (i=0; i<hyph_count; i++)
        {
            if ( stream->Read( &hyph, 522, &dw )!=LVERR_OK || dw!=522 ) 
                return false;
            cnv.msf( &hyph.len ); //rword(_main_hyph[i].len);
            lvpos_t newPos;
            if ( stream->Seek( hyph.len, LVSEEK_CUR, &newPos )!=LVERR_OK )
                return false;

            cnv.msf( hyph.wl );
            cnv.msf( hyph.wu );
            charMap[ (unsigned char)hyph.al ] = hyph.wl;
            charMap[ (unsigned char)hyph.au ] = hyph.wu;
//            lChar16 ch = hyph.wl;
//            CRLog::debug("wl=%s mask=%c%c", LCSTR(lString16(&ch, 1)), hyph.mask0[0], hyph.mask0[1]);
            if (hyph.mask0[0]!='0'||hyph.mask0[1]!='0') {
                unsigned char pat[4];
                pat[0] = hyph.al;
                pat[1] = hyph.mask0[0];
                pat[2] = hyph.mask0[1];
                pat[3] = 0;
                TexPattern * pattern = new TexPattern(pat, 1, charMap);
#if DUMP_PATTERNS==1
                CRLog::debug("Pattern: '%s' - %s", LCSTR(lString16(pattern->word)), pattern->attr );
#endif
                addPattern( pattern );
                patternCount++;
            }
        }

        if ( stream->SetPos(p)!=p )
            return false;

        for (i=0; i<hyph_count; i++)
        {
            stream->Read( &hyph, 522, &dw );
            if (dw!=522) 
                return false;
            cnv.msf( &hyph.len );

            stream->Read(buf, hyph.len, &dw); 
            if (dw!=hyph.len)
                return false;

            unsigned char * p = buf;
            unsigned char * end_p = p + hyph.len;
            while ( p < end_p ) {
                lUInt8 sz = *p++;
                if ( p + sz > end_p )
                    break;
                TexPattern * pattern = new TexPattern( p, sz, charMap );
#if DUMP_PATTERNS==1
                CRLog::debug("Pattern: '%s' - %s", LCSTR(lString16(pattern->word)), pattern->attr);
#endif
                addPattern( pattern );
                patternCount++;
                p += sz + sz + 1;
            }
        }

        return patternCount>0;
    } else {
        // tex xml format as for FBReader
        lString16Collection data;
        HyphPatternReader reader( data );
        LVXMLParser parser( stream, &reader );
        if ( !parser.CheckFormat() )
            return false;
        if ( !parser.Parse() )
            return false;
        if ( !data.length() )
            return false;
        for ( int i=0; i<(int)data.length(); i++ ) {
            data[i].lowercase();
            TexPattern * pattern = new TexPattern( data[i] );
#if DUMP_PATTERNS==1
            CRLog::debug("Pattern: (%s) '%s' - %s", LCSTR(data[i]), LCSTR(lString16(pattern->word)), pattern->attr);
#endif
            addPattern( pattern );
            patternCount++;
        }
        return patternCount>0;
    }
}
Example #12
0
int GetBookProperties(char *name,  struct BookProperties* pBookProps, int localLanguage)
{
    CRLog::trace("GetBookProperties( %s )", name);
    memset(pBookProps, 0, sizeof(BookProperties) );

    // open stream
    LVStreamRef stream = LVOpenFileStream(name, LVOM_READ);
    if (!stream) {
        CRLog::error("cannot open file %s", name);
        return 0;
    }
    // check archieve
#ifdef USE_ZLIB
    LVContainerRef arc;
    //printf("start opening arc\n");
    //for ( int i=0; i<1000; i++ )
    //for ( int kk=0; kk<1000; kk++) 
    {
        arc = LVOpenArchieve( stream );
    //printf("end opening arc\n");
    if (!arc.isNull())
    {
        CRLog::trace("%s is archive with %d items", name, arc->GetObjectCount());
        // archieve
        const LVContainerItemInfo * bestitem = NULL;
        const LVContainerItemInfo * fb2item = NULL;
        const LVContainerItemInfo * fbditem = NULL;
        for (int i=0; i<arc->GetObjectCount(); i++)
        {
            const LVContainerItemInfo * item = arc->GetObjectInfo(i);
            if (item)
            {
                if ( !item->IsContainer() )
                {
                    lString16 name( item->GetName() );
                    if ( name.length() > 5 )
                    {
                        name.lowercase();
                        const lChar16 * pext = name.c_str() + name.length() - 4;
                        if ( pext[0]=='.' && pext[1]=='f' && pext[2]=='b' && pext[3]=='2') {
                            fb2item = item;
                        } else if ( pext[0]=='.' && pext[1]=='f' && pext[2]=='b' && pext[3]=='d') {
                            fbditem = item;
                        }
                    }
                }
            }
        }
        bestitem = fb2item;
        if ( fbditem )
            bestitem = fbditem;
        if ( !bestitem )
            return 0;
        CRLog::trace( "opening item %s from archive", UnicodeToUtf8(bestitem->GetName()).c_str() );
        //printf("start opening stream\n");
        //for ( int k=0; k<1000; k++ ) {
            stream = arc->OpenStream( bestitem->GetName(), LVOM_READ );
            char buf[8192];
            stream->Read(buf, 8192, NULL );
        //}
        //printf("end opening stream\n");
        if ( stream.isNull() )
            return 0;
        CRLog::trace( "stream created" );
        // opened archieve stream
    }
    }

#endif //USE_ZLIB

    // read document
#if COMPACT_DOM==1
    ldomDocument doc(stream, 0);
#else
    ldomDocument doc;
#endif
    ldomDocumentWriter writer(&doc, true);
    doc.setNodeTypes( fb2_elem_table );
    doc.setAttributeTypes( fb2_attr_table );
    doc.setNameSpaceTypes( fb2_ns_table );
    LVXMLParser parser( stream, &writer );
    CRLog::trace( "checking format..." );
    if ( !parser.CheckFormat() ) {
        return 0;
    }
    CRLog::trace( "parsing..." );
    if ( !parser.Parse() ) {
        return 0;
    }
    CRLog::trace( "parsed" );
    #if 0
        char ofname[512];
        sprintf(ofname, "%s.xml", name);
        CRLog::trace("    writing to file %s", ofname);
        LVStreamRef out = LVOpenFileStream(ofname, LVOM_WRITE);
        doc.saveToStream(out, "utf16");
    #endif
    lString16 authors = extractDocAuthors( &doc );
    lString16 title = extractDocTitle( &doc );
    lString16 series = extractDocSeriesReverse( &doc );
#if SERIES_IN_AUTHORS==1
    if ( !series.empty() )
    	authors << L"    " << series;
#endif
    SetFieldValue( pBookProps->name, title );
    if ( !authors.empty() )
        SetFieldValue( pBookProps->author, authors );
    if ( !series.empty() )
        SetFieldValue( pBookProps->series, series );
    pBookProps->filesize = (long)stream->GetSize();
    strncpy( pBookProps->filename, name, MAX_PROPERTY_LEN-1 );
    struct stat fs;
    time_t t;
    if ( stat( name, &fs ) ) {
        t = (time_t)time(0);
    } else {
        t = fs.st_mtime;
    }
    SetFieldValue( pBookProps->filedate, getDateTimeString( t, localLanguage ) );
    return 1;
}