lzcopy.c
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:5k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. /*          DOS Lempel-Ziv Data Decompression Module
  2.             (C) Copyright 1989 by Microsoft
  3.             written by David Dickman
  4.             LZ code by Steve Zeck
  5.   note:
  6.   this module is compiled twice.  with LZDLL defined to be linked
  7.   with the LZEXPAND.DLL windows code.  without this, to build the
  8.   LZCOPY.LIB dos library.  be sure things work in both cases.
  9. */
  10. #ifdef LZDLL
  11. #include <windows.h>
  12. #include <winexp.h>
  13. #else
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17. #include <io.h>
  18. #include <dos.h>
  19. #include <fcntl.h>
  20. #include <systypes.h>
  21. #include <sysstat.h>
  22. #include <malloc.h>
  23. #include <errno.h>
  24. #endif
  25. #include "lzcopy.h"
  26. // Globals
  27. static long cblOutSize;        // size in bytes of output file
  28. // WriteOutBuf()
  29. //
  30. // NOTE! not to be confused with WriteOutBuf() in compress.c
  31. //
  32. // Dumps output buffer to output file.  Returns c cast as an int if the write
  33. // is successful.  If the write is unsuccessful, returns LZERROR_BADOUTHANDLE or
  34. // LZERROR_WRITE.
  35. //
  36. // returns:
  37. // < 0 error code (all errors are < 0)
  38. // > 0 success, char as described above
  39. //
  40. int WriteOutBuf(UCHAR uch,    // first character to be added to the empty
  41.                               // buffer after the full buffer is written
  42.                 int doshDest) // DOS output file handle
  43. {
  44.    unsigned ucbToWrite,        // number of bytes to write from rguchOutBuf[]
  45.             ucbWritten;        // number of bytes actually written
  46.    // how many bytes should be written from rguchOutBuf[]?
  47.    ucbToWrite = (unsigned)(puchOutBuf - rguchOutBuf);
  48.    ucbWritten = FWRITE(doshDest, rguchOutBuf, ucbToWrite);
  49.    
  50.    if (ucbWritten != ucbToWrite)
  51.       return LZERROR_WRITE;
  52. #ifndef LZDLL
  53.    if (FERROR())
  54.          return LZERROR_WRITE;
  55. #endif
  56.    // keep track of bytes written
  57.    cblOutSize += (long)ucbWritten;
  58.    // reset write pointer to beginning of output buffer
  59.    puchOutBuf = rguchOutBuf;
  60.    // add the next character to the new buffer
  61.    return ((int)(*puchOutBuf++ = uch));
  62. }  // WriteOutBuf()
  63. /***************************************************************************
  64.  *
  65.  * long DOSLZCopy()
  66.  *
  67.  * Copies input file with DOS handle doshSource to output file with DOS
  68.  * handle doshDest.  If the input file has a LZ compressed file header, 
  69.  * it is decompressed into the output file using LZ decoding.  If the 
  70.  * input file does not have a LZ compressed file header, it is directly 
  71.  * copied to the output file.
  72.  *
  73.  * in:
  74.  * doshSource source file handle
  75.  * doshDest dest file handle
  76.  *
  77.  * returns:
  78.  * # bytes copied success
  79.  * < 0 failure for various LZERROR_ reasons
  80.  *
  81.  ***************************************************************************/
  82. long DOSLZCopy(int doshSource, int doshDest)
  83. {
  84.    FH FHIn;          // structure holding header information from
  85.                      // compressed input file (used for decoding)
  86.    unsigned ucbRead;  // number of bytes actually read into rguchOutBuf[]
  87.                      // during direct copy
  88.    int f;            // holds LZDecode() return value
  89.    cblOutSize = 0L;
  90.    if (! InitBuffers())
  91.       return LZERROR_GLOBALLOC;
  92.    // check for LZ compressed file header
  93.    if (! GetHdr((FH LZPTR *)&FHIn, doshSource) || ! ChkHdr(FHIn)
  94.        || FHIn.uchAlgorithm != uchALG_LEMPEL_ZIV)
  95.    {
  96.       /************************ not compressed ****************************/
  97.       // uncompressed file (straight DOS copy)
  98.       // move to beginning of input file
  99.       if (FSEEK(doshSource, 0L, SEEK_SET) != 0L)
  100.       {
  101.          FreeBuffers();
  102.          return LZERROR_BADINHANDLE;
  103.       }
  104.       while ((ucbRead = FREAD(doshSource, (LPSTR)rguchOutBuf, ucbIOBufLen)) > 0U
  105. #ifdef LZDLL
  106.              && ucbRead != (unsigned)(-1))
  107. #else
  108.              && (FERROR() == 0))
  109. #endif
  110.       {
  111.          if (FWRITE(doshDest, rguchOutBuf, ucbRead) != ucbRead) {
  112.             FreeBuffers();
  113.             return LZERROR_WRITE;
  114.          }
  115.          cblOutSize += (long)ucbRead;
  116.       }
  117. #ifdef LZDLL
  118.       // here, ucbRead ==  0, EOF (proper loop termination)
  119.       //               == -1, bad DOS handle
  120.       if (ucbRead == (unsigned)(-1))
  121. #else
  122.       // here, FERROR() == 0U, EOF (proper loop termination)
  123.       //                != 0U, bad DOS handle
  124.       if (FERROR() != 0U)
  125. #endif
  126.       {
  127.          FreeBuffers();
  128.          return LZERROR_READ;
  129.       }
  130.    } else {
  131.       /************************ compressed ****************************/
  132.       // compressed file (LZ decompression)
  133.       // move to beginning of compressed data and decompress file
  134.       if (FSEEK(doshSource, (long)cbHdrSize, SEEK_SET) != (long)cbHdrSize)
  135.       {
  136.          FreeBuffers();
  137.          return LZERROR_BADINHANDLE;
  138.       }
  139.       if ((f = LZDecode(doshSource, doshDest)) != LZDECODE_OK)
  140.       {
  141.          FreeBuffers();
  142.          return f;
  143.       }
  144.    }
  145.    // copy date and time stamp
  146.    // doshSource and doshDest known to be valid DOS file handles
  147.    CopyCreateDate(doshSource, doshDest);
  148.    FreeBuffers();
  149.    return cblOutSize; // # bytes generated
  150. }  // DOSLZCopy()