|
|
1.1 ! root 1: /* $Header: DiskSrc.c,v 1.1 87/09/11 08:00:03 toddb Exp $ */ ! 2: #ifndef lint ! 3: static char *sccsid = "@(#)DiskSource.c 1.9 2/25/87"; ! 4: #endif lint ! 5: ! 6: /* ! 7: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. ! 8: * ! 9: * All Rights Reserved ! 10: * ! 11: * Permission to use, copy, modify, and distribute this software and its ! 12: * documentation for any purpose and without fee is hereby granted, ! 13: * provided that the above copyright notice appear in all copies and that ! 14: * both that copyright notice and this permission notice appear in ! 15: * supporting documentation, and that the name of Digital Equipment ! 16: * Corporation not be used in advertising or publicity pertaining to ! 17: * distribution of the software without specific, written prior permission. ! 18: * ! 19: * ! 20: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 21: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 22: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 23: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 24: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 25: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 26: * SOFTWARE. ! 27: */ ! 28: ! 29: /* File: DiskSource.c */ ! 30: /* Documentation for source specfic routine semantics may be found in the ! 31: * TextDisp.h file. ! 32: */ ! 33: ! 34: #include "Xlib.h" ! 35: #include <stdio.h> ! 36: #include "Intrinsic.h" ! 37: #include "Text.h" ! 38: #include "TextDisp.h" /** included in all text subwindow files **/ ! 39: ! 40: void bcopy(); ! 41: ! 42: /** private DiskSource definitions **/ ! 43: ! 44: typedef struct _DiskSourceData { ! 45: FILE *file; ! 46: XtTextPosition position, /* file position of first char in buffer */ ! 47: length; /* length of file */ ! 48: char *buffer; /* piece of file in memory */ ! 49: int charsInBuffer; /* number of bytes used in memory */ ! 50: XtEditType editMode; /* append, read */ ! 51: } DiskSourceData, *DiskSourcePtr; ! 52: ! 53: #define bufSize 1000 ! 54: ! 55: #define Increment(data, position, direction)\ ! 56: {\ ! 57: if (direction == XtsdLeft) {\ ! 58: if (position > 0) \ ! 59: position -= 1;\ ! 60: }\ ! 61: else {\ ! 62: if (position < data->length)\ ! 63: position += 1;\ ! 64: }\ ! 65: } ! 66: ! 67: static char Look(data, position, direction) ! 68: DiskSourcePtr data; ! 69: XtTextPosition position; ! 70: ScanDirection direction; ! 71: { ! 72: ! 73: if (direction == XtsdLeft) { ! 74: if (position == 0) ! 75: return('\n'); ! 76: else { ! 77: FillBuffer(data, position - 1); ! 78: return(data->buffer[position - data->position - 1]); ! 79: } ! 80: } ! 81: else { ! 82: if (position == data->length) ! 83: return('\n'); ! 84: else { ! 85: FillBuffer(data, position); ! 86: return(data->buffer[position - data->position]); ! 87: } ! 88: } ! 89: } ! 90: ! 91: ! 92: ! 93: int DiskReadText (src, pos, text, maxRead) ! 94: XtTextSource *src; ! 95: XtTextPosition pos; /** starting position */ ! 96: XtTextBlock *text; /** RETURNED: text read in */ ! 97: int maxRead; /** max number of bytes to read **/ ! 98: { ! 99: XtTextPosition count; ! 100: DiskSourcePtr data; ! 101: ! 102: data = (DiskSourcePtr) src->data; ! 103: FillBuffer(data, pos); ! 104: text->firstPos = pos; ! 105: text->ptr = data->buffer + (pos - data->position); ! 106: count = data->charsInBuffer - (pos - data->position); ! 107: text->length = (maxRead > count) ? count : maxRead; ! 108: return pos + text->length; ! 109: } ! 110: ! 111: /* ! 112: * this routine reads text starting at "pos" into memory. ! 113: * Contains heuristic for keeping the read position centered in the buffer. ! 114: */ ! 115: static int FillBuffer (data, pos) ! 116: DiskSourcePtr data; ! 117: XtTextPosition pos; ! 118: { ! 119: long readPos; ! 120: if ((pos < data->position || ! 121: pos >= data->position + data->charsInBuffer - 100) && ! 122: data->charsInBuffer != data->length) { ! 123: if (pos < (bufSize / 2)) ! 124: readPos = 0; ! 125: else ! 126: if (pos >= data->length - bufSize) ! 127: readPos = data->length - bufSize; ! 128: else ! 129: if (pos >= data->position + data->charsInBuffer - 100) ! 130: readPos = pos - (bufSize / 2); ! 131: else ! 132: readPos = pos; ! 133: (void) fseek(data->file, readPos, 0); ! 134: data->charsInBuffer = fread(data->buffer, sizeof(char), bufSize, ! 135: data->file); ! 136: data->position = readPos; ! 137: } ! 138: } ! 139: ! 140: /* ! 141: * This is a dummy routine for read only disk sources. ! 142: */ ! 143: /*ARGSUSED*/ /* keep lint happy */ ! 144: static int DummyReplaceText (src, startPos, endPos, text, delta) ! 145: XtTextSource *src; ! 146: XtTextPosition startPos, endPos; ! 147: XtTextBlock *text; ! 148: int *delta; ! 149: { ! 150: return(EDITERROR); ! 151: } ! 152: ! 153: ! 154: /* ! 155: * This routine will only append to the end of a source. If incorrect ! 156: * starting and ending positions are given, an error will be returned. ! 157: */ ! 158: static int DiskAppendText (src, startPos, endPos, text, delta) ! 159: XtTextSource *src; ! 160: XtTextPosition startPos, endPos; ! 161: XtTextBlock *text; ! 162: int *delta; ! 163: { ! 164: long topPosition = 0; ! 165: char *tmpPtr; ! 166: DiskSourcePtr data; ! 167: data = (DiskSourcePtr) src->data; ! 168: if (startPos != endPos || endPos != data->length) ! 169: return (POSITIONERROR); ! 170: /* write the new text to the end of the file */ ! 171: if (text->length > 0) { ! 172: (void) fseek(data->file, data->length, 0); ! 173: (void) fwrite(text->ptr, sizeof(char), text->length, data->file); ! 174: } else ! 175: /* if the delete key was hit, blank out last char in the file */ ! 176: if (text->length < 0) { ! 177: (void) fseek(data->file, data->length-1, 0); ! 178: (void) fwrite(" ", sizeof(char), 1, data->file); ! 179: } ! 180: /* need this in case the application trys to seek to end of file. */ ! 181: (void) fseek(data->file, topPosition, 2); ! 182: ! 183: /* put the new text into the buffer in memory */ ! 184: data->length += text->length; ! 185: if (data->charsInBuffer + text->length <= bufSize) { ! 186: /**** NOTE: need to check if text won't fit in the buffer ***/ ! 187: if (text->length > 0) { ! 188: tmpPtr = data->buffer + data->charsInBuffer; ! 189: bcopy(text->ptr, tmpPtr, text->length); ! 190: } ! 191: data->charsInBuffer += text->length; ! 192: } else ! 193: FillBuffer(data, data->length - text->length); ! 194: ! 195: *delta = text->length; ! 196: return (EDITDONE); ! 197: } ! 198: ! 199: ! 200: static int DiskSetLastPos (src, lastPos) ! 201: XtTextSource *src; ! 202: XtTextPosition lastPos; ! 203: { ! 204: ((DiskSourceData *)(src->data))->length = lastPos; ! 205: } ! 206: ! 207: /* ! 208: * This routine will start at ! 209: * the "pos" position of the source and scan in the appropriate ! 210: * direction until it finds something of the right sType. It returns ! 211: * the new position. If upon reading it hits the end of the buffer ! 212: * in memory, it will refill the buffer. ! 213: */ ! 214: static XtTextPosition DiskScan (src, pos, sType, dir, count, include) ! 215: XtTextSource *src; ! 216: XtTextPosition pos; ! 217: ScanType sType; ! 218: ScanDirection dir; ! 219: int count; ! 220: Boolean include; ! 221: { ! 222: DiskSourcePtr data; ! 223: XtTextPosition position; ! 224: int i, whiteSpace; ! 225: char c; ! 226: ! 227: data = (DiskSourcePtr) src->data; ! 228: position = pos; ! 229: switch (sType) { ! 230: case XtstPositions: ! 231: if (!include && count > 0) ! 232: count -= 1; ! 233: for (i = 0; i < count; i++) { ! 234: Increment(data, position, dir); ! 235: } ! 236: break; ! 237: case XtstWhiteSpace: ! 238: for (i = 0; i < count; i++) { ! 239: whiteSpace = 0; ! 240: while (position >= 0 && position <= data->length) { ! 241: FillBuffer(data, position); ! 242: c = Look(data, position, dir); ! 243: whiteSpace = (c == ' ') || (c == '\t') || (c == '\n'); ! 244: if (whiteSpace) ! 245: break; ! 246: Increment(data, position, dir); ! 247: } ! 248: if (i + 1 != count) ! 249: Increment(data, position, dir); ! 250: } ! 251: if (include) ! 252: Increment(data, position, dir); ! 253: break; ! 254: case XtstEOL: ! 255: for (i = 0; i < count; i++) { ! 256: while (position >= 0 && position <= data->length) { ! 257: if (Look(data, position, dir) == '\n') ! 258: break; ! 259: Increment(data, position, dir); ! 260: } ! 261: if (i + 1 != count) ! 262: Increment(data, position, dir); ! 263: } ! 264: if (include) { ! 265: /* later!!!check for last char in file # eol */ ! 266: Increment(data, position, dir); ! 267: } ! 268: break; ! 269: case XtstFile: ! 270: case XtselectAll: ! 271: if (dir == XtsdLeft) ! 272: position = 0; ! 273: else ! 274: position = data->length; ! 275: } ! 276: return(position); ! 277: } ! 278: ! 279: ! 280: static XtEditType DiskGetEditType(src) ! 281: XtTextSource *src; ! 282: { ! 283: DiskSourcePtr data; ! 284: data = (DiskSourcePtr) src->data; ! 285: return(data->editMode); ! 286: } ! 287: ! 288: /******* Public routines **********/ ! 289: ! 290: int *XtDiskSourceCreate(name, mode) ! 291: char *name; ! 292: XtEditType mode; ! 293: { ! 294: XtTextSource *src; ! 295: DiskSourcePtr data; ! 296: long topPosition = 0; ! 297: ! 298: src = (XtTextSource *) XtMalloc(sizeof(XtTextSource)); ! 299: src->read = DiskReadText; ! 300: src->setLastPos = DiskSetLastPos; ! 301: src->scan = DiskScan; ! 302: src->editType = DiskGetEditType; ! 303: src->data = (int *) (XtMalloc(sizeof(DiskSourceData))); ! 304: data = (DiskSourcePtr) src->data; ! 305: switch (mode) { ! 306: case XttextRead: ! 307: if ((data->file = fopen(name, "r")) == 0) ! 308: XtErrorFunction(XtFOPEN); ! 309: src->replace = DummyReplaceText; ! 310: break; ! 311: case XttextAppend: ! 312: if ((data->file = fopen(name, "r+")) == 0) ! 313: XtErrorFunction(XtFOPEN); ! 314: src->replace = DiskAppendText; ! 315: break; ! 316: default: ! 317: if ((data->file = fopen(name, "r")) == 0) ! 318: XtErrorFunction(XtFOPEN); ! 319: src->replace = DummyReplaceText; ! 320: } ! 321: (void) fseek(data->file, topPosition, 2); ! 322: data->editMode = mode; ! 323: data->length = ftell (data->file); ! 324: data->buffer = (char *) XtMalloc(bufSize); ! 325: data->position = 0; ! 326: data->charsInBuffer = 0; ! 327: src->data = (int *) (data); ! 328: return(int *) src; ! 329: } ! 330: ! 331: void XtDiskSourceDestroy (src) ! 332: XtTextSource *src; ! 333: { ! 334: DiskSourcePtr data; ! 335: data = (DiskSourcePtr) src->data; ! 336: XtFree((char *) data->buffer); ! 337: XtFree((char *) src->data); ! 338: XtFree((char *) src); ! 339: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.