Annotation of researchv9/X11/src/X.V11R1/lib/Xtk/DiskSrc.c, revision 1.1

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

unix.superglobalmegacorp.com

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