Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsing using the Storable (Data.Store) #20

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

tclv
Copy link
Collaborator

@tclv tclv commented Dec 12, 2016

I have not yet ran these changes against a compositor. Will do so soon!

Implemented the Storable typeclass from Data.Store. Was implemented in
such a way that all the machinery from Data.Store can be used to
efficiently encode and decode the Wayland ByteString format.

Fixes #6.

tclv added 2 commits December 10, 2016 19:49
Implemented the Storable typeclass from Data.Store. Was implemented in
such a way that all the machinery from Data.Store can be used to
efficiently encode and decode the Wayland ByteString format.
}
{-# INLINE size #-}
{-# INLINE peek #-}
{-# INLINE poke #-}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to complain about these pragmas, but store itself seems to have them as well, so I suppose we should add a comment saying that we just follow those conventions.
Also, perhaps future readers might be confused for a second why we can't just peek the payload. So perhaps a comment saying they're variable size.
(There seems to be support in store for ByteStrings using some StaticSize type, but that's probably overkill for us.)

Copy link
Owner

@abooij abooij left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here are some random nitpicks.

@@ -944,11 +945,11 @@ display_read_events proxyP = withStablePtr proxyP $ \proxy -> do
fd_queue <- newTQueueIO
atomically $ mapM_ (writeTQueue fd_queue) fds

let pkgsParse = parseOnly pkgStream bytes
let pkgsParse = (S.decode bytes :: Either S.PeekException [WirePackage])
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the Store instance of [WirePackage] come from? As the latter is variable size...

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can drop the parentheses here.

sz <- peek
let payloadSize = fromIntegral sz - 8
plraw <- peekToPlainForeignPtr "Data.ByteString.ByteString" payloadSize
let pl = B.PS plraw 0 payloadSize
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand if this is able to leak memory or not. And in any case, these two lines are strange, as peekToPlainForeignPtr creates a ByteString, and then extracts the ForeignPtr, which we then reinsert into a ByteString. Surely we can do this directly. If not, please add a comment explaining why not.

-- Allows us to use the optimized machinery for Data.Store
-- to gain faster performing decoding/encoding.
instance Store WirePackage where
size = VarSize $ fromIntegral . wirePackageSize
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(perhaps we should add test cases that check that indeed the byte size of a WirePackage is its wirePackageSize - though perhaps that is a store invariant)

wirePackBuilder sender size opcode payload =
BBE.word32Host sender
<>
-- FIXME make byte order portable here
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot what this FIXME was about, it seems to be doing the right thing. So yes this comment can probably be dropped.

payload
-- Storable that writes in the Wayland binary format.
-- Allows us to use the optimized machinery for Data.Store
-- to gain faster performing decoding/encoding.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a useful comment, so make it a haddock one by starting with -- |. "Faster performing" than what?

{ wirePackageSender=sen
, wirePackageSize=sz
, wirePackageOpcode=op
, wirePackagePayload=pl
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spaces around = please :)

@abooij
Copy link
Owner

abooij commented Dec 13, 2016

Upon further investigation, it seems that two points of my review are ill-informed: you're just using store's own approach to implementing a Store instance for ByteString, and the list instance is indeed part of store.

pkgStream :: A.Parser [WirePackage]
pkgStream = A.many' parseWirePackage
wirePack :: WirePackage -> BB.Builder
wirePack = BB.byteString . encode
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we can replace wirePack by the list instance of Store: its only purpose is to sequences packages into a big binary blob (see serializeQueue1 in Graphics.Sudbury.CABI.Common), and store can do this for us.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(but then we'd have to first use this list instance, and then cut away the first value in the output which is the length)

Copy link
Collaborator Author

@tclv tclv Dec 17, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So currently this breaks regardless due to the fact that Store doesn't align on 32 bits, which the Wayland protocol requires (I'll include a test for future reference). I think the easiest fix would be a newtype wrapper around a list and write an override for the store implementation (which would be identical for the most part to the default list implementation in Store).

tclv added 6 commits December 18, 2016 15:11
The list instances used previously were incorrect as the dont account
for padding and do not have the correct format (prepend the size of the
list). Added a test case (with a multiple packages bytestring arbitrary
instance) to check for this in the future.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants