Logo Search packages:      
Sourcecode: djvulibre version File versions

GP< DjVuFile > DjVuDocument::get_djvu_file ( int  page_num,
bool  dont_create = false 
) const

Returns {DjVuFile} corresponding to the specified page. Normally it translates the page number to the URL using {page_to_url}() and then creates {DjVuFile} initializing it with data from the URL.

The behavior becomes different, though in the case when the document structure is unknown at the moment this function is called. In this situations it invents a temporary URL, creates a {DjVuFile}, initializes it with this URL and returns immediately. The caller may start decoding the file right away (if necessary). The decoding will block but will automatically continue as soon as enough information is collected about the document. This trick should be quite transparent to the user and helps to prevent the main thread from blocking. The decoding will unblock and this function will stop using this "trick" as soon as DjVuDocument# passes some given stages of initialization and {page_to_url}(), {id_to_url}() functions start working properly.

If dont_create# is FALSE# the function will return the file only if it already exists.

{ Note:} To wait for the initialization to complete use {wait_for_complete_init}(). For single threaded applications the initialization completes before the {init}() function returns.

Definition at line 870 of file DjVuDocument.cpp.

References DjVuPortcaster::add_route(), DjVuPortcaster::alias_to_port(), DjVuFile::create(), DjVuPort::get_portcaster(), GURL::get_string(), GURL::is_empty(), is_init_complete(), and page_to_url().

Referenced by DjVuDocEditor::create_shared_anno_file(), get_djvm_doc(), get_djvu_file(), get_page(), DjVuDocEditor::get_shared_anno_file(), get_thumbnail(), id_to_file(), DjVuDocEditor::remove_file(), DjVuDocEditor::save_pages_as(), and DjVuDocEditor::simplify_anno().

{
   check();
   DEBUG_MSG("DjVuDocument::get_djvu_file(): request for page " << page_num << "\n");
   DEBUG_MAKE_INDENT(3);

   DjVuPortcaster * pcaster=DjVuPort::get_portcaster();
   
   GURL url;
   {
       // I'm locking the flags because depending on what page_to_url()
       // returns me, I'll be creating DjVuFile in different ways.
       // And I don't want the situation to change between the moment I call
       // id_to_url() and I actually create DjVuFile
      GMonitorLock lock(&(const_cast<DjVuDocument *>(this)->flags));
      url=page_to_url(page_num);
      if (url.is_empty())
      {
          // If init is complete and url is empty, we know for sure, that
          // smth is wrong with the page_num. So we can return ZERO.
          // Otherwise we create a temporary file and wait for init to finish
       if (is_init_complete()) return 0;
       
       DEBUG_MSG("Structure is not known => check <doc_url>#<page_num> alias...\n");
       GP<DjVuPort> port;
       if (cache)
          port=pcaster->alias_to_port(init_url.get_string()+"#"+GUTF8String(page_num));
       if (!port || !port->inherits("DjVuFile"))
       {
          DEBUG_MSG("failed => invent dummy URL and proceed\n");
       
             // Invent some dummy temporary URL. I don't care what it will
             // be. I'll remember the page_num and will generate the correct URL
             // after I learn what the document is
            GUTF8String name("page");
            name+=GUTF8String(page_num);
            name+=".djvu";
            url=invent_url(name);

            GCriticalSectionLock(&(const_cast<DjVuDocument *>(this)->ufiles_lock));
          for(GPosition pos=ufiles_list;pos;++pos)
          {
             GP<UnnamedFile> f=ufiles_list[pos];
             if (f->url==url) return f->file;
          }
          GP<UnnamedFile> ufile=new UnnamedFile(UnnamedFile::PAGE_NUM, 0,
                                      page_num, url, 0);

             // We're adding the record to the list before creating the DjVuFile
             // because DjVuFile::init() will call request_data(), and the
             // latter should be able to find the record.
             //
             // We also want to keep ufiles_lock to make sure that when
             // request_data() is called, the record is still there
          const_cast<DjVuDocument *>(this)->ufiles_list.append(ufile);
      
          GP<DjVuFile> file=
              DjVuFile::create(url,const_cast<DjVuDocument *>(this),recover_errors,verbose_eof);
          ufile->file=file;
          return file;
       } else url=((DjVuFile *) (DjVuPort *) port)->get_url();
      }
   }
   
   GP<DjVuFile> file=url_to_file(url, dont_create);
   if (file) 
     pcaster->add_route(file, const_cast<DjVuDocument *>(this));
   return file;
}


Generated by  Doxygen 1.6.0   Back to index