author | Claus Gittinger <cg@exept.de> |
Mon, 15 Jul 2019 15:39:26 +0200 | |
changeset 5054 | b01df68cba0a |
parent 4326 | 5aca213f1a71 |
child 5141 | 046c31b9f275 |
permissions | -rw-r--r-- |
4326 | 1 |
" |
2 |
COPYRIGHT (c) 2002 by Claus Gittinger |
|
3 |
All Rights Reserved |
|
4 |
||
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
1015 | 12 |
"{ Package: 'stx:libbasic2' }" |
13 |
||
3978 | 14 |
"{ NameSpace: Smalltalk }" |
15 |
||
1015 | 16 |
Stream subclass:#InternalPipeStream |
3978 | 17 |
instanceVariableNames:'queue closed contentsSpecies' |
1015 | 18 |
classVariableNames:'' |
19 |
poolDictionaries:'' |
|
20 |
category:'Streams' |
|
21 |
! |
|
22 |
||
1016 | 23 |
!InternalPipeStream class methodsFor:'documentation'! |
24 |
||
4326 | 25 |
copyright |
26 |
" |
|
27 |
COPYRIGHT (c) 2002 by Claus Gittinger |
|
28 |
All Rights Reserved |
|
29 |
||
30 |
This software is furnished under a license and may be used |
|
31 |
only in accordance with the terms of that license and with the |
|
32 |
inclusion of the above copyright notice. This software may not |
|
33 |
be provided or otherwise made available to, or used by, any |
|
34 |
other person. No title to or ownership of the software is |
|
35 |
hereby transferred. |
|
36 |
" |
|
37 |
! |
|
38 |
||
1016 | 39 |
documentation |
40 |
" |
|
41 |
not useful on its own, but can be used to talk to a vt100 |
|
42 |
terminal view ... |
|
3978 | 43 |
|
1016 | 44 |
See example. |
45 |
" |
|
46 |
! |
|
47 |
||
48 |
examples |
|
49 |
" |
|
50 |
[exBegin] |
|
51 |
|p| |
|
52 |
||
53 |
p := InternalPipeStream new. |
|
54 |
[ |
|
55 |
10 timesRepeat:[ |
|
56 |
p nextPutLine:'hello' |
|
57 |
]. |
|
58 |
] fork. |
|
59 |
||
60 |
[ |
|
61 |
10 timesRepeat:[ |
|
62 |
Transcript showCR:p nextLine |
|
63 |
]. |
|
64 |
] fork. |
|
65 |
[exEnd] |
|
66 |
||
67 |
[exBegin] |
|
3291
facd0cfd0781
Fixed examples (added missing vars, dot at the end of statement)
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
3128
diff
changeset
|
68 |
|userInput elizasOutput top terminal| |
1016 | 69 |
|
70 |
userInput := InternalPipeStream new. |
|
71 |
elizasOutput := InternalPipeStream new. |
|
72 |
||
73 |
top := StandardSystemView new. |
|
74 |
terminal := VT100TerminalView openOnInput: userInput output:elizasOutput in:top. |
|
75 |
||
76 |
top extent:(terminal preferredExtent). |
|
77 |
top label:'The doctor is in'. |
|
78 |
top iconLabel:'doctor'. |
|
79 |
top open. |
|
80 |
top waitUntilVisible. |
|
3978 | 81 |
top onChangeEvaluate:[:what :aParameter :changedObject | what == #destroyed ifTrue:[userInput close]]. |
1016 | 82 |
|
83 |
terminal translateNLToCRNL:true. |
|
84 |
terminal inputTranslateCRToNL:true. |
|
85 |
terminal localEcho:true. |
|
86 |
||
87 |
elizasOutput nextPutLine:'Hi, I am Eliza'. |
|
3978 | 88 |
elizasOutput nextPutLine:'What is your problem (type end to finish conversation) ?'. |
1016 | 89 |
elizasOutput nextPutLine:''. |
90 |
elizasOutput nextPutAll:'>'. |
|
91 |
||
92 |
[top realized] whileTrue:[ |
|
93 |
|line answer matchingRule| |
|
94 |
||
95 |
line := userInput nextLine. |
|
3978 | 96 |
((line isEmptyOrNil and:[userInput atEnd]) or:[ #('quit' 'exit' 'end' 'bye') includes:line ]) ifTrue:[ |
1016 | 97 |
top destroy. |
98 |
^ self |
|
99 |
]. |
|
100 |
||
3291
facd0cfd0781
Fixed examples (added missing vars, dot at the end of statement)
Jan Vrany <jan.vrany@fit.cvut.cz>
parents:
3128
diff
changeset
|
101 |
answer := 'Tell me more.'. |
1016 | 102 |
elizasOutput nextPutLine:answer. |
103 |
elizasOutput nextPutAll:'>'. |
|
104 |
]. |
|
105 |
[exEnd] |
|
106 |
" |
|
107 |
! ! |
|
1015 | 108 |
|
109 |
!InternalPipeStream class methodsFor:'instance creation'! |
|
110 |
||
111 |
new |
|
112 |
^ self basicNew initialize |
|
113 |
! ! |
|
114 |
||
115 |
!InternalPipeStream methodsFor:'accessing'! |
|
116 |
||
117 |
atEnd |
|
3978 | 118 |
^ closed and:[queue isEmpty] |
1015 | 119 |
! |
120 |
||
121 |
close |
|
3978 | 122 |
"if there is any partner waiting at either side of the queue, |
123 |
tell it that the pipe is no longer active. |
|
124 |
(readers will read an EOF condition, writers will get a write error). |
|
125 |
Either side may close the internal pipe." |
|
126 |
||
127 |
closed := true. |
|
128 |
queue readSemaphore signalForAll |
|
129 |
! |
|
130 |
||
131 |
isOpen |
|
132 |
^ closed not |
|
1015 | 133 |
! |
134 |
||
135 |
next |
|
136 |
"return the next element from the stream (might block until something is written)" |
|
137 |
||
3978 | 138 |
(closed and:[queue isEmpty]) ifTrue:[^ self pastEndRead]. |
1015 | 139 |
^ queue next |
140 |
! |
|
141 |
||
142 |
nextAvailableBytes:nMax into:aBuffer startingAt:startIndex |
|
143 |
|n idx ch| |
|
144 |
||
3978 | 145 |
(closed and:[queue isEmpty and:[self pastEndRead isNil]]) ifTrue:[^ 0]. |
146 |
||
1015 | 147 |
n := 0. |
148 |
idx := startIndex. |
|
149 |
[n <= nMax] whileTrue:[ |
|
150 |
ch := queue nextIfEmpty:[^ n ]. |
|
151 |
aBuffer at:idx put:ch. |
|
152 |
idx := idx + 1. |
|
153 |
n := n + 1 |
|
154 |
]. |
|
155 |
^ n |
|
156 |
! |
|
157 |
||
3978 | 158 |
nextPut:anObject |
1015 | 159 |
"write an element (might wakeup readers)" |
160 |
||
3978 | 161 |
closed ifTrue:[ self errorNotOpen]. |
162 |
queue nextPut:anObject |
|
163 |
||
164 |
" |
|
165 |
|s| |
|
166 |
s := InternalPipeStream new. |
|
167 |
s nextPut:$a. |
|
168 |
s nextPut:$b. |
|
169 |
s nextPut:$c. |
|
170 |
" |
|
3128 | 171 |
! |
172 |
||
173 |
size |
|
174 |
^ queue size |
|
1015 | 175 |
! ! |
176 |
||
177 |
!InternalPipeStream methodsFor:'initialization'! |
|
178 |
||
3978 | 179 |
contentsSpecies:aClass |
180 |
"by default, I will return a String of elements, if reading multiple elements. |
|
181 |
However, you may change this to eg. an array, if desired" |
|
182 |
||
183 |
contentsSpecies := aClass. |
|
184 |
! |
|
185 |
||
1015 | 186 |
initialize |
187 |
queue := SharedQueue new. |
|
3978 | 188 |
closed := false. |
189 |
! ! |
|
190 |
||
191 |
!InternalPipeStream methodsFor:'queries'! |
|
192 |
||
193 |
contentsSpecies |
|
194 |
^ contentsSpecies ? String |
|
1015 | 195 |
! ! |
196 |
||
197 |
!InternalPipeStream methodsFor:'synchronization'! |
|
198 |
||
199 |
readWait |
|
200 |
queue readSemaphore wait |
|
3978 | 201 |
! |
202 |
||
203 |
writeWaitWithTimeoutMs:timeout |
|
204 |
queue writeSemaphore waitWithTimeoutMs:timeout |
|
1015 | 205 |
! ! |
206 |
||
207 |
!InternalPipeStream class methodsFor:'documentation'! |
|
208 |
||
209 |
version |
|
3978 | 210 |
^ '$Header$' |
1015 | 211 |
! ! |
3128 | 212 |