Skip to content

Commit 7c9e2c2

Browse files
committedSep 12, 2008
buffered input & output
R=r DELTA=812 (803 added, 0 deleted, 9 changed) OCL=15225 CL=15280
1 parent 2273115 commit 7c9e2c2

File tree

5 files changed

+824
-9
lines changed

5 files changed

+824
-9
lines changed
 

‎src/lib/bufio.go

+402
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,402 @@
1+
// Copyright 2009 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package bufio
6+
import "os"
7+
import "io"
8+
9+
10+
// TODO:
11+
// - maybe define an interface
12+
// - BufRead: ReadRune, UnreadRune ?
13+
// could make ReadRune generic if we dropped UnreadRune
14+
// - buffered output
15+
16+
const (
17+
DefaultBufSize = 4096
18+
)
19+
20+
func NewError(s string) *os.Error {
21+
// BUG return &os.Error{s};
22+
e := new(os.Error);
23+
e.s = s;
24+
return e
25+
}
26+
27+
export var (
28+
EndOfFile = NewError("end of file");
29+
PhaseError = NewError("phase error");
30+
BufferFull = NewError("buffer full");
31+
InternalError = NewError("bufio internal error");
32+
BadBufSize = NewError("bad bufio size");
33+
ShortWrite = NewError("short write");
34+
)
35+
36+
func CopySlice(dst *[]byte, src *[]byte) {
37+
for i := 0; i < len(dst); i++ {
38+
dst[i] = src[i]
39+
}
40+
}
41+
42+
43+
// Buffered input.
44+
45+
export type BufRead struct {
46+
err *os.Error;
47+
buf *[]byte;
48+
r, w int;
49+
rd io.Read;
50+
}
51+
52+
export func NewBufReadSize(rd io.Read, size int) (b *BufRead, err *os.Error) {
53+
if size <= 0 {
54+
return nil, BadBufSize
55+
}
56+
b = new(BufRead);
57+
b.buf = new([]byte, size);
58+
b.rd = rd
59+
return b, nil
60+
}
61+
62+
export func NewBufRead(rd io.Read) (b *BufRead, err *os.Error) {
63+
// 6g BUG return NewBufReadSize(rd, DefaultBufSize)
64+
r, e := NewBufReadSize(rd, DefaultBufSize)
65+
return r, e
66+
}
67+
68+
// Read a new chunk into the buffer.
69+
func (b *BufRead) Fill() *os.Error {
70+
if b.err != nil {
71+
return b.err
72+
}
73+
74+
// Slide existing data to beginning.
75+
if b.w > b.r {
76+
CopySlice(b.buf[0:b.w-b.r], b.buf[b.r:b.w]);
77+
b.w -= b.r;
78+
} else {
79+
b.w = 0
80+
}
81+
b.r = 0;
82+
83+
// Read new data.
84+
n, e := b.rd.Read(b.buf[b.w:len(b.buf)])
85+
if e != nil {
86+
b.err = e
87+
return e
88+
}
89+
b.w += n
90+
return nil
91+
}
92+
93+
// Read into p.
94+
// Returns the number of bytes read into p.
95+
// If nn < len(p), also returns an error explaining
96+
// why the read is short.
97+
func (b *BufRead) Read(p *[]byte) (nn int, err *os.Error) {
98+
nn = 0
99+
for len(p) > 0 {
100+
n := len(p)
101+
if b.w == b.r {
102+
b.Fill()
103+
if b.err != nil {
104+
return nn, b.err
105+
}
106+
if b.w == b.r {
107+
return nn, EndOfFile
108+
}
109+
}
110+
if n > b.w - b.r {
111+
n = b.w - b.r
112+
}
113+
CopySlice(p[0:n], b.buf[b.r:b.r+n]);
114+
p = p[n:len(p)];
115+
b.r += n;
116+
nn += n
117+
}
118+
return nn, nil
119+
}
120+
121+
// Read a single byte.
122+
// If no byte available, returns error.
123+
func (b *BufRead) ReadByte() (c byte, err *os.Error) {
124+
if b.w == b.r {
125+
b.Fill()
126+
if b.err != nil {
127+
return 0, b.err
128+
}
129+
if b.w == b.r {
130+
return 0, EndOfFile
131+
}
132+
}
133+
c = b.buf[b.r];
134+
b.r++
135+
return c, nil
136+
}
137+
138+
// Unread the last byte. Only guaranteed to be able to unread one byte.
139+
func (b *BufRead) UnreadByte() *os.Error {
140+
if b.err != nil {
141+
return b.err
142+
}
143+
if b.r <= 0 {
144+
return PhaseError
145+
}
146+
b.r--
147+
return nil
148+
}
149+
150+
// Helper function: look for byte c in array p,
151+
// returning its index or -1.
152+
func FindByte(p *[]byte, c byte) int {
153+
for i := 0; i < len(p); i++ {
154+
if p[i] == c {
155+
return i
156+
}
157+
}
158+
return -1
159+
}
160+
161+
// Returns the number of bytes that can be read.
162+
func (b *BufRead) Buffered() int {
163+
return b.w - b.r;
164+
}
165+
166+
// Read until the first occurrence of delim in the input,
167+
// returning a slice pointing at the bytes in the buffer.
168+
// The bytes stop being valid at the next read call.
169+
// Fails if the line doesn't fit in the buffer.
170+
// For internal (or advanced) use only.
171+
// Use ReadLineString or ReadLineBytes instead.
172+
func (b *BufRead) ReadLineSlice(delim byte) (line *[]byte, err *os.Error) {
173+
if b.err != nil {
174+
return nil, b.err
175+
}
176+
177+
// Look in buffer.
178+
if i := FindByte(b.buf[b.r:b.w], delim); i >= 0 {
179+
line1 := b.buf[b.r:b.r+i+1];
180+
b.r += i+1;
181+
return line1, nil
182+
}
183+
184+
// Read more into buffer, until buffer fills or we find delim.
185+
for {
186+
n := b.Buffered();
187+
b.Fill();
188+
if b.err != nil {
189+
return nil, b.err
190+
}
191+
if b.Buffered() == n { // no data added; end of file
192+
return nil, EndOfFile
193+
}
194+
195+
// Search new part of buffer
196+
if i := FindByte(b.buf[n:b.w], delim); i >= 0 {
197+
line := b.buf[0:n+i+1];
198+
b.r = n+i+1
199+
return line, nil
200+
}
201+
202+
// Buffer is full?
203+
if b.Buffered() >= len(b.buf) {
204+
return nil, BufferFull
205+
}
206+
}
207+
208+
// BUG 6g bug100
209+
return nil, nil
210+
}
211+
212+
// Read until the first occurrence of delim in the input,
213+
// returning a new byte array containing the line.
214+
// If an error happens, returns the data (without a delimiter)
215+
// and the error. (Can't leave the data in the buffer because
216+
// we might have read more than the buffer size.)
217+
func (b *BufRead) ReadLineBytes(delim byte) (line *[]byte, err *os.Error) {
218+
if b.err != nil {
219+
return nil, b.err
220+
}
221+
222+
// Use ReadLineSlice to look for array,
223+
// accumulating full buffers.
224+
var frag *[]byte;
225+
var full *[]*[]byte;
226+
nfull := 0;
227+
err = nil;
228+
229+
for {
230+
var e *os.Error;
231+
frag, e = b.ReadLineSlice(delim);
232+
if e == nil { // got final fragment
233+
break
234+
}
235+
if e != BufferFull { // unexpected error
236+
err = e;
237+
break
238+
}
239+
240+
// Read bytes out of buffer.
241+
buf := new([]byte, b.Buffered());
242+
var n int;
243+
n, e = b.Read(buf);
244+
if e != nil {
245+
frag = buf[0:n];
246+
err = e
247+
break
248+
}
249+
if n != len(buf) {
250+
frag = buf[0:n];
251+
err = InternalError
252+
break
253+
}
254+
255+
// Grow list if needed.
256+
if full == nil {
257+
full = new([]*[]byte, 16);
258+
} else if nfull >= len(full) {
259+
newfull := new([]*[]byte, len(full)*2);
260+
// BUG slice assignment
261+
for i := 0; i < len(full); i++ {
262+
newfull[i] = full[i];
263+
}
264+
full = newfull
265+
}
266+
267+
// Save buffer
268+
full[nfull] = buf;
269+
nfull++
270+
}
271+
272+
// Allocate new buffer to hold the full pieces and the fragment.
273+
n := 0
274+
for i := 0; i < nfull; i++ {
275+
n += len(full[i])
276+
}
277+
if frag != nil {
278+
n += len(frag);
279+
}
280+
281+
// Copy full pieces and fragment in.
282+
buf := new([]byte, n);
283+
n = 0
284+
for i := 0; i < nfull; i++ {
285+
CopySlice(buf[n:n+len(full[i])], full[i]);
286+
n += len(full[i])
287+
}
288+
if frag != nil {
289+
CopySlice(buf[n:n+len(frag)], frag)
290+
}
291+
return buf, err
292+
}
293+
294+
// Read until the first occurrence of delim in the input,
295+
// returning a new string containing the line.
296+
// If savedelim, keep delim in the result; otherwise chop it off.
297+
func (b *BufRead) ReadLineString(delim byte, savedelim bool) (line string, err *os.Error) {
298+
bytes, e := b.ReadLineBytes(delim)
299+
if e != nil {
300+
return string(bytes), e
301+
}
302+
if !savedelim {
303+
bytes = bytes[0:len(bytes)-1]
304+
}
305+
return string(bytes), nil
306+
}
307+
308+
309+
// buffered output
310+
311+
export type BufWrite struct {
312+
err *os.Error;
313+
buf *[]byte;
314+
n int;
315+
wr io.Write;
316+
}
317+
318+
export func NewBufWriteSize(wr io.Write, size int) (b *BufWrite, err *os.Error) {
319+
if size <= 0 {
320+
return nil, BadBufSize
321+
}
322+
b = new(BufWrite);
323+
b.buf = new([]byte, size);
324+
b.wr = wr
325+
return b, nil
326+
}
327+
328+
export func NewBufWrite(wr io.Write) (b *BufWrite, err *os.Error) {
329+
// 6g BUG return NewBufWriteSize(wr, DefaultBufSize)
330+
r, e := NewBufWriteSize(wr, DefaultBufSize)
331+
return r, e
332+
}
333+
334+
// Flush the output buffer.
335+
func (b *BufWrite) Flush() *os.Error {
336+
if b.err != nil {
337+
return b.err
338+
}
339+
n := 0
340+
for n < b.n {
341+
m, e := b.wr.Write(b.buf[n:b.n]);
342+
n += m
343+
if m == 0 && e == nil {
344+
e = ShortWrite
345+
}
346+
if e != nil {
347+
if n < b.n {
348+
CopySlice(b.buf[0:b.n-n], b.buf[n:b.n])
349+
}
350+
b.n -= n;
351+
b.err = e
352+
return e
353+
}
354+
}
355+
b.n = 0
356+
return nil
357+
}
358+
359+
func (b *BufWrite) Available() int {
360+
return len(b.buf) - b.n
361+
}
362+
363+
func (b *BufWrite) Buffered() int {
364+
return b.n
365+
}
366+
367+
func (b *BufWrite) Write(p *[]byte) (nn int, err *os.Error) {
368+
if b.err != nil {
369+
return 0, b.err
370+
}
371+
nn = 0
372+
for len(p) > 0 {
373+
n := b.Available()
374+
if n <= 0 {
375+
if b.Flush(); b.err != nil {
376+
break
377+
}
378+
n = b.Available()
379+
}
380+
if n > len(p) {
381+
n = len(p)
382+
}
383+
CopySlice(b.buf[b.n:b.n+n], p[0:n]);
384+
b.n += n;
385+
nn += n;
386+
p = p[n:len(p)]
387+
}
388+
return nn, b.err
389+
}
390+
391+
func (b *BufWrite) WriteByte(c byte) *os.Error {
392+
if b.err != nil {
393+
return b.err
394+
}
395+
if b.Available() <= 0 && b.Flush() != nil {
396+
return b.err
397+
}
398+
b.buf[b.n] = c;
399+
b.n++
400+
return nil
401+
}
402+

