Revert "Revert "Made use of ::= in core libraries and defined a RebindError condition...
[cslatevm.git] / src / lib / buffer.slate
blob95414025e179989085fa98d068e1bd010272efe2
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
4 the memory-manager."
6 b@(BufferStream traits) on: s
8   b stream := s.
9   b buffer := b buffer newSameSize.
10   b
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."
18 [| b |
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].
23   b clear.
24   s stream flush.
25   s
28 s@(WriteBufferStream traits) nextPut: obj
30   s buffer isFull ifTrue: [s flush].
31   s buffer addLast: obj
34 s@(WriteBufferStream traits) nextPutAll: seq
36   s buffer gapSize < seq size ifFalse: [s flush].
37   s buffer isSplit
38     ifTrue:
39       [seq doWithIndex:
40          [| :each :index |
41           s contents at: s buffer firstIndex + index := each].
42        s firstIndex := s buffer firstIndex + seq size]
43     ifFalse:
44       [| dstIndex |
45        dstIndex := s lastIndex.
46        0 below: seq size do:
47          [| :each |
48           dstIndex := dstIndex = s contents size
49             ifTrue: [0]
50             ifFalse: [dstIndex + 1].
51           s contents at: dstIndex := each].
52        s lastIndex := dstIndex].
53   seq
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."
67 [| b |
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].
72   s
75 s@(ReadBufferStream traits) next
77   s buffer isEmpty
78     ifTrue: 
79       [s buffer firstIndex := 0. 
80        s buffer lastIndex := s stream next: s buffer capacity putInto: s buffer contents].
81   s buffer removeFirst
84 s@(ReadBufferStream traits) peek
86   s buffer isEmpty
87     ifTrue: [s buffer addFirst: s next]
88     ifFalse: [s buffer first]
91 s@(ReadBufferStream traits) next: n putInto: seq@(Sequence traits)
92 [| b oldSize |
93   oldSize := (b := s buffer) size.
94   n > oldSize
95     ifTrue:
96       [b doWithIndex:
97          [| :each :index | seq at: index := each].
98        b clear.
99        s stream next: b capacity putInto: b.
100        oldSize below: seq size do:
101          [| :index | seq at: index := b removeFirst]]
102     ifFalse:
103       [0 below: n do: [| :index | seq at: index := b removeFirst]].
104   seq size
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].