|
|
1.1 ! root 1: ! 2: /******************************************************************************\ ! 3: * This is a part of the Microsoft Source Code Samples. ! 4: * Copyright (C) 1993 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.