Annotation of GNUtools/libg++/libio/editbuf.h, revision 1.1

1.1     ! root        1: /* This is part of libio/iostream, providing -*- C++ -*- input/output.
        !             2: Copyright (C) 1993 Free Software Foundation
        !             3: 
        !             4: This file is part of the GNU IO Library.  This library is free
        !             5: software; you can redistribute it and/or modify it under the
        !             6: terms of the GNU General Public License as published by the
        !             7: Free Software Foundation; either version 2, or (at your option)
        !             8: any later version.
        !             9: 
        !            10: This library is distributed in the hope that it will be useful,
        !            11: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            13: GNU General Public License for more details.
        !            14: 
        !            15: You should have received a copy of the GNU General Public License
        !            16: along with GNU CC; see the file COPYING.  If not, write to
        !            17: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
        !            18: 
        !            19: As a special exception, if you link this library with files
        !            20: compiled with a GNU compiler to produce an executable, this does not cause
        !            21: the resulting executable to be covered by the GNU General Public License.
        !            22: This exception does not however invalidate any other reasons why
        !            23: the executable file might be covered by the GNU General Public License.
        !            24: 
        !            25: Written by Per Bothner ([email protected]). */
        !            26: 
        !            27: #ifndef _EDITBUF_H
        !            28: #define _EDITBUF_H
        !            29: #ifdef __GNUG__
        !            30: #pragma interface
        !            31: #pragma cplusplus
        !            32: #endif
        !            33: #include <stdio.h>
        !            34: #include <fstream.h>
        !            35: 
        !            36: typedef unsigned long mark_pointer;
        !            37: // At some point, it might be nice to parameterize this code
        !            38: // in terms of buf_char.
        !            39: typedef /*unsigned*/ char buf_char;
        !            40: 
        !            41: // Logical pos from start of buffer (does not count gap).
        !            42: typedef long buf_index;
        !            43:                        
        !            44: // Pos from start of buffer, possibly including gap_size.
        !            45: typedef long buf_offset; 
        !            46: 
        !            47: #if 0
        !            48: struct buf_cookie {
        !            49:     FILE *file;
        !            50:     struct edit_string *str;
        !            51:     struct buf_cookie *next;
        !            52:     buf_index tell();
        !            53: };
        !            54: #endif
        !            55: 
        !            56: struct edit_buffer;
        !            57: struct edit_mark;
        !            58: 
        !            59: // A edit_string is defined as the region between the 'start' and 'end' marks.
        !            60: // Normally (always?) 'start->insert_before()' should be false,
        !            61: // and 'end->insert_before()' should be true.
        !            62: 
        !            63: struct edit_string {
        !            64:     struct edit_buffer *buffer; // buffer that 'start' and 'end' belong to
        !            65:     struct edit_mark *start, *end;
        !            66:     int length() const; // count of buf_chars currently in string
        !            67:     edit_string(struct edit_buffer *b,
        !            68:                      struct edit_mark *ms, struct edit_mark *me)
        !            69:        { buffer = b; start = ms; end = me; }
        !            70: /* Make a fresh, contiguous copy of the data in STR.
        !            71:    Assign length of STR to *LENP.
        !            72:    (Output has extra NUL at out[*LENP].) */
        !            73:     buf_char *copy_bytes(int *lenp) const;
        !            74: //    FILE *open_file(char *mode);
        !            75:     void assign(struct edit_string *src); // copy bytes from src to this
        !            76: };
        !            77: 
        !            78: struct edit_streambuf : public streambuf {
        !            79:     friend edit_buffer;
        !            80:     edit_string *str;
        !            81:     edit_streambuf* next; // Chain of edit_streambuf's for a edit_buffer.
        !            82:     short _mode;
        !            83:     edit_streambuf(edit_string* bstr, int mode);
        !            84:     ~edit_streambuf();
        !            85:     virtual int underflow();
        !            86:     virtual int overflow(int c = EOF);
        !            87:     virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
        !            88:     void flush_to_buffer();
        !            89:     void flush_to_buffer(edit_buffer* buffer);
        !            90:     int _inserting;
        !            91:     int inserting() { return _inserting; }
        !            92:     void inserting(int i) { _inserting = i; }
        !            93: //    int delete_chars(int count, char* cut_buf); Not implemented.
        !            94:     int truncate();
        !            95:     int is_reading() { return gptr() != NULL; }
        !            96:     buf_char* current() { return is_reading() ? gptr() : pptr(); }
        !            97:     void set_current(char *p, int is_reading);
        !            98:   protected:
        !            99:     void disconnect_gap_from_file(edit_buffer* buffer);
        !           100: };
        !           101: 
        !           102: // A 'edit_mark' indicates a position in a buffer.
        !           103: // It is "attached" the text (rather than the offset).
        !           104: // There are two kinds of mark, which have different behavior
        !           105: // when text is inserted at the mark:
        !           106: // If 'insert_before()' is true the mark will be adjusted to be
        !           107: // *after* the new text.
        !           108: 
        !           109: struct edit_mark {
        !           110:     struct edit_mark *chain;
        !           111:     mark_pointer _pos;
        !           112:     inline int insert_before() { return _pos & 1; }
        !           113:     inline unsigned long index_in_buffer(struct edit_buffer *buffer)
        !           114:        { return _pos >> 1; }
        !           115:     inline buf_char *ptr(struct edit_buffer *buf);
        !           116:     buf_index tell();
        !           117:     edit_mark() { }
        !           118:     edit_mark(struct edit_string *str, long delta);
        !           119:     edit_buffer *buffer();
        !           120:     ~edit_mark();
        !           121: };
        !           122: 
        !           123: // A 'edit_buffer' consists of a sequence of buf_chars (the data),
        !           124: // a list of edit_marks pointing into the data, and a list of FILEs
        !           125: // also pointing into the data.
        !           126: // A 'edit_buffer' coerced to a edit_string is the string of
        !           127: // all the buf_chars in the buffer.
        !           128: 
        !           129: // This implementation uses a conventional buffer gap (as in Emacs).
        !           130: // The gap start is defined by de-referencing a (buf_char**).
        !           131: // This is because sometimes a FILE is inserting into the buffer,
        !           132: // so rather than having each putc adjust the gap, we use indirection
        !           133: // to have the gap be defined as the write pointer of the FILE.
        !           134: // (This assumes that putc adjusts a pointer (as in GNU's libc), not an index.)
        !           135: 
        !           136: struct edit_buffer {
        !           137:     buf_char *data; /* == emacs buffer_text.p1+1 */
        !           138:     buf_char *_gap_start;
        !           139:     edit_streambuf* _writer; // If non-NULL, currently writing stream
        !           140:     inline buf_char *gap_start()
        !           141:        { return _writer ? _writer->pptr() : _gap_start; }
        !           142:     buf_offset __gap_end_pos; // size of part 1 + size of gap
        !           143:     /* int gap; implicit: buf_size - size1 - size2 */
        !           144:     int buf_size;
        !           145:     struct edit_streambuf *files;
        !           146:     struct edit_mark start_mark;
        !           147:     struct edit_mark end_mark;
        !           148:     edit_buffer();
        !           149:     inline buf_offset gap_end_pos() { return __gap_end_pos; }
        !           150:     inline struct edit_mark *start_marker() { return &start_mark; }
        !           151:     inline struct edit_mark *end_marker() { return &end_mark; }
        !           152: /* these should be protected, ultimately */
        !           153:     buf_index tell(edit_mark*);
        !           154:     buf_index tell(buf_char*);
        !           155:     inline buf_char *gap_end() { return data + gap_end_pos(); }
        !           156:     inline int gap_size() { return gap_end() - gap_start(); }
        !           157:     inline int size1() { return gap_start() - data; }
        !           158:     inline int size2() { return buf_size - gap_end_pos(); }
        !           159:     inline struct edit_mark * mark_list() { return &start_mark; }
        !           160:     void make_gap (buf_offset);
        !           161:     void move_gap (buf_offset pos);
        !           162:     void move_gap (buf_char *pos) { move_gap(pos - data); }
        !           163:     void gap_left (int pos);
        !           164:     void gap_right (int pos);
        !           165:     void adjust_markers(mark_pointer low, mark_pointer high,
        !           166:                        int amount, buf_char *old_data);
        !           167:     void delete_range(buf_index from, buf_index to);
        !           168:     void delete_range(struct edit_mark *start, struct edit_mark *end);
        !           169: };
        !           170: 
        !           171: extern buf_char * bstr_copy(struct edit_string *str, int *lenp);
        !           172: 
        !           173: // Convert a edit_mark to a (buf_char*)
        !           174: 
        !           175: inline buf_char *edit_mark::ptr(struct edit_buffer *buf)
        !           176:        { return buf->data + index_in_buffer(buf); }
        !           177: 
        !           178: inline void edit_streambuf::flush_to_buffer()
        !           179: {
        !           180:     edit_buffer* buffer = str->buffer;
        !           181:     if (buffer->_writer == this) flush_to_buffer(buffer);
        !           182: }
        !           183: #endif /* !_EDITBUF_H*/
        !           184: 

unix.superglobalmegacorp.com

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