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; }
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; }