⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textfile.cpp

📁 俄罗斯人开发的大名鼎鼎的Pocket Pc 阅读器haaliread的源代码,visual c
💻 CPP
字号:
/*
 * Copyright (c) 2001,2002,2003 Mike Matsnev.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice immediately at the beginning of the file, without modification,
 *    this list of conditions, and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Absolutely no warranty of function or purpose is made by the author
 *    Mike Matsnev.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * $Id: TextFile.cpp,v 1.45.2.5 2004/07/07 12:04:47 mike Exp $
 * 
 */

#include <afxwin.h>
#include <afxtempl.h>

#include "resource.h"

#include "TextFile.h"
#include "ZipFile.h"
#include "PDBFile.h"
#include "TCRFile.h"
#include "TextViewNG.h"
#include "ProgressDlg.h"
#include "Unicode.h"
#include "config.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

TextFile::TextFile(RFile *fp,const CString& name) :
  m_name(name), m_bookmarks(name), m_dictp(NULL)
{
  m_format=m_bookmarks.Format();
  m_enc=m_bookmarks.Encoding();
  if (m_format>=TextParser::GetNumFormats())
    m_format=-1;
  if (m_enc>=Unicode::GetNumCodePages())
    m_enc=-1;
  // create a buffered file for it
  m_fp=new CBufFile(kilo::auto_ptr<RFile>(fp));
  // and initialize parser
  m_bookmarks.LoadFromRegistry();
  SetFormatEncodingImp(m_format,m_enc,&m_bookmarks);
  m_bookmarks.NormalizeLevels();
}

void TextFile::SaveBookmarks(FilePos cur) {
  m_bookmarks.SetStartPos(cur);
  if (m_bookmarks.SaveInfo())
      m_bookmarks.SaveToRegistry();
}

void	      TextFile::SetFormatEncodingImp(int format,int enc,Bookmarks *bmk) {
  TextParser  *np=NULL;
  CProgressDlg	  dlg(Name(),AfxGetMainWnd());

  dlg.SetMax(m_fp->size());
  if (format<0) {
    m_fp->seek(0);
    int	    nf=TextParser::DetectFormat(m_fp.get());
    np=TextParser::Create(&dlg,m_fp.get(),nf,enc,bmk);
  } else {
    if (m_tp.get() && format==m_tp->GetFormat()) {
      m_format=format;
      return;
    }
    np=TextParser::Create(&dlg,m_fp.get(),format,enc,bmk);
  }
  if (np==NULL)
    return;
  m_tp.reset(np);
  m_format=format;
  m_enc=enc;
  m_bookmarks.SetFormat(m_format);
  m_bookmarks.SetEncoding(m_enc);
}

void	      TextFile::Reparse() {
  TextParser  *np=NULL;
  CProgressDlg	  dlg(Name(),AfxGetMainWnd());

  dlg.SetMax(m_fp->size());
  int fmt=m_format<0 ? m_tp->GetFormat() : m_format;
  np=TextParser::Create(&dlg,m_fp.get(),fmt,m_enc,NULL);
  if (np==NULL)
    return;
  m_tp.reset(np);
}

const TCHAR   *TextFile::GetEncodingName(int enc) {
  return enc<0 ? _T("Auto") : Unicode::GetCodePageName(enc);
}

const TCHAR   *TextFile::GetFormatName(int format) {
  return format<0 ? _T("Auto") : TextParser::GetFormatName(format);
}

class DummyRFile: public RFile {
public:
  DummyRFile() : RFile(CString()) { }

  // generic file operations
  virtual DWORD	  size() { return 0; }
  virtual DWORD	  read(void *buf) { return 0; }
  virtual void	  seek(DWORD pos) { }
};

TextFile      *TextFile::Open(const CString& filename) {
  kilo::auto_ptr<RFile> fp;
  CString	  cur(filename);
  bool		  zip=false;
  RFile		  *rf=NULL;

#if !defined(_WIN32_WCE)
  CString   FILENAME;
  // normalize filename
  TCHAR   buffer[MAX_PATH],*filepart;
  DWORD	  nc=GetFullPathName(cur,sizeof(buffer)/sizeof(TCHAR),buffer,&filepart);
  if (nc>0 && nc<sizeof(buffer)/sizeof(TCHAR))
    FILENAME=buffer;
  else
    FILENAME=filename;
#else
#define FILENAME filename
  if (filename==_T("NUL")) {
    rf=new DummyRFile();
    goto ok;
  }
#endif

  for (;;) {
    fp = new RFile(cur);
    if (fp->Reopen()) {
      if (zip) { // try to decompress fp, if this is not the first try
	ZipFile	  *zf=new ZipFile(cur);
	if (!zf->ReadZip()) {
	  delete zf;
	  return NULL;
	}
	// good, now try to find the file in zip
	cur=filename.Mid(cur.GetLength());
	int   spos=cur.ReverseFind(_T('\\'));
	if (spos>=0) {
	  if (spos>0 && !zf->SetDir(cur.Left(spos))) { // no such dir
	      delete zf;
	      return NULL;
	  }
	  cur=cur.Mid(spos+1);
	}
	if (!zf->Open(cur)) { // no such file in zip
	  delete zf;
	  return NULL;
	}
	rf=zf;
      } else {
	if (PDBFile::IsPDB(fp.get()))
	  rf=new PDBFile(cur);
	else if (TCRFile::IsTCR(fp.get()))
	  rf=new TCRFile(cur);
	else
	  rf=fp.release();
      }
      goto ok;
    } else { // unable to open, chop last piece
      int   spos=cur.ReverseFind(_T('\\'));
      if (spos<=0) // we failed
	break;
      cur.Delete(spos,cur.GetLength()-spos);
    }
    zip=true;
  }
  // when we get here we failed to open any prefix of filename
  return NULL;
ok:{
    TextFile *tf;
    TRY {
      tf=new TextFile(rf,FILENAME);
    } CATCH_ALL(e) {
      tf=NULL;
    }
    END_CATCH_ALL
    if (tf && !tf->Ok()) {
      delete tf;
      tf=NULL;
    }
    return tf;
  }
}

// these tricks are needed to distinguish between a true end of paragraph
// and position 0, which is difficult when length is also 0
int TextFile::GetPLength(int docid,int para) {
  int pl=Parser(docid)->GetPLength(docid,para);
  return pl==0 ? 1 : pl;
}

Paragraph TextFile::GetParagraph(int docid,int para) {
  Paragraph p(Parser(docid)->GetParagraph(docid,para));
  if (p.len==0) {
    p.len=1;
    p.str=Buffer<wchar_t>(1); p.str[0]=_T(' ');
    p.cflags=Buffer<Attr>(1);
    p.cflags[0].wa=0;
  }

  // map ipa extensions to alt font
  for (int j=0;j<p.len;++j)
    if (p.str[j]>=0x250 && p.str[j]<0x2b0)
      p.cflags[j].xfont=1;
  return p;
}

bool  TextFile::LookupDict(const wchar_t *name,FilePos& dest) {
  if (m_dictp && m_dictp->LookupReference(name,dest)) {
    dest.docid=-1;
    return true;
  }
  return false;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -