Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread John Van Enk


 Fair enough.   I am just new to the interface, wondering if I should
 try matching responses by pulling apart via Get, or the bit syntax
 package.



I'm assming you have some 'data Foo = ...'? If this is the case, you're
probably okay writing an instance of Binary for Foo and using encode/decode.
That's all I've had to do and had superb performance.

/jve
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread David Leimbach
On Thu, May 28, 2009 at 9:17 AM, John Van Enk vane...@gmail.com wrote:


 Fair enough.   I am just new to the interface, wondering if I should
 try matching responses by pulling apart via Get, or the bit syntax
 package.



 I'm assming you have some 'data Foo = ...'? If this is the case, you're
 probably okay writing an instance of Binary for Foo and using encode/decode.
 That's all I've had to do and had superb performance.



encode/decode do Big Endian, and 9P does little endian.

From the man page:

Each message consists of a sequence of bytes. Two–, four–, and eight–byte
fields hold unsigned integers represented in little–endian order (least
significant byte first).

encode/decode just won't work for me as a result, as they assume the
not-so-aptly-named (at least in this case) network byte order.  Since I'm
not Rob Pike, or Ken Thompson or any of the Plan 9 guys, I can't tell you
why they chose little endian for this.

(I should note that I sometimes work with CAN hardware, and depending on
what people want to put on the line, little endian creeps in there too, so
this issue will have to be dealt with here as well, if I am to use
Data.Binary)

I've got (typing from memory, forgive syntax errors)

module Nine (Message) where

{-- missing imports --}

notag = putWord16le -1

-- Message type field values
-- from: http://plan9.bell-labs.com/sources/plan9/sys/include/fcall.h
tversion = 100
rversion = 101
rerror = 107


-- only 9P2000 is being handled so some constructors are simple
data Message = Tversion
| Rversion {size :: Int, tag :: Int,  msize :: Int,
version :: String}
| Rerror {message :: String}  -- maybe this should
be Maybe ByteString?
...

instance Binary Message where
put Tversion = putWord32le 16  tversion  notag  msize  9P2000
put Rversion = putWord32le 16  rversion  notag  msize  9P2000
get = do size - getWord32le
 tag - getWord8
 case tag of
  rversion - do msize - getWord32le
   version - getRemainingLazyByteString
   return (Rversion size tag msize (C.unpack
version))

 ===

I'm beginning to feel the Get Monad is not going to be as nice as if I had
some bit-syntax for determining what type of return message I'm getting.
 Any T message can be met with the paired R response, or an Rerror
message, with a detailed description of what went wrong.  My instance of get
is looking like it's going to be pretty nasty :-)

The first message in any 9p session is Tversion with Rversion or Rerror
response.  There's optional authentication hooks via Tauth/Rauth, and then
the filesystem namespace navigation operation messages.

Dave

/jve

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread Don Stewart
leimy2k:
 encode/decode do Big Endian, and 9P does little endian. 
 
 From the man page:
 
 Each message consists of a sequence of bytes. Two , four , and eight byte
 fields hold unsigned integers represented in little endian order (least
 significant byte first).
 
 encode/decode just won't work for me as a result, as they assume the
 not-so-aptly-named (at least in this case) network byte order.  Since I'm 
 not
 Rob Pike, or Ken Thompson or any of the Plan 9 guys, I can't tell you why they
 chose little endian for this. 


I think you misunderstand the API: encode and decode *use whatever the
underlying instance for your data type uses*. If you write an instance
that uses the little endian primitives, that is what I will use.

-- Don
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread John Van Enk
Writing instances encode/decode that use either little endian or big endian
(or mixed!) is trivial... see attached file.

I don't see where your problem is...

