module HaskellWorks.Data.Network.Ip.Internal where import Control.Applicative import Control.Monad import Data.Char import Data.Word import HaskellWorks.Data.Bits.BitWise import qualified Data.Attoparsec.Text as AP fourOctetsToWord32 :: Word8 -> Word8 -> Word8 -> Word8 -> Word32 fourOctetsToWord32 a b c d = (fromIntegral a .<. 24) .|. (fromIntegral b .<. 16) .|. (fromIntegral c .<. 8) .|. fromIntegral d {-# INLINE fourOctetsToWord32 #-} infixl 2 #<*># (#<*>#) :: AP.Parser Word8 -> AP.Parser Word8 -> AP.Parser Word8 (#<*>#) pa pb = paste <$> pa <*> pb where paste a b = a * 10 + b octet :: AP.Parser Word8 octet = ((d12 #<*># d5 ) #<*># d05) <|> ((d12 #<*># d04) #<*># d09) <|> ((d1 #<*># d09) #<*># d09) <|> ( d19 #<*># d09) <|> d09 where d5 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (== '5') d1 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (== '1') d04 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '0' && c <= '4') d05 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '0' && c <= '5') d09 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '0' && c <= '9') d19 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '1' && c <= '9') d12 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '1' && c <= '2') ipv4Address :: AP.Parser Word32 ipv4Address = fourOctetsToWord32 <$> (octet <* AP.char '.') <*> (octet <* AP.char '.') <*> (octet <* AP.char '.') <*> octet whitespace :: AP.Parser () whitespace = void $ many (AP.satisfy isSpace)