Annotation of researchv9/X11/src/X.V11R1/lib/oldXtk/DiskSrc.c, revision 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.