From 5eb23e19d0621e7b6228a8703d6960627285e0a4 Mon Sep 17 00:00:00 2001 From: Jens Nolte <git@queezle.net> Date: Tue, 21 Sep 2021 18:52:35 +0200 Subject: [PATCH] Remove unnecessary copy when sending --- src/Quasar/Wayland/Protocol/Core.hs | 37 +++++++++++++---------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/Quasar/Wayland/Protocol/Core.hs b/src/Quasar/Wayland/Protocol/Core.hs index 6ea6a80..0fa8c2d 100644 --- a/src/Quasar/Wayland/Protocol/Core.hs +++ b/src/Quasar/Wayland/Protocol/Core.hs @@ -142,12 +142,12 @@ instance WireFormat Fixed where showArgument = show instance WireFormat WlString where - putArgument (WlString x) = pure $ putWaylandBlob x + putArgument (WlString x) = putWaylandBlob x getArgument = pure . WlString <$> getWaylandBlob showArgument = show instance WireFormat BS.ByteString where - putArgument x = pure $ putWaylandBlob x + putArgument x = putWaylandBlob x getArgument = pure <$> getWaylandBlob showArgument array = "[array " <> show (BS.length array) <> "B]" @@ -535,27 +535,20 @@ sendMessage object message = do (opcode, pairs) <- putUp object message let (putBodyParts, partLengths) = unzip pairs let putBody = mconcat putBodyParts - let bodyLength = foldr (+) 0 partLengths - let body = runPut putBody + + let bodyLength = foldr (+) 8 partLengths + when (bodyLength > fromIntegral (maxBound :: Word16)) $ + throwM $ ProtocolUsageError $ "Tried to send message larger than 2^16 bytes" + traceM $ "-> " <> showObjectMessage object message - sendRawMessage $ messageWithHeader opcode body + sendRawMessage $ putHeader opcode bodyLength >> putBody where oId = objectId object - messageWithHeader :: Opcode -> BSL.ByteString -> Put - messageWithHeader opcode body = do + (GenericObjectId objectIdWord) = objectId object + putHeader :: Opcode -> Int -> Put + putHeader opcode msgSize = do putWord32host objectIdWord putWord32host $ (fromIntegral msgSize `shiftL` 16) .|. fromIntegral opcode - putLazyByteString body - where - (GenericObjectId objectIdWord) = objectId object - msgSize :: Word16 - msgSize = - if msgSizeInteger <= fromIntegral (maxBound :: Word16) - then fromIntegral msgSizeInteger - else error "Message too large" - -- TODO: body length should be returned from `putMessage`, instead of realizing it to a ByteString here - msgSizeInteger :: Integer - msgSizeInteger = 8 + fromIntegral (BSL.length body) receiveMessages :: IsSide s => ProtocolM s () @@ -624,8 +617,12 @@ getWaylandBlob = do skipPadding pure string -putWaylandBlob :: BS.ByteString -> (Put, Int) -putWaylandBlob blob = (putBlob, 4 + len + pad) +putWaylandBlob :: BS.ByteString -> ProtocolM s (Put, Int) +putWaylandBlob blob = do + when (len > fromIntegral (maxBound :: Word16)) $ + throwM $ ProtocolUsageError $ "Tried to send string or array larger than 2^16 bytes" + + pure (putBlob, 4 + len + pad) where -- Total data length including null byte len = BS.length blob + 1 -- GitLab