‎src/lib/io.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright 2009 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package io
6+
import os "os"
7+
8+
export func StringToBytes(b *[]byte, s string) bool {
9+
if len(s) >= len(b) {
10+
return false
11+
}
12+
for i := 0; i < len(s); i++ {
13+
b[i] = s[i]
14+
}
15+
b[len(s)] = '\000'; // not necessary - memory is zeroed - but be explicit
16+
return true
17+
}
18+
19+
export type Read interface {
20+
Read(p *[]byte) (n int, err *os.Error);
21+
}
22+
23+
export type Write interface {
24+
Write(p *[]byte) (n int, err *os.Error);
25+
}
26+
27+
export func WriteString(w Write, s string) (n int, err *os.Error) {
28+
b := new([]byte, len(s)+1)
29+
if !StringToBytes(b, s) {
30+
return -1, os.EINVAL
31+
}
32+
// BUG return w.Write(b[0:len(s)])
33+
r, e := w.Write(b[0:len(s)])
34+
return r, e
35+
}
36+

‎src/lib/make.bash

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ do
1515
done
1616

1717
rm -f *.6
18-
for i in fmt.go flag.go container/vector.go rand.go sort.go strings.go
18+
for i in fmt.go flag.go container/vector.go rand.go sort.go io.go bufio.go strings.go
1919
do
2020
base=$(basename $i .go)
2121
echo 6g -o $GOROOT/pkg/$base.6 $i

