codesnippets:octets
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| codesnippets:octets [2021/03/17 07:27] – created f2b216 | codesnippets:octets [2025/10/08 00:48] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Octets ====== | ====== Octets ====== | ||
| - | <code Haskell> | + | * type '' |
| - | module Main where | + | * with type '' |
| + | * with instances for '' | ||
| + | * example | ||
| + | * code, of module '' | ||
| + | {-# LANGUAGE BinaryLiterals #-} | ||
| + | module Octetable | ||
| + | ( | ||
| + | Octetable(..), | ||
| + | Octet, | ||
| + | Octets, | ||
| + | getOctets, | ||
| + | putOctets | ||
| + | ) where | ||
| + | |||
| import qualified Data.Word as W | import qualified Data.Word as W | ||
| import qualified Data.Bits as Bts | import qualified Data.Bits as Bts | ||
| - | import Data.Bits ((.|.)) | + | import |
| - | import qualified Data.List as L | + | import qualified System.IO as SysIo |
| + | import qualified Data.ByteString as BS | ||
| + | import | ||
| - | main :: IO () | + | type Octet = W.Word8 |
| - | main = do | + | |
| - | print $ atDefault 0x00 (-1) myOctet | + | |
| - | print $ atDefault 0x00 0 myOctet | + | |
| - | print $ atDefault 0x00 1 myOctet | + | |
| - | print $ atDefault 0x00 2 myOctet | + | |
| - | print $ atDefault 0x00 3 myOctet | + | |
| - | print $ atDefault 0x00 4 myOctet | + | |
| - | myOctet | + | type Octets |
| - | atDefault | + | getOctets |
| - | atDefault aDef _ [] = aDef -- case: is empty anyway | + | getOctets |
| - | atDefault _ 0 | + | |
| - | atDefault aDef nIndex | + | |
| - | | nIndex > 0 = atDefault aDef (nIndex - 1) la -- case: index is positive | + | |
| - | | otherwise | + | |
| - | class Octetable | + | putOctets :: SysIo.Handle -> [W.Word8] -> IO () |
| - | toOctets :: w -> [W.Word8] | + | putOctets hOut octs = BS.hPut hOut (BS.pack octs) |
| + | |||
| + | class (Eq a, Show a) => Octetable | ||
| + | toOctets :: a -> Octets | ||
| + | fromOctets :: Octets -> a | ||
| instance Octetable W.Word32 where | instance Octetable W.Word32 where | ||
| Line 37: | Line 45: | ||
| , fromIntegral w32 | , fromIntegral w32 | ||
| ] | ] | ||
| + | fromOctets lw = foldl (\w32 w8 -> (w32 `Bts.shiftL` 8) + (fromIntegral w8)) 0 lw | ||
| + | |||
| + | instance Octetable Char where | ||
| + | toOctets ch = (fIntegralToOctets . Chr.ord) ch | ||
| + | fromOctets [] = ' | ||
| + | fromOctets lw = Chr.chr (integralFromOctets lw) | ||
| + | |||
| + | {-| UTF-8 character | ||
| + | |||
| + | * prefix: cu8 | ||
| + | * represent on UTF-8 character | ||
| + | * keeps one, two, three or four character | ||
| + | -} | ||
| + | data Utf8Char = | ||
| + | OneByte (W.Word8) | ||
| + | | TwoBytes (W.Word8, W.Word8) | ||
| + | | ThreeBytes (W.Word8, W.Word8, W.Word8) | ||
| + | | FourBytes (W.Word8, W.Word8, W.Word8, W.Word8) | ||
| + | deriving (Show, Eq) | ||
| + | |||
| + | instance Octetable Utf8Char where | ||
| + | toOctets (OneByte w81) = [w81] | ||
| + | toOctets (TwoBytes (w81,w82)) = [w81,w82] | ||
| + | toOctets (ThreeBytes (w81, | ||
| + | toOctets (FourBytes (w81, | ||
| + | fromOctets (w81: | ||
| + | | (w81 .&. 0b10000000) == 0b00000000 = OneByte w81 | ||
| + | | (w81 .&. 0b11100000) == 0b11000000 = TwoBytes (w81,w82) | ||
| + | | (w81 .&. 0b11110000) == 0b11100000 = ThreeBytes (w81, | ||
| + | | otherwise | ||
| + | fromOctets (w81: | ||
| + | | (w81 .&. 0b10000000) == 0b00000000 = OneByte w81 | ||
| + | | (w81 .&. 0b11100000) == 0b11000000 = TwoBytes (w81,w82) | ||
| + | | otherwise | ||
| + | fromOctets (w81: | ||
| + | | (w81 .&. 0b10000000) == 0b00000000 = OneByte w81 | ||
| + | | otherwise | ||
| + | fromOctets (w81:[]) = OneByte w81 | ||
| + | fromOctets [] = (OneByte 0) | ||
| + | |||
| + | instance Octetable Integer where | ||
| + | toOctets n = fIntegralToOctets n | ||
| + | fromOctets lw = integralFromOctets lw | ||
| + | |||
| + | instance Octetable Int where | ||
| + | toOctets n = fIntegralToOctets n | ||
| + | fromOctets lw = integralFromOctets lw | ||
| + | |||
| + | fIntegralToOctets :: (Integral a) => a -> Octets | ||
| + | fIntegralToOctets n | ||
| + | | n > 0 = | ||
| + | let (_, lw8) = fIntegralToOctets' | ||
| + | in keepOctetsPositive lw8 | ||
| + | | n < 0 = | ||
| + | let (_, lw8) = fIntegralToOctets' | ||
| + | in (keepOctetsNegative . (fmap Bts.complement)) lw8 | ||
| + | | otherwise = [] | ||
| + | |||
| + | fIntegralToOctets' | ||
| + | fIntegralToOctets' | ||
| + | tpl | ||
| + | fIntegralToOctets' | ||
| + | fIntegralToOctets' | ||
| + | |||
| + | keepOctetsPositive :: Octets -> Octets | ||
| + | keepOctetsPositive [] = [] | ||
| + | keepOctetsPositive lw8 | ||
| + | | Bts.testBit (head lw8) 7 = 0 : lw8 -- highest bit is set, hence would be interpreted as negative by integralFromOctets -> append 0x00 to keep positive | ||
| + | | otherwise | ||
| + | |||
| + | keepOctetsNegative :: Octets -> Octets | ||
| + | keepOctetsNegative [] = [] | ||
| + | keepOctetsNegative lw8 | ||
| + | | Bts.testBit (head lw8) 7 = lw8 -- highest bit is set, hence would be interpreted as negative by integralFromOctets -> append 0x00 to keep positive | ||
| + | | otherwise | ||
| + | |||
| + | integralFromOctets :: (Integral a) => Octets -> a | ||
| + | integralFromOctets lw8 | ||
| + | | Bts.testBit (head lw8) 7 = (negate . (+1) . integralFromOctets . (fmap Bts.complement)) lw8 | ||
| + | | otherwise | ||
| </ | </ | ||
| + | * code, of module '' | ||
| + | import qualified Octetable as Oct | ||
| + | |||
| + | main :: IO () | ||
| + | main = | ||
| + | do | ||
| + | printExample ' | ||
| + | printExample ' | ||
| + | printExample ' | ||
| + | printExample ' | ||
| + | printExample ' | ||
| + | printExample ' | ||
| + | printExample ' | ||
| + | printExample (127 :: Int) | ||
| + | printExample (128 :: Int) | ||
| + | printExample (255 :: Int) | ||
| + | printExample (256 :: Int) | ||
| + | printExample (257 :: Int) | ||
| + | printExample (258 :: Int) | ||
| + | printExample (-127 :: Int) | ||
| + | printExample (-128 :: Int) | ||
| + | printExample (-129 :: Int) | ||
| + | printExample (-130 :: Int) | ||
| + | printExample (-255 :: Int) | ||
| + | printExample (-256 :: Int) | ||
| + | printExample (-257 :: Int) | ||
| + | printExample (-258 :: Int) | ||
| + | printExample (127 :: Integer) | ||
| + | printExample (128 :: Integer) | ||
| + | printExample (255 :: Integer) | ||
| + | printExample (256 :: Integer) | ||
| + | printExample (257 :: Integer) | ||
| + | printExample (258 :: Integer) | ||
| + | printExample (-127 :: Integer) | ||
| + | printExample (-128 :: Integer) | ||
| + | printExample (-255 :: Integer) | ||
| + | printExample (-256 :: Integer) | ||
| + | printExample (-257 :: Integer) | ||
| + | printExample (-258 :: Integer) | ||
| + | printExample hugeInteger | ||
| + | printExample (-hugeInteger) | ||
| + | |||
| + | printExample :: Oct.Octetable a => a -> IO () | ||
| + | printExample x = | ||
| + | let | ||
| + | octX :: Oct.Octets | ||
| + | octX = Oct.toOctets x | ||
| + | x' = Oct.fromOctets octX | ||
| + | in | ||
| + | do | ||
| + | if (x /= x') | ||
| + | then | ||
| + | putStrLn " | ||
| + | else | ||
| + | putStrLn " | ||
| + | putStrLn $ " | ||
| + | putStrLn $ " | ||
| + | putStrLn $ " | ||
| + | |||
| + | hugeInteger :: Integer | ||
| + | hugeInteger = 31 ^ (1000 :: Int) | ||
| + | </ | ||
| + | * compiles, error and warning free, with compiler: GHC 8.10.4, using compiler option -Wall | ||
| + | * executes, with output:< | ||
| + | OK | ||
| + | ' | ||
| + | [97] | ||
| + | ' | ||
| + | OK | ||
| + | ' | ||
| + | [122] | ||
| + | ' | ||
| + | OK | ||
| + | ' | ||
| + | [65] | ||
| + | ' | ||
| + | OK | ||
| + | ' | ||
| + | [90] | ||
| + | ' | ||
| + | OK | ||
| + | ' | ||
| + | [48] | ||
| + | ' | ||
| + | OK | ||
| + | ' | ||
| + | [57] | ||
| + | ' | ||
| + | OK | ||
| + | ' | ||
| + | | ||
| + | ' | ||
| + | OK | ||
| + | 127 | ||
| + | [127] | ||
| + | 127 | ||
| + | OK | ||
| + | 128 | ||
| + | | ||
| + | 128 | ||
| + | OK | ||
| + | 255 | ||
| + | | ||
| + | 255 | ||
| + | OK | ||
| + | 256 | ||
| + | [1,0] | ||
| + | 256 | ||
| + | OK | ||
| + | 257 | ||
| + | [1,1] | ||
| + | 257 | ||
| + | OK | ||
| + | 258 | ||
| + | [1,2] | ||
| + | 258 | ||
| + | OK | ||
| + | -127 | ||
| + | [129] | ||
| + | -127 | ||
| + | OK | ||
| + | -128 | ||
| + | [128] | ||
| + | -128 | ||
| + | OK | ||
| + | -129 | ||
| + | | ||
| + | -129 | ||
| + | OK | ||
| + | -130 | ||
| + | | ||
| + | -130 | ||
| + | OK | ||
| + | -255 | ||
| + | | ||
| + | -255 | ||
| + | OK | ||
| + | -256 | ||
| + | | ||
| + | -256 | ||
| + | OK | ||
| + | -257 | ||
| + | | ||
| + | -257 | ||
| + | OK | ||
| + | -258 | ||
| + | | ||
| + | -258 | ||
| + | OK | ||
| + | 127 | ||
| + | [127] | ||
| + | 127 | ||
| + | OK | ||
| + | 128 | ||
| + | | ||
| + | 128 | ||
| + | OK | ||
| + | 255 | ||
| + | | ||
| + | 255 | ||
| + | OK | ||
| + | 256 | ||
| + | [1,0] | ||
| + | 256 | ||
| + | OK | ||
| + | 257 | ||
| + | [1,1] | ||
| + | 257 | ||
| + | OK | ||
| + | 258 | ||
| + | [1,2] | ||
| + | 258 | ||
| + | OK | ||
| + | -127 | ||
| + | [129] | ||
| + | -127 | ||
| + | OK | ||
| + | -128 | ||
| + | [128] | ||
| + | -128 | ||
| + | OK | ||
| + | -255 | ||
| + | | ||
| + | -255 | ||
| + | OK | ||
| + | -256 | ||
| + | | ||
| + | -256 | ||
| + | OK | ||
| + | -257 | ||
| + | | ||
| + | -257 | ||
| + | OK | ||
| + | -258 | ||
| + | | ||
| + | -258 | ||
| + | OK | ||
| + | | ||
| + | | ||
