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

Windows Mobile

开发平台:

Visual C++

  1. // Written by Andrey Chicherov, uart@os2.ru
  2. #include <afxwin.h>
  3. #include "ptr.h"
  4. #include "TCRFile.h"
  5. #include "TextViewNG.h"
  6. #include <string.h>
  7. // ----------------------------------------------------------------------------------------------------------------
  8. CString TCRFile::CompressionInfo() {
  9. CString ret; ret.Format(_T("TCR, packed (%.2f)"),
  10.   (double)RFile::size()/(double)m_length
  11. );
  12.     return ret;
  13. }
  14. // ----------------------------------------------------------------------------------------------------------------
  15. bool TCRFile::CheckTCR (RFile *fp) {
  16. char sign [9]; fp->seek (0);
  17. if (fp->read2 (sign,9) != 9) return false;
  18. if (memcmp (sign,"!!8-Bit!!",9))
  19. return false;
  20. return true;
  21. }
  22. // ----------------------------------------------------------------------------------------------------------------
  23. bool TCRFile::IsTCR (RFile *fp) {
  24. bool ret = CheckTCR (fp);
  25. fp->seek (0);
  26. return ret;
  27. }
  28. // ----------------------------------------------------------------------------------------------------------------
  29. TCRFile::TCRFile (const CString& fn) : RFile(fn), m_length(0), m_ptr(0) {
  30. if (Reopen() && CheckTCR (this)) {
  31. DWORD offset = 9; unsigned char ch; for (int i = 0; i < 256; i++) {
  32. if (RFile::read2 (&ch, 1) != 1) goto fail; Dictonary [i] = Buffer<unsigned char>(ch + 1);
  33. Dictonary [i][0] = ch; if (RFile::read2 (Dictonary [i] + 1, ch) != ch) goto fail;
  34. offset += ch + 1;
  35. }
  36. int nr = (int)((RFile::size() - offset + 4095) / 4096); m_blocks = Buffer<Block>(nr);
  37. Buffer<unsigned char> tmp (4096); for (int i = 0; i < nr; i++) {
  38. m_blocks [i].off = offset; m_blocks [i].size = RFile::read2 (tmp, 4096);
  39. m_blocks [i].uoff = m_length; m_blocks [i].usize = 0;
  40. for (DWORD j = 0; j < m_blocks [i].size; j++)
  41. m_blocks [i].usize += Dictonary [tmp[j]] [0];
  42. m_length += m_blocks [i].usize;
  43. offset += m_blocks [i].size;
  44. }
  45. return;
  46. }
  47. fail:
  48. CTVApp::Barf(_T("Invalid or unsupported TCR file"));
  49. }
  50. // ----------------------------------------------------------------------------------------------------------------
  51. void TCRFile::seek (DWORD pos) {
  52.   if (pos>=m_length)
  53.     m_ptr=m_length;
  54.   else
  55.     m_ptr=pos&BMASK;
  56. }
  57. // ----------------------------------------------------------------------------------------------------------------
  58. DWORD TCRFile::read (void *buf) {
  59. unsigned char *out = (unsigned char*) buf; DWORD n = BSZ; for (int i = 0; i < m_blocks.size() && n; i++)
  60. if (m_ptr >= m_blocks[i].uoff && m_ptr < m_blocks[i].uoff + m_blocks[i].usize) {
  61.   Buffer<unsigned char> src (m_blocks[i].size);  RFile::seek(m_blocks[i].off);
  62. if (RFile::read2 (src, m_blocks[i].size) != m_blocks[i].size) return 0;
  63. Buffer<unsigned char> dst (m_blocks[i].usize); unsigned char *ptr = dst;
  64. for (DWORD j = 0; j < m_blocks[i].size; j++) {
  65. unsigned char len = Dictonary [src[j]][0];
  66. memcpy (ptr, Dictonary [src[j]] + 1, len);
  67. ptr += len;
  68. }
  69. DWORD len = m_blocks[i].usize - (m_ptr - m_blocks[i].uoff); if (len > n) len = n;
  70. memcpy (out, dst + m_ptr - m_blocks[i].uoff, len); out += len;
  71. m_ptr += len; n -= len;
  72. }
  73. return BSZ - n;
  74. }