TextFile.cpp
上传用户:hmc_gdtv
上传日期:2013-08-04
资源大小:798k
文件大小:7k
源码类别:

Windows Mobile

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 2001,2002,2003 Mike Matsnev.  All Rights Reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice immediately at the beginning of the file, without modification,
  10.  *    this list of conditions, and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. Absolutely no warranty of function or purpose is made by the author
  15.  *    Mike Matsnev.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  * 
  28.  * $Id: TextFile.cpp,v 1.45.2.5 2004/07/07 12:04:47 mike Exp $
  29.  * 
  30.  */
  31. #include <afxwin.h>
  32. #include <afxtempl.h>
  33. #include "resource.h"
  34. #include "TextFile.h"
  35. #include "ZipFile.h"
  36. #include "PDBFile.h"
  37. #include "TCRFile.h"
  38. #include "TextViewNG.h"
  39. #include "ProgressDlg.h"
  40. #include "Unicode.h"
  41. #include "config.h"
  42. #ifdef _DEBUG
  43. #undef THIS_FILE
  44. static char THIS_FILE[]=__FILE__;
  45. #define new DEBUG_NEW
  46. #endif
  47. TextFile::TextFile(RFile *fp,const CString& name) :
  48.   m_name(name), m_bookmarks(name), m_dictp(NULL)
  49. {
  50.   m_format=m_bookmarks.Format();
  51.   m_enc=m_bookmarks.Encoding();
  52.   if (m_format>=TextParser::GetNumFormats())
  53.     m_format=-1;
  54.   if (m_enc>=Unicode::GetNumCodePages())
  55.     m_enc=-1;
  56.   // create a buffered file for it
  57.   m_fp=new CBufFile(kilo::auto_ptr<RFile>(fp));
  58.   // and initialize parser
  59.   m_bookmarks.LoadFromRegistry();
  60.   SetFormatEncodingImp(m_format,m_enc,&m_bookmarks);
  61.   m_bookmarks.NormalizeLevels();
  62. }
  63. void TextFile::SaveBookmarks(FilePos cur) {
  64.   m_bookmarks.SetStartPos(cur);
  65.   if (m_bookmarks.SaveInfo())
  66.       m_bookmarks.SaveToRegistry();
  67. }
  68. void       TextFile::SetFormatEncodingImp(int format,int enc,Bookmarks *bmk) {
  69.   TextParser  *np=NULL;
  70.   CProgressDlg   dlg(Name(),AfxGetMainWnd());
  71.   dlg.SetMax(m_fp->size());
  72.   if (format<0) {
  73.     m_fp->seek(0);
  74.     int     nf=TextParser::DetectFormat(m_fp.get());
  75.     np=TextParser::Create(&dlg,m_fp.get(),nf,enc,bmk);
  76.   } else {
  77.     if (m_tp.get() && format==m_tp->GetFormat()) {
  78.       m_format=format;
  79.       return;
  80.     }
  81.     np=TextParser::Create(&dlg,m_fp.get(),format,enc,bmk);
  82.   }
  83.   if (np==NULL)
  84.     return;
  85.   m_tp.reset(np);
  86.   m_format=format;
  87.   m_enc=enc;
  88.   m_bookmarks.SetFormat(m_format);
  89.   m_bookmarks.SetEncoding(m_enc);
  90. }
  91. void       TextFile::Reparse() {
  92.   TextParser  *np=NULL;
  93.   CProgressDlg   dlg(Name(),AfxGetMainWnd());
  94.   dlg.SetMax(m_fp->size());
  95.   int fmt=m_format<0 ? m_tp->GetFormat() : m_format;
  96.   np=TextParser::Create(&dlg,m_fp.get(),fmt,m_enc,NULL);
  97.   if (np==NULL)
  98.     return;
  99.   m_tp.reset(np);
  100. }
  101. const TCHAR   *TextFile::GetEncodingName(int enc) {
  102.   return enc<0 ? _T("Auto") : Unicode::GetCodePageName(enc);
  103. }
  104. const TCHAR   *TextFile::GetFormatName(int format) {
  105.   return format<0 ? _T("Auto") : TextParser::GetFormatName(format);
  106. }
  107. class DummyRFile: public RFile {
  108. public:
  109.   DummyRFile() : RFile(CString()) { }
  110.   // generic file operations
  111.   virtual DWORD   size() { return 0; }
  112.   virtual DWORD   read(void *buf) { return 0; }
  113.   virtual void   seek(DWORD pos) { }
  114. };
  115. TextFile      *TextFile::Open(const CString& filename) {
  116.   kilo::auto_ptr<RFile> fp;
  117.   CString   cur(filename);
  118.   bool   zip=false;
  119.   RFile   *rf=NULL;
  120. #if !defined(_WIN32_WCE)
  121.   CString   FILENAME;
  122.   // normalize filename
  123.   TCHAR   buffer[MAX_PATH],*filepart;
  124.   DWORD   nc=GetFullPathName(cur,sizeof(buffer)/sizeof(TCHAR),buffer,&filepart);
  125.   if (nc>0 && nc<sizeof(buffer)/sizeof(TCHAR))
  126.     FILENAME=buffer;
  127.   else
  128.     FILENAME=filename;
  129. #else
  130. #define FILENAME filename
  131.   if (filename==_T("NUL")) {
  132.     rf=new DummyRFile();
  133.     goto ok;
  134.   }
  135. #endif
  136.   for (;;) {
  137.     fp = new RFile(cur);
  138.     if (fp->Reopen()) {
  139.       if (zip) { // try to decompress fp, if this is not the first try
  140. ZipFile   *zf=new ZipFile(cur);
  141. if (!zf->ReadZip()) {
  142.   delete zf;
  143.   return NULL;
  144. }
  145. // good, now try to find the file in zip
  146. cur=filename.Mid(cur.GetLength());
  147. int   spos=cur.ReverseFind(_T('\'));
  148. if (spos>=0) {
  149.   if (spos>0 && !zf->SetDir(cur.Left(spos))) { // no such dir
  150.       delete zf;
  151.       return NULL;
  152.   }
  153.   cur=cur.Mid(spos+1);
  154. }
  155. if (!zf->Open(cur)) { // no such file in zip
  156.   delete zf;
  157.   return NULL;
  158. }
  159. rf=zf;
  160.       } else {
  161. if (PDBFile::IsPDB(fp.get()))
  162.   rf=new PDBFile(cur);
  163. else if (TCRFile::IsTCR(fp.get()))
  164.   rf=new TCRFile(cur);
  165. else
  166.   rf=fp.release();
  167.       }
  168.       goto ok;
  169.     } else { // unable to open, chop last piece
  170.       int   spos=cur.ReverseFind(_T('\'));
  171.       if (spos<=0) // we failed
  172. break;
  173.       cur.Delete(spos,cur.GetLength()-spos);
  174.     }
  175.     zip=true;
  176.   }
  177.   // when we get here we failed to open any prefix of filename
  178.   return NULL;
  179. ok:{
  180.     TextFile *tf;
  181.     TRY {
  182.       tf=new TextFile(rf,FILENAME);
  183.     } CATCH_ALL(e) {
  184.       tf=NULL;
  185.     }
  186.     END_CATCH_ALL
  187.     if (tf && !tf->Ok()) {
  188.       delete tf;
  189.       tf=NULL;
  190.     }
  191.     return tf;
  192.   }
  193. }
  194. // these tricks are needed to distinguish between a true end of paragraph
  195. // and position 0, which is difficult when length is also 0
  196. int TextFile::GetPLength(int docid,int para) {
  197.   int pl=Parser(docid)->GetPLength(docid,para);
  198.   return pl==0 ? 1 : pl;
  199. }
  200. Paragraph TextFile::GetParagraph(int docid,int para) {
  201.   Paragraph p(Parser(docid)->GetParagraph(docid,para));
  202.   if (p.len==0) {
  203.     p.len=1;
  204.     p.str=Buffer<wchar_t>(1); p.str[0]=_T(' ');
  205.     p.cflags=Buffer<Attr>(1);
  206.     p.cflags[0].wa=0;
  207.   }
  208.   // map ipa extensions to alt font
  209.   for (int j=0;j<p.len;++j)
  210.     if (p.str[j]>=0x250 && p.str[j]<0x2b0)
  211.       p.cflags[j].xfont=1;
  212.   return p;
  213. }
  214. bool  TextFile::LookupDict(const wchar_t *name,FilePos& dest) {
  215.   if (m_dictp && m_dictp->LookupReference(name,dest)) {
  216.     dest.docid=-1;
  217.     return true;
  218.   }
  219.   return false;
  220. }