In other Smalltalk (VW, Dolphin, ...) there is

nextAvailable: anInteger
        "Answer the next anInteger elements of the receiver.  If there are not
        enough elements available, answer a collection of as many as are 
available."

while next: would raise an Error if incomplete...

Maybe it's time to adopt it.

Nicolas

2013/3/21 Igor Stasenko <siguc...@gmail.com>:
> On 21 March 2013 20:48, Sven Van Caekenberghe <s...@stfx.eu> wrote:
>> Hi,
>>
>> Related to a hard to find Zinc bug that I just discovered, I require some 
>> feedback as to the semantics of SocketStream>>#next:
>>
>> IMHO, the current implementation is semantically wrong. I would expect the 
>> semantics to be: try to read count elements and return a new species 
>> collection containing them. If less elements are available, return a smaller 
>> collection. ( It then becomes effectively a limited #upToEnd).
>>
>> I always implemented #next: by delegating to #next:into:, to 
>> #next:into:startingAt: and finally #readInto:startingAt:count: (see for 
>> example ZdcAbstractSocketStream, ZnLimitedReadStream or ZnChunkedReadStream).
>>
>> When you look at the implementations of #next:into:, #next:into:startingAt: 
>> and #readInto:startingAt:count: on SocketStream, the fact that 
>> ConnectionClosed is not signalled is clearly stated. Yet 
>> SocketStream>>#next: is different, it does signal ConnectionClosed, which 
>> makes it impossible (unless you proceed the exception) to read up to end. 
>> And this is what InflateStream>>#getFirstBuffer expects. And which fails 
>> when less than 65536 bytes are available. Note that InflateStream reads its 
>> subsequent buffers using #next:into:startingAt: (see #moveSourceToFront) so 
>> that it properly reads up to end without signalling ConnectionClosed for 
>> larger payloads.
>>
>> I can easily program around it, but I think SocketStream>>#next: is wrong 
>> and should be changed.
>>
>> Any opinions ?
>>
>> Sven
>>
> I agree, the implementation notes of #next: should be:
>  - read the N elements from receiver, answer a collection of read elements.
> if receiver at end, or will reach end before reading all N elements,
> answer a collection of elements
> which were successfully read.
> ..
> the caller can always check the collection size, and if it < N, (and
> he insists on having N) he can either throw an error or handle it more
> graciously.
>
> '' readStream next: 5
> answering ''
> so, it actually consistent with what i stating.
>
> A reference implementation (in Stream), however doesn't works like that:
>
> next: anInteger
>         "Answer the next anInteger number of objects accessible by the 
> receiver."
>
>         | aCollection |
>         aCollection := OrderedCollection new.
>         anInteger timesRepeat: [aCollection addLast: self next].
>         ^aCollection
>
> this code will always answer collection of N elements..
> the bad side of it, that if stream reaching end, the tail will be
> filled with 'userful' nils. :)
>
> so , based on ReadStream implementation we can assume that caller
> already expects
> to receive <=N elements, but not N with partly filled with nils.
>
> Because then you cannot distinguish whether this nil goes from stream
> data or from stream itself, e.g.:
>
> #( 1 3 nil 4 5 nil nil ) readStream next: 10.
>
>> --
>> Sven Van Caekenberghe
>> http://stfx.eu
>> Smalltalk is the Red Pill
>>
>>
>
>
>
> --
> Best regards,
> Igor Stasenko.
>

Reply via email to