On Thu, May 28, 2009 at 12:35 PM, David Leimbach leim...@gmail.com wrote:



   On Thu, May 28, 2009 at 9:17 AM, John Van Enk vane...@gmail.com wrote:


 Fair enough.   I am just new to the interface, wondering if I should
 try matching responses by pulling apart via Get, or the bit syntax
 package.



 I'm assming you have some 'data Foo = ...'? If this is the case, you're
 probably okay writing an instance of Binary for Foo and using encode/decode.
 That's all I've had to do and had superb performance.



 encode/decode do Big Endian, and 9P does little endian.

 From the man page:

 Each message consists of a sequence of bytes. Two–, four–, and eight–byte
 fields hold unsigned integers represented in little–endian order (least
 significant byte first).

 encode/decode just won't work for me as a result, as they assume the
 not-so-aptly-named (at least in this case) network byte order.  Since I'm
 not Rob Pike, or Ken Thompson or any of the Plan 9 guys, I can't tell you
 why they chose little endian for this.

 (I should note that I sometimes work with CAN hardware, and depending on
 what people want to put on the line, little endian creeps in there too, so
 this issue will have to be dealt with here as well, if I am to use
 Data.Binary)

 I've got (typing from memory, forgive syntax errors)

 module Nine (Message) where

 {-- missing imports --}

 notag = putWord16le -1

 -- Message type field values
 -- from: http://plan9.bell-labs.com/sources/plan9/sys/include/fcall.h
 tversion = 100
 rversion = 101
 rerror = 107


 -- only 9P2000 is being handled so some constructors are simple
 data Message = Tversion
 | Rversion {size :: Int, tag :: Int,  msize :: Int,
 version :: String}
 | Rerror {message :: String}  -- maybe this should
 be Maybe ByteString?
 ...

  instance Binary Message where
 put Tversion = putWord32le 16  tversion  notag  msize  9P2000
 put Rversion = putWord32le 16  rversion  notag  msize  9P2000
 get = do size - getWord32le
  tag - getWord8
  case tag of
   rversion - do msize - getWord32le
version - getRemainingLazyByteString
return (Rversion size tag msize
 (C.unpack version))

  ===

 I'm beginning to feel the Get Monad is not going to be as nice as if I had
 some bit-syntax for determining what type of return message I'm getting.
  Any T message can be met with the paired R response, or an Rerror
 message, with a detailed description of what went wrong.  My instance of get
 is looking like it's going to be pretty nasty :-)

 The first message in any 9p session is Tversion with Rversion or Rerror
 response.  There's optional authentication hooks via Tauth/Rauth, and then
 the filesystem namespace navigation operation messages.

 Dave

   /jve



 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe




-- 
/jve


binaryTest.hs
Description: Binary data
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-28 Thread David Leimbach
On Thu, May 28, 2009 at 11:39 AM, John Van Enk vane...@gmail.com wrote:

 Writing instances encode/decode that use either little endian or big endian
 (or mixed!) is trivial... see attached file.

 I don't see where your problem is...



Inexperience, lack of enough contiguous time to digest everything at once
(till now),  thank you for your most detailed example!  This should be
wiki'd.

Dave


 On Thu, May 28, 2009 at 12:35 PM, David Leimbach leim...@gmail.comwrote:



   On Thu, May 28, 2009 at 9:17 AM, John Van Enk vane...@gmail.comwrote:


 Fair enough.   I am just new to the interface, wondering if I should
 try matching responses by pulling apart via Get, or the bit syntax
 package.



 I'm assming you have some 'data Foo = ...'? If this is the case, you're
 probably okay writing an instance of Binary for Foo and using encode/decode.
 That's all I've had to do and had superb performance.



 encode/decode do Big Endian, and 9P does little endian.

 From the man page:

 Each message consists of a sequence of bytes. Two–, four–, and
 eight–byte fields hold unsigned integers represented in little–endian order
 (least significant byte first).

 encode/decode just won't work for me as a result, as they assume the
 not-so-aptly-named (at least in this case) network byte order.  Since I'm
 not Rob Pike, or Ken Thompson or any of the Plan 9 guys, I can't tell you
 why they chose little endian for this.

 (I should note that I sometimes work with CAN hardware, and depending on
 what people want to put on the line, little endian creeps in there too, so
 this issue will have to be dealt with here as well, if I am to use
 Data.Binary)

 I've got (typing from memory, forgive syntax errors)

 module Nine (Message) where

 {-- missing imports --}

 notag = putWord16le -1

 -- Message type field values
 -- from: http://plan9.bell-labs.com/sources/plan9/sys/include/fcall.h
 tversion = 100
 rversion = 101
 rerror = 107


 -- only 9P2000 is being handled so some constructors are simple
 data Message = Tversion
 | Rversion {size :: Int, tag :: Int,  msize ::
 Int, version :: String}
 | Rerror {message :: String}  -- maybe this should
 be Maybe ByteString?
 ...

  instance Binary Message where
 put Tversion = putWord32le 16  tversion  notag  msize 
 9P2000
 put Rversion = putWord32le 16  rversion  notag  msize 
 9P2000
 get = do size - getWord32le
  tag - getWord8
  case tag of
   rversion - do msize - getWord32le
