Here is the C++ code
#include <cstdio>
int main(void){
for(;;){
int x;
int code=fread(&x,sizeof(x),1,stdin);
if(code!=1)break;
printf("%08x\n",x);
}
}
and here is the Haskell code
module Main where{
import Data.Binary.Get;
import qualified Data.ByteString.Lazy as B;
import Data.Word;
import Text.Printf;
import Data.Int;
takes :: Int64 -> B.ByteString -> [B.ByteString];
takes n s = let {
(x,y) = B.splitAt n s;
{- The implementation of splitAt suggests that it is
better to call splitAt than take and drop separately -}
}
in if (B.length x == n) then
(x : (takes n y)) else [];
{- ignore if less than four bytes left over -}
readWord :: B.ByteString -> Word32;
readWord = runGet getWord32host;
main::IO();
main = B.getContents >>=
mapM_ (printf "%08x\n") . map readWord . takes 4;
}
It took a while to achieve this. I wanted lazy IO (do not read the entire input into memory), ignore leftover bytes at the end, and works OK when run interactively.
Update: a better version
module Main where{
import Data.Binary.Get;
import qualified Data.ByteString.Lazy as B;
import Data.Word;
import Text.Printf;
import System.IO;
readWord :: B.ByteString -> Word32;
readWord = runGet getWord32host;
main::IO();
main = catch (sequence_ $ repeat $ do { x <- B.hGet stdin 4;
if (B.length x/=4) then (fail "done") else
printf "%08x\n" (readWord x);} ) (const $ return ());
}
No comments :
Post a Comment