1 define: #BufferStream &parents: {Stream} &slots: {#stream -> Stream clone. #buffer -> RingBuffer new}.
2 "A BufferStream is a Stream with a buffer array resizable up to a fixed amount,
3 with wrap-around semantics to reduce heavy i/o interaction and avoid stressing
6 b@(BufferStream traits) on: s
9 b buffer := b buffer newSameSize.
13 define: #WriteBufferStream &parents: {BufferStream. WriteStream}.
14 "A BufferStream with semantics for writing."
16 s@(WriteBufferStream traits) flush
17 "Empty the buffer into the stream all at once."
19 (b := s buffer) isSplit
20 ifTrue: [s nextPutAll: b from: b firstIndex to: b size - 1.
21 s nextPutAll: b from: 0 to: b lastIndex]
22 ifFalse: [s nextPutAll: b from: b firstIndex to: b lastIndex].
28 s@(WriteBufferStream traits) nextPut: obj
30 s buffer isFull ifTrue: [s flush].
34 s@(WriteBufferStream traits) nextPutAll: seq
36 s buffer gapSize < seq size ifFalse: [s flush].
41 s contents at: s buffer firstIndex + index := each].
42 s firstIndex := s buffer firstIndex + seq size]
45 dstIndex := s lastIndex.
48 dstIndex := dstIndex = s contents size
50 ifFalse: [dstIndex + 1].
51 s contents at: dstIndex := each].
52 s lastIndex := dstIndex].
56 s@(WriteBufferStream traits) nextPutAll: seq from: start to: end
57 "Overridden to use the optimized BufferStream method nextPutAll:."
59 s nextPutAll: (seq sliceFrom: start to: end)
62 define: #ReadBufferStream &parents: {BufferStream. ReadStream}.
63 "A BufferStream designed to be read from."
65 s@(ReadBufferStream traits) flush
66 "Fill the buffer from the stream all at once."
68 (b := s buffer) isSplit
69 ifTrue: [s stream next: b gapSize putInto: b]
70 ifFalse: [s stream next: b capacity - b lastIndex putInto: b.
71 s stream next: b firstIndex putInto: b].
75 s@(ReadBufferStream traits) next
79 [s buffer firstIndex := 0.
80 s buffer lastIndex := s stream next: s buffer capacity putInto: s buffer contents].
84 s@(ReadBufferStream traits) peek
87 ifTrue: [s buffer addFirst: s next]
88 ifFalse: [s buffer first]
91 s@(ReadBufferStream traits) next: n putInto: seq@(Sequence traits)
93 oldSize := (b := s buffer) size.
97 [| :each :index | seq at: index := each].
99 s stream next: b capacity putInto: b.
100 oldSize below: seq size do:
101 [| :index | seq at: index := b removeFirst]]
103 [0 below: n do: [| :index | seq at: index := b removeFirst]].
107 s@(ReadBufferStream traits) isAtEnd
109 s buffer isEmpty /\ s stream isAtEnd
112 define: #ReadWriteBufferStream &slots: {}.
113 "This is a rough concept to implement that requires basically two
114 BufferStreams and coordination between them."
115 "TODO: Implement something workable."
117 "Return new BufferStreams of the appropriate type wrapping their arguments."
119 s@(ReadStream traits) buffered [ReadBufferStream newOn: s].
120 s@(Stream traits) readBuffered [ReadBufferStream newOn: s].
122 s@(WriteStream traits) buffered [WriteBufferStream newOn: s].
123 s@(Stream traits) writeBuffered [WriteBufferStream newOn: s].