home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / windiff / file.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  8KB  |  296 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright (C) 1993-1997 Microsoft Corporation.
  5. *       All rights reserved. 
  6. *       This source code is only intended as a supplement to 
  7. *       Microsoft Development Tools and/or WinHelp documentation.
  8. *       See these sources for detailed information regarding the 
  9. *       Microsoft samples programs.
  10. \******************************************************************************/
  11.  
  12. /****************************** Module Header *******************************
  13. * Module Name: FILE.C
  14. *
  15. * An object representing a file and the lines of text it contains.
  16. *
  17. * Functions:
  18. *
  19. * file_new()
  20. * file_getdiritem()
  21. * file_delete()
  22. * file_getlinelist()
  23. * file_discardlines()
  24. * file_reset()
  25. * file_readlines()
  26. *
  27. * Comments:
  28. *
  29. * A FILEDATA object is initialised with a DIRITEM handle from which it
  30. * can get a filename. It knows how to supply a list of LINE handles for the
  31. * lines of text in the file.
  32. *
  33. * The file is read into memory optionally on creation of the FILEDATA object:
  34. * otherwise, at the first call to file_getlinelist. It can be discarded
  35. * by calling file_discardlines: in this case, it will be re-read next time
  36. * file_getlinelist is called.
  37. *
  38. * Calling file_reset will cause line_reset to be called for all lines
  39. * in the list. This clears any links.
  40. *
  41. * We allocate all memory from a gmem* heap hHeap, assumed to be declared and
  42. * initialised elsewhere.
  43. *
  44. ****************************************************************************/
  45.  
  46. #include <windows.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49.  
  50. #include "gutils.h"
  51. #include "windiff.h"
  52. #include "list.h"
  53. #include "line.h"
  54. #include "scandir.h"
  55. #include "file.h"
  56.  
  57. extern HANDLE hHeap;
  58.  
  59. struct filedata {
  60.  
  61.         DIRITEM diritem;        /* handle to file name information */
  62.         LIST lines;             /* NULL if lines not read in */
  63. };
  64.  
  65.  
  66. void file_readlines(FILEDATA fd);
  67.  
  68. /****************************************************************************
  69.  * Function: file_new
  70.  *
  71.  * Purpose:
  72.  * 
  73.  * Creates a new FILEDATA, based on a DIRITEM. the filedata will retain
  74.  * the diritem handle for use in fetching filenames and handles.
  75.  *
  76.  * If the bRead is set, the file will be read into memory. If not, this
  77.  * will be done during the first call to file_getlines.
  78.  *
  79.  ***************************************************************************/
  80. FILEDATA
  81. file_new(DIRITEM fiName, BOOL bRead)
  82. {
  83.         FILEDATA fd;
  84.  
  85.         fd = (FILEDATA) gmem_get(hHeap, sizeof(struct filedata));
  86.         if (fd == NULL) {
  87.                 return(NULL);
  88.         }
  89.  
  90.         fd->diritem = fiName;
  91.         fd->lines = NULL;
  92.  
  93.         if (bRead) {
  94.                 file_readlines(fd);
  95.         }
  96.  
  97.         return(fd);
  98. }
  99.  
  100. /****************************************************************************
  101.  * Function: file_getdiritem
  102.  *
  103.  * Purpose:
  104.  * 
  105.  * Returns a handle to the DIRITEM used to create this FILEDATA
  106.  *
  107.  ***************************************************************************/
  108. DIRITEM
  109. file_getdiritem(FILEDATA fd)
  110. {
  111.         if (fd == NULL) {
  112.                 return(NULL);
  113.         }
  114.  
  115.         return(fd->diritem);
  116. }
  117.  
  118.  
  119. /****************************************************************************
  120.  * Function: file_delete
  121.  *
  122.  * Purpose:
  123.  * 
  124.  * Deletes a filedata and its associated list of lines. Note that the diritem
  125.  * is not deleted (this is owned by the DIRLIST, and will be deleted
  126.  * when the DIRLIST is deleted)
  127.  *
  128.  ***************************************************************************/
  129. void
  130. file_delete(FILEDATA fd)
  131. {
  132.         if (fd == NULL) {
  133.                 return;
  134.         }
  135.  
  136.         /* throw away the line list, if there is one */
  137.         file_discardlines(fd);
  138.  
  139.         gmem_free(hHeap, (LPSTR) fd, sizeof(struct filedata));
  140. }
  141.  
  142. /****************************************************************************
  143.  * Function: file_getlinelist
  144.  *
  145.  * Purpose:
  146.  * 
  147.  * Returns a handle to a list of lines in this file. The items in the
  148.  * list are LINE handles.
  149.  *
  150.  * The first call to this function will cause the file to be read into
  151.  * memory if bRead was FALSE on the call to file_new, or if file_discardlines
  152.  * has since been called.
  153.  *
  154.  * The list of lines returned should not be deleted except by calls to
  155.  * file_delete or file_discardlines.
  156.  *
  157.  ***************************************************************************/
  158. LIST
  159. file_getlinelist(FILEDATA fd)
  160. {
  161.         if (fd == NULL) {
  162.                 return NULL;
  163.         }
  164.  
  165.         if (fd->lines == NULL) {
  166.                 file_readlines(fd);
  167.         }
  168.         return(fd->lines);
  169. }
  170.  
  171.  
  172. /****************************************************************************
  173.  * Function: file_discardlines
  174.  *
  175.  * Purpose:
  176.  * 
  177.  * Discards the list of lines associated with a file. This will cause
  178.  * the file to be re-read next time file_getlinelist is called.
  179.  *
  180.  ***************************************************************************/
  181. void
  182. file_discardlines(FILEDATA fd)
  183. {
  184.         LINE line;
  185.  
  186.         if (fd == NULL) {
  187.                 return;
  188.         }
  189.  
  190.         if (fd->lines != NULL) {
  191.  
  192.                 /* clear each line to free any memory associated
  193.                  * with them, then discard the entire list
  194.                  */
  195.                 List_TRAVERSE(fd->lines, line) {
  196.                         line_delete(line);
  197.                 }
  198.                 List_Destroy(&fd->lines);
  199.         }
  200.  
  201.         /* this is probably done in List_Destroy, but better do it anyway*/
  202.         fd->lines = NULL;
  203. }
  204.  
  205.  
  206. /****************************************************************************
  207.  * Function: file_reset
  208.  *
  209.  * Purpose:
  210.  * 
  211.  * Forces a reset of each line in the list. The function line_reset discards 
  212.  * links between lines, and any hashcode information. This would be used if
  213.  * the compare options or hashcode options have changed.
  214.  *
  215.  ***************************************************************************/
  216. void
  217. file_reset(FILEDATA fd)
  218. {
  219.         LINE line;
  220.  
  221.         if (fd == NULL) {
  222.                 return;
  223.         }
  224.  
  225.         if (fd->lines != NULL) {
  226.  
  227.                 List_TRAVERSE(fd->lines, line)  {
  228.                         line_reset(line);
  229.                 }
  230.         }
  231. }
  232.  
  233.  
  234. /****************************************************************************
  235.  * Function: file_readlines
  236.  *
  237.  * Purpose:
  238.  * 
  239.  * Reads the file into a list of lines.
  240.  *
  241.  * Comments:
  242.  *
  243.  * We use the buffered read functions to read a block at a time, and
  244.  * return us a pointer to a line within the block. The line we are
  245.  * pointed to is not null terminated. from this we do a line_new: this
  246.  * will make a copy of the text (since we want to re-use the buffer), and
  247.  * will null-terminate its copy.
  248.  *
  249.  *
  250.  ***************************************************************************/
  251. void
  252. file_readlines(FILEDATA fd)
  253. {
  254.         LPSTR textp;
  255.         int fh;
  256.         FILEBUFFER fbuf;
  257.         int linelen;
  258.         int linenr = 1;
  259.         HCURSOR hcurs;
  260.  
  261.         hcurs = SetCursor(LoadCursor(NULL, IDC_WAIT));
  262.  
  263.         /* open the file */
  264.         fh = dir_openfile(fd->diritem);
  265.  
  266.         if (fh < 0) {
  267.                 SetCursor(hcurs);
  268.                 return;
  269.         }
  270.         /* initialise the file buffering */
  271.         fbuf = readfile_new(fh);
  272.  
  273.  
  274.         /* make an empty list for the files */
  275.         fd->lines = List_Create();
  276.  
  277.         while ( (textp = readfile_next(fbuf, &linelen)) != NULL) {
  278.  
  279.                 line_new(textp, linelen, linenr++, fd->lines);
  280.  
  281.         }
  282.  
  283.         /* close filehandle and free buffer */
  284.         readfile_delete(fbuf);
  285.  
  286.         dir_closefile(fd->diritem, fh);
  287.  
  288.         SetCursor(hcurs);
  289. }
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.