On 09.01.2012 00:18, Eliot Miranda wrote:


On Sun, Jan 8, 2012 at 5:46 AM, Mariano Martinez Peck <[email protected] <mailto:[email protected]>> wrote:

    Hi guys. Some time ago Henry spot to us a small improvement for
    WriteStream >> nextPutAll: that we are using in Fuel, but I think
    it can be general. Henry comment was exactly:

    /Also: For variableBytes classes, if you rewrite:

    WriteStream
    nextPutAll: aCollection

         | newEnd |
    *collection class instSpec == aCollection class instSpec ifFalse:*
             [^ super nextPutAll: aCollection ].

         newEnd := position + aCollection size.
         newEnd > writeLimit ifTrue:
             [self growTo: newEnd + 10].

    collection replaceFrom: position+1 to: newEnd  with: aCollection
    startingAt: 1.
         position := newEnd.

        ^ aCollection

    You can now pass all variableByte classes (Like ByteString)
    directly to a stream with a ByteArray collection, and the
    replaceFrom:to:with:/
    /startingAt: primitive will work correctly, just like the file
    primitive does
This means you don't need special Serializers for these either, using f.ex. clunky nextStringPutAll: methods with manual
    asByteArray conversions./


    So...if you agree, I can commit the patch.


Surely this will break special encoded strings where the encode/decode is done in at:/at:put:. Moving the bytes isn't safe in general. However, if the programmer knows they themselves can use next:putAll:startingAt: or some such. I don't think your suggestion is safe in general for WriteStream. Instead if next:putAll:startingAt: doesn't do the job invent some new protocol that will.
In principle I agree, though the only such case I can think of in an image atm is the newly introduced:
wa := WordArray new: 2.
ws := wa writeStream.
ws nextPutAll: 1.0

The string example in itself is rather theoretical, the "convention" is to use ByteStrings for all encodings, and let the programmer fend for himself when it comes to remembering which ByteStrings he's converted to which encoding. (A practice which, sadly, is only enabled by the collection class = aCollection class check (the one in next:putAll:startingAt:), as encoding/decoding a ByteString to a ByteString is much faster than the equivalent operation resulting in a ByteArray... ) So in practice, even the current class check does not protect against what would be the common error.

Though, for a general, collection-agnostic approach which can still use primitives between compatible classes, I guess giving the nextPutAll: argument a say in what method is actually used to do a next:putAll:startingAt: would be a better approach than simply removing the check and crossing our fingers. :)

Cheers,
Henry

Reply via email to