‎src/lib/os/os_file.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ export const (
4141
O_TRUNC = syscall.O_TRUNC;
4242
)
4343

44-
export func Open(name string, mode int64, flags int64) (fd *FD, err *Error) {
45-
r, e := syscall.open(name, mode, flags);
44+
export func Open(name string, mode int, flags int) (fd *FD, err *Error) {
45+
r, e := syscall.open(name, int64(mode), int64(flags));
4646
return NewFD(r), ErrnoToError(e)
4747
}
4848

@@ -55,23 +55,23 @@ func (fd *FD) Close() *Error {
5555
return ErrnoToError(e)
5656
}
5757

58-
func (fd *FD) Read(b *[]byte) (ret int64, err *Error) {
58+
func (fd *FD) Read(b *[]byte) (ret int, err *Error) {
5959
if fd == nil {
6060
return -1, EINVAL
6161
}
6262
r, e := syscall.read(fd.fd, &b[0], int64(len(b)));
63-
return r, ErrnoToError(e)
63+
return int(r), ErrnoToError(e)
6464
}
6565

66-
func (fd *FD) Write(b *[]byte) (ret int64, err *Error) {
66+
func (fd *FD) Write(b *[]byte) (ret int, err *Error) {
6767
if fd == nil {
6868
return -1, EINVAL
6969
}
7070
r, e := syscall.write(fd.fd, &b[0], int64(len(b)));
71-
return r, ErrnoToError(e)
71+
return int(r), ErrnoToError(e)
7272
}
7373

74-
func (fd *FD) WriteString(s string) (ret int64, err *Error) {
74+
func (fd *FD) WriteString(s string) (ret int, err *Error) {
7575
if fd == nil {
7676
return -1, EINVAL
7777
}
@@ -80,5 +80,5 @@ func (fd *FD) WriteString(s string) (ret int64, err *Error) {
8080
return -1, EINVAL
8181
}
8282
r, e := syscall.write(fd.fd, &b[0], int64(len(s)));
83-
return r, ErrnoToError(e)
83+
return int(r), ErrnoToError(e)
8484
}

‎test/bufiolib.go

+377
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,377 @@
1+
// Copyright 2009 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// $G $F.go && $L $F.$A && ./$A.out
6+
7+
package main
8+
9+
import (
10+
"os";
11+
"io";
12+
"bufio";
13+
"syscall";
14+
"rand"
15+
)
16+
17+
func StringToBytes(s string) *[]byte {
18+
b := new([]byte, len(s));
19+
for i := 0; i < len(s); i++ {
20+
b[i] = s[i]
21+
}
22+
return b
23+
}
24+
25+
// Should be in language!
26+
func Copy(p *[]byte, q *[]byte) {
27+
for i := 0; i < len(p); i++ {
28+
p[i] = q[i]
29+
}
30+
}
31+
32+
// Reads from p.
33+
type ByteReader struct {
34+
p *[]byte
35+
}
36+
37+
func NewByteReader(p *[]byte) io.Read {
38+
b := new(ByteReader);
39+
b.p = p
40+
return b
41+
}
42+
43+
func (b *ByteReader) Read(p *[]byte) (int, *os.Error) {
44+
n := len(p)
45+
if n > len(b.p) {
46+
n = len(b.p)
47+
}
48+
Copy(p[0:n], b.p[0:n]);
49+
b.p = b.p[n:len(b.p)]
50+
return n, nil
51+
}
52+
53+
54+
// Reads from p but only returns half of what you asked for.
55+
type HalfByteReader struct {
56+
p *[]byte
57+
}
58+
59+
func NewHalfByteReader(p *[]byte) io.Read {
60+
b := new(HalfByteReader);
61+
b.p = p
62+
return b
63+
}
64+
65+
func (b *HalfByteReader) Read(p *[]byte) (int, *os.Error) {
66+
n := len(p)/2
67+
if n == 0 && len(p) > 0 {
68+
n = 1
69+
}
70+
if n > len(b.p) {
71+
n = len(b.p)
72+
}
73+
Copy(p[0:n], b.p[0:n]);
74+
b.p = b.p[n:len(b.p)]
75+
return n, nil
76+
}
77+
78+
// Reads from a reader and rot13s the result.
79+
type Rot13Reader struct {
80+
r io.Read
81+
}
82+
83+
func NewRot13Reader(r io.Read) *Rot13Reader {
84+
r13 := new(Rot13Reader);
85+
r13.r = r
86+
return r13
87+
}
88+
89+
func (r13 *Rot13Reader) Read(p *[]byte) (int, *os.Error) {
90+
n, e := r13.r.Read(p)
91+
if e != nil {
92+
return n, e
93+
}
94+
for i := 0; i < n; i++ {
95+
if 'a' <= p[i] && p[i] <= 'z' || 'A' <= p[i] && p[i] <= 'Z' {
96+
if 'a' <= p[i] && p[i] <= 'm' || 'A' <= p[i] && p[i] <= 'M' {
97+
p[i] += 13;
98+
} else {
99+
p[i] -= 13;
100+
}
101+
}
102+
}
103+
return n, nil
104+
}
105+
106+
func MakeByteReader(p *[]byte) io.Read {
107+
return NewByteReader(p)
108+
}
109+
func MakeHalfByteReader(p *[]byte) io.Read {
110+
return NewHalfByteReader(p)
111+
}
112+
113+
var readmakers = []*(p *[]byte) io.Read {
114+
&NewByteReader,
115+
&NewHalfByteReader
116+
}
117+
118+
119+
// Call ReadLineString (which ends up calling everything else)
120+
// to accumulate the text of a file.
121+
func ReadLines(b *bufio.BufRead) string {
122+
s := ""
123+
for {
124+
s1, e := b.ReadLineString('\n', false)
125+
if e == bufio.EndOfFile {
126+
break
127+
}
128+
if e != nil {
129+
panic("GetLines: "+e.String())
130+
}
131+
s += s1
132+
}
133+
return s
134+
}
135+
136+
// Call ReadByte to accumulate the text of a file
137+
func ReadBytes(buf *bufio.BufRead) string {
138+
var b [1000]byte;
139+
nb := 0
140+
for {
141+
c, e := buf.ReadByte()
142+
if e == bufio.EndOfFile {
143+
break
144+
}
145+
if e != nil {
146+
panic("GetBytes: "+e.String())
147+
}
148+
b[nb] = c;
149+
nb++
150+
}
151+
// BUG return string(b[0:nb]) ?
152+
return string(b)[0:nb]
153+
}
154+
155+
// Call Read to accumulate the text of a file
156+
func Reads(buf *bufio.BufRead, m int) string {
157+
var b [1000]byte;
158+
nb := 0
159+
for {
160+
// BUG parens around (&b) should not be needed
161+
n, e := buf.Read((&b)[nb:nb+m]);
162+
nb += n
163+
if e == bufio.EndOfFile {
164+
break
165+
}
166+
}
167+
// BUG 6g bug102 - out of bounds error on empty byte array -> string
168+
if nb == 0 { return "" }
169+
return string((&b)[0:nb])
170+
}
171+
172+
func Read1(b *bufio.BufRead) string { return Reads(b, 1) }
173+
func Read2(b *bufio.BufRead) string { return Reads(b, 2) }
174+
func Read3(b *bufio.BufRead) string { return Reads(b, 3) }
175+
func Read4(b *bufio.BufRead) string { return Reads(b, 4) }
176+
func Read5(b *bufio.BufRead) string { return Reads(b, 5) }
177+
func Read7(b *bufio.BufRead) string { return Reads(b, 7) }
178+
179+
var bufreaders = []*(b *bufio.BufRead) string {
180+
&Read1, &Read2, &Read3, &Read4, &Read5, &Read7,
181+
&ReadBytes, &ReadLines
182+
}
183+
184+
var bufsizes = []int {
185+
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
186+
23, 32, 46, 64, 93, 128, 1024, 4096
187+
}
188+
189+
func TestBufRead() {
190+
// work around 6g bug101
191+
readmakers[0] = &NewByteReader;
192+
readmakers[1] = &NewHalfByteReader;
193+
194+
bufreaders[0] = &Read1;
195+
bufreaders[1] = &Read2;
196+
bufreaders[2] = &Read3;
197+
bufreaders[3] = &Read4;
198+
bufreaders[4] = &Read5;
199+
bufreaders[5] = &Read7;
200+
bufreaders[6] = &ReadBytes;
201+
bufreaders[7] = &ReadLines;
202+
203+
bufsizes[0] = 1;
204+
bufsizes[1] = 2;
205+
bufsizes[2] = 3;
206+
bufsizes[3] = 4;
207+
bufsizes[4] = 5;
208+
bufsizes[5] = 6;
209+
bufsizes[6] = 7;
210+
bufsizes[7] = 8;
211+
bufsizes[8] = 9;
212+
bufsizes[9] = 10;
213+
bufsizes[10] = 23;
214+
bufsizes[11] = 32;
215+
bufsizes[12] = 46;
216+
bufsizes[13] = 64;
217+
bufsizes[14] = 93;
218+
bufsizes[15] = 128;
219+
bufsizes[16] = 1024;
220+
bufsizes[17] = 4096;
221+
222+
var texts [31]string
223+
str := "";
224+
all := ""
225+
for i := 0; i < len(texts)-1; i++ {
226+
texts[i] = str + "\n";
227+
all += texts[i];
228+
str += string(i%26+'a')
229+
}
230+
texts[len(texts)-1] = all;
231+
232+
// BUG 6g should not need nbr temporary (bug099)
233+
nbr := NewByteReader(StringToBytes("hello world"));
234+
b, e := bufio.NewBufRead(nbr);
235+
if ReadBytes(b) != "hello world" { panic("hello world") }
236+
237+
// BUG 6g should not need nbr nor nbr1 (bug009)
238+
nbr = NewByteReader(StringToBytes("hello world"));
239+
nbr1 := NewRot13Reader(nbr);
240+
b, e = bufio.NewBufRead(nbr1);
241+
if ReadBytes(b) != "uryyb jbeyq" { panic("hello world") }
242+
243+
for h := 0; h < len(texts); h++ {
244+
text := texts[h];
245+
textbytes := StringToBytes(text)
246+
for i := 0; i < len(readmakers); i++ {
247+
readmaker := readmakers[i]
248+
for j := 0; j < len(bufreaders); j++ {
249+
bufreader := bufreaders[j]
250+
for k := 0; k < len(bufsizes); k++ {
251+
bufsize := bufsizes[k];
252+
read := readmaker(textbytes);
253+
buf, e := bufio.NewBufReadSize(read, bufsize);
254+
s := bufreader(buf);
255+
if s != text {
256+
print("Failed: ", h, " ", i, " ", j, " ", k, " ", len(s), " ", len(text), "\n");
257+
print("<", s, ">\nshould be <", text, ">\n");
258+
panic("bufio result")
259+
}
260+
}
261+
}
262+
}
263+
}
264+
}
265+
266+
267+
type WriteBuffer interface {
268+
Write(p *[]byte) (int, *os.Error);
269+
GetBytes() *[]byte
270+
}
271+
272+
// Accumulates bytes into a byte array.
273+
type ByteWriter struct {
274+
p *[]byte;
275+
n int
276+
}
277+
278+
func NewByteWriter() WriteBuffer {
279+
return new(ByteWriter)
280+
}
281+
282+
func (w *ByteWriter) Write(p *[]byte) (int, *os.Error) {
283+
if w.p == nil {
284+
w.p = new([]byte, len(p)+100)
285+
} else if w.n + len(p) >= len(w.p) {
286+
newp := new([]byte, len(w.p)*2 + len(p));
287+
Copy(newp[0:w.n], w.p[0:w.n]);
288+
w.p = newp
289+
}
290+
Copy(w.p[w.n:w.n+len(p)], p);
291+
w.n += len(p)
292+
return len(p), nil
293+
}
294+
295+
func (w *ByteWriter) GetBytes() *[]byte {
296+
return w.p[0:w.n]
297+
}
298+
299+
// Accumulates bytes written into a byte array
300+
// but Write only takes half of what you give it.
301+
type HalfByteWriter struct {
302+
bw WriteBuffer
303+
}
304+
305+
func NewHalfByteWriter() WriteBuffer {
306+
w := new(HalfByteWriter);
307+
w.bw = NewByteWriter()
308+
return w
309+
}
310+
311+
func (w *HalfByteWriter) Write(p *[]byte) (int, *os.Error) {
312+
n := (len(p)+1) / 2;
313+
// BUG return w.bw.Write(p[0:n])
314+
r, e := w.bw.Write(p[0:n])
315+
return r, e
316+
}
317+
318+
func (w *HalfByteWriter) GetBytes() *[]byte {
319+
return w.bw.GetBytes()
320+
}
321+
322+
func TestBufWrite() {
323+
var data [8192]byte
324+
325+
var writers [2]*()WriteBuffer;
326+
writers[0] = &NewByteWriter;
327+
writers[1] = &NewHalfByteWriter;
328+
329+
for i := 0; i < len(data); i++ {
330+
data[i] = byte(rand.rand())
331+
}
332+
for i := 0; i < len(bufsizes); i++ {
333+
for j := 0; j < len(bufsizes); j++ {
334+
for k := 0; k < len(writers); k++ {
335+
nwrite := bufsizes[i];
336+
bs := bufsizes[j];
337+
338+
// Write nwrite bytes using buffer size bs.
339+
// Check that the right amount makes it out
340+
// and that the data is correct.
341+
342+
write := writers[k]();
343+
buf, e := bufio.NewBufWriteSize(write, bs);
344+
if e != nil {
345+
panic("NewBufWriteSize error: "+e.String())
346+
}
347+
n, e1 := buf.Write((&data)[0:nwrite])
348+
if e1 != nil {
349+
panic("buf.Write error "+e1.String())
350+
}
351+
if n != nwrite {
352+
panic("buf.Write wrong count")
353+
}
354+
e = buf.Flush()
355+
if e != nil {
356+
panic("buf.Flush error "+e.String())
357+
}
358+
359+
written := write.GetBytes();
360+
if len(written) != nwrite {
361+
panic("wrong amount written")
362+
}
363+
for l := 0; l < len(written); l++ {
364+
if written[i] != data[i] {
365+
panic("wrong bytes written")
366+
}
367+
}
368+
}
369+
}
370+
}
371+
}
372+
373+
374+
func main() {
375+
TestBufRead();
376+
TestBufWrite()
377+
}

0 commit comments

Comments
 (0)
Please sign in to comment.