Annotation of researchv9/X11/src/X.V11R1/clients/xedit/EDiskSrc.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char rcs_id[] = "$Header: EDiskSrc.c,v 1.5 87/09/11 08:21:59 toddb Exp $";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  *                       COPYRIGHT 1987
        !             7:  *                DIGITAL EQUIPMENT CORPORATION
        !             8:  *                    MAYNARD, MASSACHUSETTS
        !             9:  *                     ALL RIGHTS RESERVED.
        !            10:  *
        !            11:  * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
        !            12:  * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
        !            13:  * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
        !            14:  * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
        !            15:  *
        !            16:  * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
        !            17:  * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
        !            18:  * SET FORTH ABOVE.
        !            19:  *
        !            20:  *
        !            21:  * Permission to use, copy, modify, and distribute this software and its
        !            22:  * documentation for any purpose and without fee is hereby granted, provided
        !            23:  * that the above copyright notice appear in all copies and that both that
        !            24:  * copyright notice and this permission notice appear in supporting documentation,
        !            25:  * and that the name of Digital Equipment Corporation not be used in advertising
        !            26:  * or publicity pertaining to distribution of the software without specific, 
        !            27:  * written prior permission.
        !            28:  */
        !            29: 
        !            30: /* File: TEDiskSource.c - last edit by */
        !            31: /* weissman:   25 Aug 86 */
        !            32: 
        !            33: #include <sys/types.h>
        !            34: #include <sys/stat.h>
        !            35: #include <sys/file.h>
        !            36: #include "xedit.h"
        !            37: /* Private definitions. */
        !            38: 
        !            39: #define BUFSIZE        512
        !            40: 
        !            41: extern char *malloc();
        !            42: extern char *realloc();
        !            43: extern char *strcpy();
        !            44: 
        !            45: typedef struct {
        !            46:     char *buf;
        !            47:     int length;
        !            48:     int maxlength;
        !            49:     long start;
        !            50: } PieceRec, *PiecePtr;
        !            51: 
        !            52: typedef struct {
        !            53:     int file;
        !            54:     char *name;
        !            55:     XtTextPosition length;
        !            56:     XtTextPosition origlength;
        !            57:     int numpieces;
        !            58:     PiecePtr piece;
        !            59:     short changed, everchanged;
        !            60:     short startsvalid;
        !            61:     short eversaved;
        !            62:     XtEditType editMode;
        !            63: } EDiskRec, *EDiskPtr;
        !            64: 
        !            65: 
        !            66: static CalculateStarts(data)
        !            67:   EDiskPtr data;
        !            68: {
        !            69:     int     i;
        !            70:     PiecePtr piece;
        !            71:     long    start = 0;
        !            72:     for (i = 0, piece = data->piece; i < data->numpieces; i++, piece++) {
        !            73:        piece->start = start;
        !            74:        start += piece->length;
        !            75:     }
        !            76:     data->startsvalid = TRUE;
        !            77: }
        !            78: 
        !            79: static ReadPiece(data, i)
        !            80:   EDiskPtr data;
        !            81:   int i;
        !            82: {
        !            83:     PiecePtr piece = data->piece + i;
        !            84:     piece->maxlength = piece->length;
        !            85:     piece->buf = malloc(piece->maxlength);
        !            86:     lseek(data->file, i * BUFSIZE, 0);
        !            87:     read(data->file, piece->buf, piece->length);
        !            88: }
        !            89: 
        !            90: 
        !            91: 
        !            92: static PiecePtr PieceFromPosition(data, position)
        !            93:   EDiskPtr data;
        !            94:   XtTextPosition position;
        !            95: {
        !            96:     int     i;
        !            97:     PiecePtr piece;
        !            98:     if (!data->everchanged) {
        !            99:        i = position / BUFSIZE;
        !           100:        if (i >= data->numpieces) i = data->numpieces - 1;
        !           101:        piece = data->piece + i;
        !           102:     } else {
        !           103:        if (!data->startsvalid)
        !           104:            CalculateStarts(data);
        !           105:        for (i = 0, piece = data->piece; i < data->numpieces - 1; i++, piece++)
        !           106:            if (position < piece->start + piece->length)
        !           107:                break;
        !           108:     }
        !           109:     if (!piece->buf) ReadPiece(data, i);
        !           110:     return piece;
        !           111: }
        !           112: 
        !           113: static XtTextPosition CoerceToLegalPosition(data, position)
        !           114:   EDiskPtr data;
        !           115:   XtTextPosition position;
        !           116: {
        !           117:     return (position < 0) ? 0 :
        !           118:                 ((position > data->length) ? data->length : position);
        !           119: }
        !           120: 
        !           121: 
        !           122: /* Semi-public definitions */
        !           123: 
        !           124: static EDiskReadText(src, position, text, maxRead)
        !           125:   XtTextSource *src;
        !           126:   XtTextPosition position;
        !           127:   XtTextBlock *text;
        !           128:   int maxRead;
        !           129: {
        !           130:     EDiskPtr data = (EDiskPtr) src->data;
        !           131:     PiecePtr piece;
        !           132:     int     count;
        !           133:     text->firstPos = position;
        !           134:     if (position < data->length) {
        !           135:        piece = PieceFromPosition(data, position);
        !           136:        text->ptr = piece->buf + (position - piece->start);
        !           137:        count = piece->length - (position - piece->start);
        !           138:        text->length = (count < maxRead) ? count : maxRead;
        !           139:     }
        !           140:     else {
        !           141:        text->length = 0;
        !           142:        text->ptr = "";
        !           143:     }
        !           144:     return position + text->length;
        !           145: }
        !           146: 
        !           147: 
        !           148: static EDiskReplaceText(src, startPos, endPos, text, Delta)
        !           149:   XtTextSource *src;
        !           150:   XtTextPosition startPos, endPos;
        !           151:   XtTextBlock *text;
        !           152:   int *Delta;
        !           153: {
        !           154:     EDiskPtr data = (EDiskPtr) src->data;
        !           155:     PiecePtr piece, piece2;
        !           156:     int     oldlength = endPos - startPos;
        !           157:     int     delta = text->length - oldlength;
        !           158:     int     i;
        !           159:    switch (data->editMode) {
        !           160:         case XttextAppend:
        !           161:             if (startPos != endPos || endPos!= data->length)
        !           162:                 return (POSITIONERROR);
        !           163:             break;
        !           164:         case XttextRead:
        !           165:             return (EDITERROR);
        !           166:         case XttextEdit:
        !           167:             break;
        !           168:         default:
        !           169:             return (EDITERROR);
        !           170:     }
        !           171: 
        !           172:     if (delta == 0 && oldlength == 0) 
        !           173:        return 0;
        !           174:     data->length += delta;
        !           175:     piece = PieceFromPosition(data, startPos);
        !           176:     if (oldlength > 0) {
        !           177:        piece2 = PieceFromPosition(data, endPos - 1);
        !           178:        if (piece != piece2) {
        !           179:            oldlength = endPos - piece2->start;
        !           180:            piece2->length -= oldlength;
        !           181:            for (i = 0; i < piece2->length; i++)
        !           182:                piece2->buf[i] = piece2->buf[i + oldlength];
        !           183:            for (piece2--; piece2 > piece; piece2--)
        !           184:                piece2->length = 0;
        !           185:            oldlength = piece->length - (startPos - piece->start);
        !           186:            delta = text->length - oldlength;
        !           187:        }
        !           188:     }
        !           189:     data->changed = data->everchanged = TRUE;
        !           190:     data->startsvalid = FALSE;
        !           191:     piece->length += delta;
        !           192:     if (piece->length > piece->maxlength) {
        !           193:        do
        !           194:            piece->maxlength *= 2;
        !           195:        while (piece->length > piece->maxlength);
        !           196:        piece->buf = realloc(piece->buf, piece->maxlength);
        !           197:     }
        !           198:     if (delta < 0)             /* insert shorter than delete, text getting
        !           199:                                   shorter */
        !           200:        for (i = startPos - piece->start; i < piece->length; i++)
        !           201:            piece->buf[i] = piece->buf[i - delta];
        !           202:     else
        !           203:        if (delta > 0)          /* insert longer than delete, text getting
        !           204:                                   longer */
        !           205:            for (i = piece->length - delta;
        !           206:                    i >= startPos - piece->start;
        !           207:                    i--)
        !           208:                piece->buf[i + delta] = piece->buf[i];
        !           209:     if (text->length)  /* do insert */
        !           210:        for (i = 0; i < text->length; ++i)
        !           211:            if ((piece->buf[startPos - piece->start + i] = text->ptr[i]) == CR)
        !           212:                 piece->buf[startPos - piece->start + i] = LF;
        !           213:        *Delta = text->length - (endPos - startPos);
        !           214:     return EDITDONE;
        !           215: }
        !           216: 
        !           217: 
        !           218: static XtTextPosition EDiskGetLastPos(src)
        !           219:   XtTextSource *src;
        !           220: {
        !           221:     return ((EDiskPtr) src->data)->length;
        !           222: }
        !           223: 
        !           224: 
        !           225: static EDiskSetLastPos(src)
        !           226:   XtTextSource *src;
        !           227: {
        !           228: }
        !           229: 
        !           230: #define Look(index, c)\
        !           231: {                                                                      \
        !           232:     if ((dir == XtsdLeft && index <= 0) ||                             \
        !           233:            (dir == XtsdRight && index >= data->length))                        \
        !           234:        c = 0;                                                          \
        !           235:     else {                                                             \
        !           236:        if (index + doff < piece->start ||                              \
        !           237:                index + doff >= piece->start + piece->length)           \
        !           238:            piece = PieceFromPosition(data, index + doff);              \
        !           239:        c = piece->buf[index + doff - piece->start];                    \
        !           240:     }                                                                  \
        !           241: }
        !           242: 
        !           243: 
        !           244: 
        !           245: static XtTextPosition EDiskScan(src, position, sType, dir, count, include)
        !           246:   XtTextSource *src;
        !           247:   XtTextPosition position;
        !           248:   ScanType sType;
        !           249:   ScanDirection dir;
        !           250:   int count, include;
        !           251: {
        !           252:     EDiskPtr data = (EDiskPtr) src->data;
        !           253:     XtTextPosition index;
        !           254:     PiecePtr piece;
        !           255:     char    c;
        !           256:     int     ddir, doff, i, whiteSpace;
        !           257:     ddir = (dir == XtsdRight) ? 1 : -1;
        !           258:     doff = (dir == XtsdRight) ? 0 : -1;
        !           259:     
        !           260:     index = position;
        !           261:     piece = data->piece;
        !           262:     switch (sType) {
        !           263:        case XtstPositions: 
        !           264:            if (!include && count > 0)
        !           265:                count--;
        !           266:            index = CoerceToLegalPosition(data, index + count * ddir);
        !           267:            break;
        !           268:        case XtstWhiteSpace:    /* %%% This seems to ignore the fact that
        !           269:                                   whitespace can come in big chunks */
        !           270:            for (i = 0; i < count; i++) {
        !           271:                whiteSpace = -1;
        !           272:                while (index >= 0 && index <= data->length) {
        !           273:                    Look(index, c);
        !           274:                    if ((c == ' ') || (c == '\t') || (c == '\n')) {
        !           275:                        if (whiteSpace < 0) whiteSpace = index;
        !           276:                    } else if (whiteSpace >= 0)
        !           277:                        break;
        !           278:                    index += ddir;
        !           279:                }
        !           280:            }
        !           281:            if (!include) {
        !           282:                if (whiteSpace < 0 && dir == XtsdRight) whiteSpace = data->length;
        !           283:                index = whiteSpace;
        !           284:            }
        !           285:            index = CoerceToLegalPosition(data, index);
        !           286:            break;
        !           287:        case XtstEOL: 
        !           288:            for (i = 0; i < count; i++) {
        !           289:                while (index >= 0 && index <= data->length) {
        !           290:                    Look(index, c);
        !           291:                    if (c == '\n')
        !           292:                        break;
        !           293:                    index += ddir;
        !           294:                }
        !           295:                if (i < count - 1)
        !           296:                    index += ddir;
        !           297:            }
        !           298:            if (include)
        !           299:                index += ddir;
        !           300:            index = CoerceToLegalPosition(data, index);
        !           301:            break;
        !           302:        case XtstFile: 
        !           303:            if (dir == XtsdLeft)
        !           304:                index = 0;
        !           305:            else
        !           306:                index = data->length;
        !           307:            break;
        !           308:     }
        !           309:     return index;
        !           310: }
        !           311: 
        !           312: static XtEditType TEDiskGetEditType(src)
        !           313:   XtTextSource *src;
        !           314: {
        !           315:     EDiskPtr data = (EDiskPtr) src->data;
        !           316:     return(data->editMode);
        !           317: }
        !           318: 
        !           319: 
        !           320: /* Public definitions. */
        !           321: 
        !           322: XtTextSource *TCreateEDiskSource(name, mode)
        !           323:   char *name;
        !           324:   XtEditType mode;
        !           325: {
        !           326:     XtTextSource * src;
        !           327:     EDiskPtr data;
        !           328:     struct stat stat;
        !           329:     int     i;
        !           330:     src = (XtTextSource *) malloc(sizeof(XtTextSource));
        !           331:     src->read = EDiskReadText;
        !           332:     src->replace = EDiskReplaceText;
        !           333:     src->getLastPos = EDiskGetLastPos;
        !           334:     src->setLastPos = EDiskSetLastPos;
        !           335:     src->editType = TEDiskGetEditType;
        !           336:     src->scan = EDiskScan;
        !           337:     data = (EDiskPtr) malloc(sizeof(EDiskRec));
        !           338:     src->data = (int *) data;
        !           339:     data->file = open(name, O_RDONLY | O_CREAT, 0666);
        !           340:     data->name = strcpy(malloc(strlen(name) + 1), name);
        !           341:     fstat(data->file, &stat);
        !           342:     data->length = data->origlength = stat.st_size;
        !           343:     data->numpieces = (data->length + BUFSIZE - 1) / BUFSIZE;
        !           344:     if (data->numpieces < 1)
        !           345:        data->numpieces = 1;
        !           346:     data->piece = (PiecePtr) malloc(data->numpieces * sizeof(PieceRec));
        !           347:     for (i = 0; i < data->numpieces; i++) {
        !           348:        data->piece[i].buf = 0;
        !           349:        data->piece[i].length = BUFSIZE;
        !           350:        data->piece[i].start = i * BUFSIZE;
        !           351:     }
        !           352:     data->piece[data->numpieces - 1].length -=
        !           353:        data->numpieces * BUFSIZE - data->length;
        !           354:     data->startsvalid = TRUE;
        !           355:     data->changed = data->everchanged = data->eversaved = FALSE;
        !           356:     if (data->length == 0) {
        !           357:        data->piece[0].buf = malloc(1);
        !           358:        data->piece[0].maxlength = 1;
        !           359:     }
        !           360:     data->editMode = mode;
        !           361:     return src;
        !           362: }
        !           363: 
        !           364: 
        !           365: TEDiskChanged(src)
        !           366:   XtTextSource *src;
        !           367: {
        !           368:     return ((EDiskPtr) src->data)->changed;
        !           369: }
        !           370: 
        !           371: TEDiskSaveFile(src)
        !           372:   XtTextSource *src;
        !           373: {
        !           374:     EDiskPtr data = (EDiskPtr) src->data;
        !           375:     PiecePtr piece;
        !           376:     int     i, needlseek;
        !           377:     if (!data->changed)
        !           378:        return;
        !           379:     data->changed = FALSE;
        !           380:     if (!data->eversaved) {
        !           381:        data->eversaved = TRUE;
        !           382:        close(data->file);
        !           383:        data->file = open(data->name, O_RDWR, 0666);
        !           384:     }
        !           385:     if (!data->startsvalid)
        !           386:        CalculateStarts(data);
        !           387:     for (i = 0, piece = data->piece; i < data->numpieces; i++, piece++) {
        !           388:        if (!(piece->buf) && i * BUFSIZE != piece->start)
        !           389:            ReadPiece(data, i);
        !           390:     }
        !           391:     needlseek = TRUE;
        !           392:     for (i = 0, piece = data->piece; i < data->numpieces; i++, piece++) {
        !           393:        if (piece->buf) {
        !           394:            if (needlseek) {
        !           395:                lseek(data->file, piece->start, 0);
        !           396:                needlseek = FALSE;
        !           397:            }
        !           398:            write(data->file, piece->buf, piece->length);
        !           399:        }
        !           400:        else
        !           401:            needlseek = TRUE;
        !           402:     }
        !           403:     if (data->length < data->origlength)
        !           404:        ftruncate(data->file, data->length);
        !           405:     data->origlength = data->length;
        !           406: }
        !           407: 
        !           408: TEDiskSaveAsFile(src, filename)
        !           409:   XtTextSource *src;
        !           410:   char *filename;
        !           411: {
        !           412:     EDiskPtr data = (EDiskPtr) src->data;
        !           413:     int     i;
        !           414:     PiecePtr piece;
        !           415:     if (strcmp(filename, data->name) != 0) {
        !           416:        for (i = 0, piece = data->piece; i < data->numpieces; i++, piece++)
        !           417:            if (!(piece->buf))
        !           418:                ReadPiece(data, i);
        !           419:        data->eversaved = FALSE;
        !           420:        data->origlength = 0;
        !           421:        data->file = creat(filename, 0666);
        !           422:        data->eversaved = TRUE;
        !           423:        data->origlength = 0;
        !           424:        free(data->name);
        !           425:        data->name = strcpy(malloc(strlen(filename) + 1), filename);
        !           426:        data->changed = TRUE;
        !           427:     }
        !           428:     TEDiskSaveFile(src);
        !           429: }
        !           430: 
        !           431: 
        !           432: TDestroyEDiskSource(src)
        !           433:   XtTextSource *src;
        !           434: {
        !           435:     EDiskPtr data = (EDiskPtr) src->data;
        !           436:     int i;
        !           437:     char *ptr;
        !           438:     close(data->file);
        !           439:     for (i=0 ; i<data->numpieces ; i++)
        !           440:        if (ptr = data->piece[i].buf) free(ptr);
        !           441:     free(data->piece);
        !           442:     free(data->name);
        !           443:     free(data);
        !           444:     free(src);
        !           445: }

unix.superglobalmegacorp.com

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