source: branches/1.4.0/src/org/armedbear/lisp/SeekableStringWriter.java

Last change on this file was 14857, checked in by Mark Evenson, 9 years ago

[PATCH 5/5] Support FILE-POSITION on string streams.
From cb667c106187443ff2d00bace14f0ee0686fe2fd Mon Sep 17 00:00:00 2001
Adds a custom, seekable writer to be able to go back in the written
output for STRING-OUTPUT-STREAM - the input case is slightly less
complex.
---

build.xml | 1 +
src/org/armedbear/lisp/SeekableStringWriter.java | 140 +++++++++++++++++++++
src/org/armedbear/lisp/StringInputStream.java | 43 ++++++-
src/org/armedbear/lisp/StringOutputStream.java | 35 +++++-
test/lisp/abcl/misc-tests.lisp | 11 +-
.../armedbear/lisp/SeekableStringWriterTest.java | 19 +++
6 files changed, 242 insertions(+), 7 deletions(-)
create mode 100644 src/org/armedbear/lisp/SeekableStringWriter.java
create mode 100644 test/src/org/armedbear/lisp/SeekableStringWriterTest.java

File size: 4.0 KB
Line 
1/*
2 * SeekableStringWriter.java
3 *
4 * Copyright (C) 2016 Olof-Joachim Frahm
5 * $Id$
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36import static org.armedbear.lisp.Lisp.*;
37
38import java.io.Writer;
39
40public final class SeekableStringWriter extends Writer {
41    private final StringBuffer stringBuffer;
42    private int offset = 0;
43
44    public SeekableStringWriter() {
45        stringBuffer = new StringBuffer();
46    }
47
48    public SeekableStringWriter(int initialSize) {
49        stringBuffer = new StringBuffer(initialSize);
50    }
51
52    public SeekableStringWriter append(char c) {
53        write(c);
54        return this;
55    }
56
57    public SeekableStringWriter append(CharSequence csq) {
58        write(csq.toString());
59        return this;
60    }
61
62    public SeekableStringWriter append(CharSequence csq, int start, int end) {
63        write(csq.subSequence(start, end).toString());
64        return this;
65    }
66
67    @Override
68    public void write(char[] cbuf) {
69        _write(cbuf, 0, cbuf.length);
70    }
71
72    @Override
73    public void write(char[] cbuf, int off, int len) {
74        int bufLen = cbuf.length;
75
76        if (off < 0 || off > bufLen || len < 0 || off + len > bufLen)
77            throw new IllegalArgumentException();
78
79        _write(cbuf, off, len);
80    }
81
82    @Override
83    public void write(int c) {
84        if (offset == stringBuffer.length())
85            stringBuffer.append((char) c);
86        else
87            stringBuffer.setCharAt(offset, (char) c);
88        ++offset;
89    }
90
91    @Override
92    public void write(String str) {
93        write(str, 0, str.length());
94    }
95
96    @Override
97    public void write(String str, int off, int len) {
98        write(str.toCharArray(), off, len);
99    }
100
101    private void _write(char[] cbuf, int off, int len) {
102        int strLen = stringBuffer.length();
103        int space = strLen - offset;
104
105        int written = Math.min(len, space);
106
107        if (written > 0)
108            stringBuffer.replace(offset, offset + written, new String(cbuf, off, written));
109
110        if (written < len)
111            stringBuffer.append(cbuf, off + written, len - written);
112
113        offset += len;
114    }
115
116    public void seek(int offset) {
117        if (offset < 0 || offset > stringBuffer.length())
118            throw new IllegalArgumentException();
119        this.offset = offset;
120    }
121
122    public StringBuffer getBuffer() {
123        return stringBuffer;
124    }
125
126    public int getOffset() {
127        return offset;
128    }
129
130    @Override
131    public String toString() {
132        return stringBuffer.toString();
133    }
134
135    @Override
136    public void close() {}
137
138    @Override
139    public void flush() {}
140}
Note: See TracBrowser for help on using the repository browser.