예제 #1
0
lString16 EpubGetRootFilePath(LVContainerRef m_arc)
{
    // check root media type
    lString16 rootfilePath;
    lString16 rootfileMediaType;
    // read container.xml
    {
        LVStreamRef container_stream = m_arc->OpenStream(L"META-INF/container.xml", LVOM_READ);
        if ( !container_stream.isNull() ) {
            ldomDocument * doc = LVParseXMLStream( container_stream );
            if ( doc ) {
                ldomNode * rootfile = doc->nodeFromXPath( lString16(L"container/rootfiles/rootfile") );
                if ( rootfile && rootfile->isElement() ) {
                    rootfilePath = rootfile->getAttributeValue(L"full-path");
                    rootfileMediaType = rootfile->getAttributeValue(L"media-type");
                }
                delete doc;
            }
        }
    }

    if ( rootfilePath.empty() || rootfileMediaType!=L"application/oebps-package+xml" )
        return lString16::empty_str;
    return rootfilePath;
}
예제 #2
0
jbyteArray scanBookCoverInternal
  (JNIEnv * _env, jclass _class, jstring _path)
{
	CRJNIEnv env(_env);
	lString16 path = env.fromJavaString(_path);
	CRLog::debug("scanBookCoverInternal(%s) called", LCSTR(path));
	lString16 arcname, item;
    LVStreamRef res;
    jbyteArray array = NULL;
    LVContainerRef arc;
	if (!LVSplitArcName(path, arcname, item)) {
		// not in archive
		LVStreamRef stream = LVOpenFileStream(path.c_str(), LVOM_READ);
		if (!stream.isNull()) {
			arc = LVOpenArchieve(stream);
			if (!arc.isNull()) {
				// ZIP-based format
				if (DetectEpubFormat(stream)) {
					// EPUB
					// extract coverpage from epub
					res = GetEpubCoverpage(arc);
				}
			} else {
				res = GetFB2Coverpage(stream);
				if (res.isNull()) {
					doc_format_t fmt;
					if (DetectPDBFormat(stream, fmt)) {
						res = GetPDBCoverpage(stream);
					}
				}
			}
		}
	} else {
    	CRLog::debug("scanBookCoverInternal() : is archive, item=%s, arc=%s", LCSTR(item), LCSTR(arcname));
		LVStreamRef arcstream = LVOpenFileStream(arcname.c_str(), LVOM_READ);
		if (!arcstream.isNull()) {
			arc = LVOpenArchieve(arcstream);
			if (!arc.isNull()) {
				LVStreamRef stream = arc->OpenStream(item.c_str(), LVOM_READ);
				if (!stream.isNull()) {
			    	CRLog::debug("scanBookCoverInternal() : archive stream opened ok, parsing");
					res = GetFB2Coverpage(stream);
					if (res.isNull()) {
						doc_format_t fmt;
						if (DetectPDBFormat(stream, fmt)) {
							res = GetPDBCoverpage(stream);
						}
					}
				}
			}
		}
	}
	if (!res.isNull())
		array = env.streamToJByteArray(res);
    if (array != NULL)
    	CRLog::debug("scanBookCoverInternal() : returned cover page array");
    else
    	CRLog::debug("scanBookCoverInternal() : cover page data not found");
    return array;
}
예제 #3
0
    virtual LVStreamRef OpenStream( const lChar16 * fname, lvopen_mode_t mode ) {

        LVStreamRef res = _container->OpenStream(fname, mode);
        if (res.isNull())
            return res;
        if (isEncryptedItem(fname))
            return LVStreamRef(new FontDemanglingStream(res, _fontManglingKey));
        return res;
    }
예제 #4
0
 bool open() {
     LVStreamRef stream = _container->OpenStream(L"META-INF/encryption.xml", LVOM_READ);
     if (stream.isNull())
         return false;
     EncCallback enccallback(this);
     LVXMLParser parser(stream, &enccallback, false, false);
     if (!parser.Parse())
         return false;
     if (_list.length())
         return true;
     return false;
 }
예제 #5
0
static void dumpZip( LVContainerRef arc ) {
    lString16 arcName = LVExtractFilenameWithoutExtension( arc->GetName() );
    if ( arcName.empty() )
        arcName = L"unziparc";
    lString16 outDir = lString16("/tmp/") + arcName;
    LVCreateDirectory(outDir);
    for ( int i=0; i<arc->GetObjectCount(); i++ ) {
        const LVContainerItemInfo * info = arc->GetObjectInfo(i);
        if ( !info->IsContainer() ) {
            lString16 outFileName = outDir + L"/" + info->GetName();
            LVCreateDirectory(LVExtractPath(outFileName));
            LVStreamRef in = arc->OpenStream(info->GetName(), LVOM_READ);
            LVStreamRef out = LVOpenFileStream(outFileName.c_str(), LVOM_WRITE);
            if ( !in.isNull() && !out.isNull() ) {
                CRLog::trace("Writing %s", LCSTR(outFileName));
                LVPumpStream(out.get(), in.get());
            }
        }
    }
}
예제 #6
0
static bool GetBookProperties(const char *name,  BookProperties * pBookProps)
{
    CRLog::trace("GetBookProperties( %s )", name);

    // check archieve
    lString16 arcPathName;
    lString16 arcItemPathName;
    bool isArchiveFile = LVSplitArcName( lString16(name), arcPathName, arcItemPathName );

    // open stream
    LVStreamRef stream = LVOpenFileStream( (isArchiveFile ? arcPathName : Utf8ToUnicode(lString8(name))).c_str() , LVOM_READ);
    if (!stream) {
        CRLog::error("cannot open file %s", name);
        return false;
    }


    if ( DetectEpubFormat( stream ) ) {
        CRLog::trace("GetBookProperties() : epub format detected");
    	return GetEPUBBookProperties( name, stream, pBookProps );
    }

    time_t t = (time_t)time(0);

    if ( isArchiveFile ) {
        int arcsize = (int)stream->GetSize();
        LVContainerRef container = LVOpenArchieve(stream);
        if ( container.isNull() ) {
            CRLog::error( "Cannot read archive contents from %s", LCSTR(arcPathName) );
            return false;
        }
        stream = container->OpenStream(arcItemPathName.c_str(), LVOM_READ);
        if ( stream.isNull() ) {
            CRLog::error( "Cannot open archive file item stream %s", LCSTR(lString16(name)) );
            return false;
        }
    }
    struct stat fs;
    if ( !stat( name, &fs ) ) {
        t = fs.st_mtime;
    }

    // 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 false;
    }
    CRLog::trace( "parsing..." );
    if ( !parser.Parse() ) {
        return false;
    }
    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("|"), false );
    lString16 title = extractDocTitle( &doc );
    lString16 language = extractDocLanguage( &doc ).lowercase();
    lString16 series = extractDocSeries( &doc, &pBookProps->seriesNumber );
#if SERIES_IN_AUTHORS==1
    if ( !series.empty() )
        authors << "    " << series;
#endif
    pBookProps->title = title;
    pBookProps->author = authors;
    pBookProps->series = series;
    pBookProps->filesize = (long)stream->GetSize();
    pBookProps->filename = lString16(name);
    pBookProps->filedate = getDateTimeString( t );
    pBookProps->language = language;
    return true;
}
예제 #7
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;
}