ugly/bad/nonportable writev for lazy ByteString

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import Control.Applicative
import Foreign.C.Types
import Foreign.Ptr
import Foreign.ForeignPtr
import Foreign.Storable
import Foreign.Marshal.Array

import qualified Data.ByteString.Lazy as B
import qualified Data.ByteString.Lazy.Internal as B
import qualified Data.ByteString.Internal as BI


data IOVec = IOVec {
  iov_base :: !(Ptr Word8),
  iov_len :: !CSize
  }

instance Storable IOVec where
  peek p = IOVec <$> peek (plusPtr p 0) <*> peek (plusPtr p 8)
  poke p v = poke (plusPtr p 0) (iov_base v) >> poke (plusPtr p 8) (iov_len v)
  sizeOf _ = 16
  alignment _ = 8

foreign import ccall writev :: CInt -> Ptr IOVec -> CInt -> IO CSize

bufcount = 1024

outputSome :: B.ByteString -> IO B.ByteString
outputSome B.Empty = return B.Empty
outputSome b = allocaArray bufcount $ \p ->
  let go n b' | n == bufcount = writev 1 p (fromIntegral n) >> return b'
      go n B.Empty = writev 1 p (fromIntegral n) >> return B.Empty
      go n (B.Chunk (BI.PS s off len) b') = withForeignPtr s $ \s' ->
        pokeElemOff p n (IOVec (plusPtr s' off) (fromIntegral len)) >> go (n+1) b'
  in go 0 b

output :: B.ByteString -> IO ()
output B.Empty = return ()
output b = outputSome b >>= output
13:1: Warning: Use camelCase
Found:
data IOVec = IOVec{iov_base :: !(Ptr Word8), iov_len :: !CSize}
Why not:
data IOVec = IOVec{iovBase :: !(Ptr Word8), iovLen :: !CSize}