module IPv4ByteString1 where import Net.Types (IPv4 (..)) import Data.Bits import Data.ByteString.Internal as I import Data.Word import Foreign.Ptr import Foreign.Storable encode :: IPv4 -> ByteString encode (IPv4 w) = I.unsafeCreateUptoN 15 ( \ptr1 -> do (len1, ptr2) <- writeWord ptr1 w1 poke ptr2 dot (len2, ptr3) <- writeWord (ptr2 `plusPtr` 1) w2 poke ptr3 dot (len3, ptr4) <- writeWord (ptr3 `plusPtr` 1) w3 poke ptr4 dot (len4, _) <- writeWord (ptr4 `plusPtr` 1) w4 return (3 + len1 + len2 + len3 + len4) ) where w1 = fromIntegral $ shiftR w 24 w2 = fromIntegral $ shiftR w 16 w3 = fromIntegral $ shiftR w 8 w4 = fromIntegral w dot = 46 writeWord :: Ptr Word8 -> Word8 -> IO (Int, Ptr Word8) writeWord ptr word | word >= 100 = do let (word1, char3) = word `quotRem` 10 (char1, char2) = word1 `quotRem` 10 poke ptr (char1 + 48) poke (ptr `plusPtr` 1) (char2 + 48) poke (ptr `plusPtr` 2) (char3 + 48) return (3, ptr `plusPtr` 3) | word >= 10 = do let (char1, char2) = word `quotRem` 10 poke ptr (char1 + 48) poke (ptr `plusPtr` 1) (char2 + 48) return (2, ptr `plusPtr` 2) | otherwise = do poke ptr (word + 48) return (1, ptr `plusPtr` 1)