Annotation of researchv9/X11/src/X.V11R1/lib/oldXtk/DiskSrc.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.