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