version - getRemainingLazyByteString
return (Rversion size tag msize
 (C.unpack version))

  ===

 I'm beginning to feel the Get Monad is not going to be as nice as if I had
 some bit-syntax for determining what type of return message I'm getting.
  Any T message can be met with the paired R response, or an Rerror
 message, with a detailed description of what went wrong.  My instance of get
 is looking like it's going to be pretty nasty :-)

 The first message in any 9p session is Tversion with Rversion or Rerror
 response.  There's optional authentication hooks via Tauth/Rauth, and then
 the filesystem namespace navigation operation messages.

 Dave

   /jve



 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe




 --
 /jve

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Data.Binary and little endian encoding

2009-05-15 Thread David Leimbach
This approach looks like it'd work just fine.

On Fri, May 15, 2009 at 2:16 AM, John Lato jwl...@gmail.com wrote:

 leimy2k:
  On Thu, May 14, 2009 at 8:46 PM, Don Stewart d...@galois.com wrote:
 
  leimy2k:
  
  
   On Thu, May 14, 2009 at 8:40 PM, Don Stewart d...@galois.com wrote:
  
   leimy2k:
I actually need little endian encoding... wondering if anyone
 else
  hit
   this
with Data.Binary. (because I'm working with Bell Lab's 9P
 protocol
  which
   does
encode things on the network in little-endian order).
   
Anyone got some tricks for this?
  
   Yes!
   There are big, little and host-endian primitives in the Get/Put
  monads.
  
  
  http://hackage.haskell.org/packages/archive/binary/0.5.0.1/doc/html/
   Data-Binary-Put.html#v%3AputWord16le
  
   You can use these to build encoders directly.
  
  
   Cool... I just have to write my own encoder and decoder now.
  
   As a request could we get encodeLe decodeLe for a later version of
 this
   library?  :-)  That'd be totally awesome.
 
  Oh, you mean entirely different instances for all the current ones, that
  use LE encodings?
 
 
  Well the library is leaning towards Network Byte Order in that it has
  encode/decode that only encode/decode for Big Endian.
 
  Us folks who have to do little endian all now have to write our own
  encoding/decoding :-)
 
  I'm speaking specifically of the encode/decode functions.  I have no idea
  how they're implemented.

 The encode/decode functions just call the runGet/runPut functions for
 whatever is being encoded or decoded to combined with the get/put
 functions from the Binary instance.  The endian-ness is entirely
 determined by the Binary instance for the data type you're
 encoding/decoding, not anything in the encode/decode functions
 themselves.

 For data types you define, you can make the Binary instance LE
 standard (although it may not be a good idea) by using the
 little-endian primitives Don mentioned.  For built-in types, if you
 want to use a different endian-ness, you can make new get/put
 functions then call runGet/runPut on those directly.  You won't be
 able to redefine the Binary instances, but if you'll be doing this
 with a lot of different types you could make your own BinaryLE class
 like this:

 class BinaryLE t where
  putLE :: t - Put
  getLE :: Get t

 encodeLE :: BinaryLE a = a - ByteString
 encodeLE = runPut . putLE

 decodeLE :: BinaryLE a = ByteString - a
 decodeLE = runGet getLE

 I've done some work with Binary and little-endian, and this bias never
 really bothered me (I think it's actually a host-endian bias, could be
 mistaken).  I was using my own data types so I had to make my own
 custom Binary instances, which I would have had to do anyway.  The
 data format specified little-endian, so making the Binary instance
 LE-standard seemed appropriate.

 You'd only need to re-make custom get/put functions if you're using
 types that already have Binary instances, and you intend to manipulate
 the data outside of Haskell.  Does that describe your situation?

 John
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe