packages feed

network-byte-order (empty) → 0.0.0.0

raw patch · 5 files changed

+362/−0 lines, 5 filesdep +basedep +bytestringdep +doctestsetup-changed

Dependencies added: base, bytestring, doctest

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2017, Kazu Yamamoto++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Kazu Yamamoto nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Network/ByteOrder.hs view
@@ -0,0 +1,280 @@+-- | Peek and poke functions for network byte order.++module Network.ByteOrder (+    -- *Types+    Buffer+  , Offset+    -- *Poking+  , poke8+  , poke16+  , poke24+  , poke32+  , poke64+    -- *Peeking+  , peek8+  , peek16+  , peek24+  , peek32+  , peek64+    -- *From Word to ByteString+  , bytestring8+  , bytestring16+  , bytestring32+  , bytestring64+    -- *From ByteString to Word+  , word8+  , word16+  , word32+  , word64+    -- *Utilities+  , unsafeWithByteString+  ) where++import Data.Bits (shiftR, shiftL, (.&.), (.|.))+import Data.ByteString.Internal (ByteString(..), unsafeCreate)+import Data.Word (Word8, Word16, Word32, Word64)+import Foreign.ForeignPtr (withForeignPtr)+import Foreign.Ptr (Ptr, plusPtr)+import Foreign.Storable (poke, peek)+import System.IO.Unsafe (unsafeDupablePerformIO)++-- $setup+-- >>> import Data.ByteString hiding (foldl')+-- >>> import Data.Word+-- >>> import Data.List++----------------------------------------------------------------++type Buffer = Ptr Word8+type Offset = Int++----------------------------------------------------------------++(+.) :: Buffer -> Offset -> Buffer+(+.) = plusPtr++----------------------------------------------------------------++-- |+--+-- >>> let buf = pack [1,2,3,4]+-- >>> unsafeWithByteString buf (poke8 0)+-- >>> unpack buf+-- [0,2,3,4]+poke8 :: Word8 -> Buffer -> Offset -> IO ()+poke8 w ptr off = poke (ptr +. off) w++-- |+--+-- >>> let buf = pack [1,2,3,4]+-- >>> unsafeWithByteString buf (poke16 (7*256 + 8))+-- >>> unpack buf+-- [7,8,3,4]+poke16 :: Word16 -> Buffer -> Offset -> IO ()+poke16 w ptr off = do+    poke8 w0 ptr off+    poke8 w1 ptr (off + 1)+  where+    w0 = fromIntegral ((w `shiftR`  8) .&. 0xff)+    w1 = fromIntegral  (w              .&. 0xff)++-- |+--+-- >>> let buf = pack [1,2,3,4]+-- >>> unsafeWithByteString buf (poke24 (6*65536 + 7*256 + 8))+-- >>> unpack buf+-- [6,7,8,4]+poke24 :: Word32 -> Buffer -> Offset -> IO ()+poke24 w ptr off = do+    poke8 w0 ptr off+    poke8 w1 ptr (off + 1)+    poke8 w2 ptr (off + 2)+  where+    w0 = fromIntegral ((w `shiftR` 16) .&. 0xff)+    w1 = fromIntegral ((w `shiftR`  8) .&. 0xff)+    w2 = fromIntegral  (w              .&. 0xff)++-- |+--+-- >>> let buf = pack [1,2,3,4]+-- >>> unsafeWithByteString buf (poke32 (6*65536 + 7*256 + 8))+-- >>> unpack buf+-- [0,6,7,8]+poke32 :: Word32 -> Buffer -> Offset -> IO ()+poke32 w ptr off = do+    poke8 w0 ptr off+    poke8 w1 ptr (off + 1)+    poke8 w2 ptr (off + 2)+    poke8 w3 ptr (off + 3)+  where+    w0 = fromIntegral ((w `shiftR` 24) .&. 0xff)+    w1 = fromIntegral ((w `shiftR` 16) .&. 0xff)+    w2 = fromIntegral ((w `shiftR`  8) .&. 0xff)+    w3 = fromIntegral  (w              .&. 0xff)++-- |+--+-- >>> let buf = pack [1,2,3,4,5,6,7,8]+-- >>> unsafeWithByteString buf (poke64 (6*65536 + 7*256 + 8))+-- >>> unpack buf+-- [0,0,0,0,0,6,7,8]+poke64 :: Word64 -> Buffer -> Offset -> IO ()+poke64 w ptr off = do+    poke8 w0 ptr off+    poke8 w1 ptr (off + 1)+    poke8 w2 ptr (off + 2)+    poke8 w3 ptr (off + 3)+    poke8 w4 ptr (off + 4)+    poke8 w5 ptr (off + 5)+    poke8 w6 ptr (off + 6)+    poke8 w7 ptr (off + 7)+  where+    w0 = fromIntegral ((w `shiftR` 56) .&. 0xff)+    w1 = fromIntegral ((w `shiftR` 48) .&. 0xff)+    w2 = fromIntegral ((w `shiftR` 40) .&. 0xff)+    w3 = fromIntegral ((w `shiftR` 32) .&. 0xff)+    w4 = fromIntegral ((w `shiftR` 24) .&. 0xff)+    w5 = fromIntegral ((w `shiftR` 16) .&. 0xff)+    w6 = fromIntegral ((w `shiftR`  8) .&. 0xff)+    w7 = fromIntegral  (w              .&. 0xff)++----------------------------------------------------------------++-- |+--+-- >>> let buf = pack [1,2,3,4]+-- >>> unsafeWithByteString buf peek8+-- 1+peek8 :: Buffer -> Offset -> IO Word8+peek8 ptr off = peek (ptr +. off)++-- |+--+-- >>> let buf = pack [1,2,3,4]+-- >>> unsafeWithByteString buf peek16+-- 258+peek16 :: Buffer -> Offset -> IO Word16+peek16 ptr off = do+    w0 <- (`shiftL` 8) . fromIntegral <$> peek8 ptr off+    w1 <-                fromIntegral <$> peek8 ptr (off + 1)+    return $ w0 .|. w1++-- |+--+-- >>> let buf = pack [1,2,3,4]+-- >>> unsafeWithByteString buf peek24+-- 66051+peek24 :: Buffer -> Offset -> IO Word32+peek24 ptr off = do+    w0 <- (`shiftL` 16) . fromIntegral <$> peek8 ptr off+    w1 <- (`shiftL`  8) . fromIntegral <$> peek8 ptr (off + 1)+    w2 <-                 fromIntegral <$> peek8 ptr (off + 2)+    return $ w0 .|. w1 .|. w2++-- |+--+-- >>> let buf = pack [1,2,3,4]+-- >>> unsafeWithByteString buf peek32+-- 16909060+peek32 :: Buffer -> Offset -> IO Word32+peek32 ptr off = do+    w0 <- (`shiftL` 24) . fromIntegral <$> peek8 ptr off+    w1 <- (`shiftL` 16) . fromIntegral <$> peek8 ptr (off + 1)+    w2 <- (`shiftL`  8) . fromIntegral <$> peek8 ptr (off + 2)+    w3 <-                 fromIntegral <$> peek8 ptr (off + 3)+    return $ w0 .|. w1 .|. w2 .|. w3++-- |+--+-- >>> let buf = pack [1,2,3,4,5,6,7,8]+-- >>> unsafeWithByteString buf peek64+-- 72623859790382856+peek64 :: Buffer -> Offset -> IO Word64+peek64 ptr off = do+    w0 <- (`shiftL` 56) . fromIntegral <$> peek8 ptr off+    w1 <- (`shiftL` 48) . fromIntegral <$> peek8 ptr (off + 1)+    w2 <- (`shiftL` 40) . fromIntegral <$> peek8 ptr (off + 2)+    w3 <- (`shiftL` 32) . fromIntegral <$> peek8 ptr (off + 3)+    w4 <- (`shiftL` 24) . fromIntegral <$> peek8 ptr (off + 4)+    w5 <- (`shiftL` 16) . fromIntegral <$> peek8 ptr (off + 5)+    w6 <- (`shiftL`  8) . fromIntegral <$> peek8 ptr (off + 6)+    w7 <-                 fromIntegral <$> peek8 ptr (off + 7)+    return $ w0 .|. w1 .|. w2 .|. w3 .|. w4 .|. w5 .|. w6 .|. w7++----------------------------------------------------------------++-- |+--+-- >>> let w = 5 :: Word8+-- >>> unpack $ bytestring8 w+-- [5]+bytestring8 :: Word8 -> ByteString+bytestring8 w = unsafeCreate 1 $ \ptr -> poke8 w ptr 0++-- |+--+-- >>> let w = foldl' (\x y -> x * 256 + y) 0 [5,6] :: Word16+-- >>> unpack $ bytestring16 w+-- [5,6]+bytestring16 :: Word16 -> ByteString+bytestring16 w = unsafeCreate 2 $ \ptr -> poke16 w ptr 0++-- |+--+-- >>> let w = foldl' (\x y -> x * 256 + y) 0 [5,6,7,8] :: Word32+-- >>> unpack $ bytestring32 w+-- [5,6,7,8]+bytestring32 :: Word32 -> ByteString+bytestring32 w = unsafeCreate 4 $ \ptr -> poke32 w ptr 0++-- |+--+-- >>> let w = foldl' (\x y -> x * 256 + y) 0 [1,2,3,4,5,6,7,8] :: Word64+-- >>> unpack $ bytestring64 w+-- [1,2,3,4,5,6,7,8]+bytestring64 :: Word64 -> ByteString+bytestring64 w = unsafeCreate 8 $ \ptr -> poke64 w ptr 0++----------------------------------------------------------------++-- |+--+-- >>> let buf = pack [1,2,3,4,5,6,7,8]+-- >>> word8 buf+-- 1+word8 :: ByteString -> Word8+word8 bs = unsafeDupablePerformIO $ unsafeWithByteString bs peek8++-- |+--+-- >>> let buf = pack [1,2,3,4,5,6,7,8]+-- >>> word16 buf+-- 258+word16 :: ByteString -> Word16+word16 bs = unsafeDupablePerformIO $ unsafeWithByteString bs peek16++-- |+--+-- >>> let buf = pack [1,2,3,4,5,6,7,8]+-- >>> word32 buf+-- 16909060+word32 :: ByteString -> Word32+word32 bs = unsafeDupablePerformIO $ unsafeWithByteString bs peek32++-- |+--+-- >>> let buf = pack [1,2,3,4,5,6,7,8]+-- >>> word64 buf+-- 72623859790382856+word64 :: ByteString -> Word64+word64 bs = unsafeDupablePerformIO $ unsafeWithByteString bs peek64++----------------------------------------------------------------++-- | Using 'ByteString' as 'Buffer' and call the 'IO' action+--   of the second argument by passing the start point and the offset+--   of the 'ByteString'.+--   Note that if a 'ByteString' is created newly, its offset is 0.+unsafeWithByteString :: ByteString -> (Buffer -> Offset -> IO a) -> IO a+unsafeWithByteString (PS fptr off _) io = withForeignPtr fptr $+    \ptr -> io ptr off
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ network-byte-order.cabal view
@@ -0,0 +1,40 @@+-- Initial network-byte-order.cabal generated by cabal init.  For further+-- documentation, see http://haskell.org/cabal/users-guide/++name:                network-byte-order+version:             0.0.0.0+synopsis:            Network byte order utilities+description:         Peek and poke functions for network byte order.+license:             BSD3+license-file:        LICENSE+author:              Kazu Yamamoto <kazu@iij.ad.jp>+maintainer:          Kazu Yamamoto <kazu@iij.ad.jp>+-- copyright:+category:            Network+build-type:          Simple+-- extra-source-files:  ChangeLog.md+cabal-version:       >= 1.10++library+  ghc-options:         -Wall+  exposed-modules:     Network.ByteOrder+  -- other-modules:+  -- other-extensions:+  build-depends:       base >= 4.8 && < 5+                     , bytestring+  -- hs-source-dirs:+  default-language:    Haskell2010++test-suite doctest+  type:                 exitcode-stdio-1.0+  default-language:     Haskell2010+  hs-source-dirs:       test+  ghc-options:          -Wall+  main-is:              doctests.hs+  build-depends:        base+                      , bytestring+                      , doctest++source-repository head+  type:     git+  location: git://github.com/kazu-yamamoto/network-byte-order.git
+ test/doctests.hs view
@@ -0,0 +1,10 @@+module Main where++import Test.DocTest++main :: IO ()+main = doctest [+    "-XOverloadedStrings"+  , "-XCPP"+  , "Network/ByteOrder.hs"+  ]