packages feed

binary-file 0.12.8 → 0.13.1

raw patch · 8 files changed

+327/−229 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- File.Binary: cc :: Str a => [a] -> a
- File.Binary: class RetType r where type family Argument r
- File.Binary: class Str a
- File.Binary: dp :: Str a => Int -> a -> a
- File.Binary: empty :: Str a => a -> Bool
- File.Binary: fbs :: Str a => ByteString -> a
- File.Binary: fi :: Str a => Int -> Integer -> a
- File.Binary: fiBE :: Str a => Int -> Integer -> a
- File.Binary: fiiBE :: Str a => Int -> Int -> a
- File.Binary: fromType :: (RetType r, Str s) => Argument r -> r -> s
- File.Binary: fs :: Str a => String -> a
- File.Binary: len :: Str a => a -> Int
- File.Binary: rev :: Str a => a -> a
- File.Binary: tbs :: Str a => a -> ByteString
- File.Binary: ti :: Str a => a -> Integer
- File.Binary: tiBE :: Str a => a -> Integer
- File.Binary: tiiBE :: Str a => Int -> a -> (Int, a)
- File.Binary: tk :: Str a => Int -> a -> a
- File.Binary: toType :: (RetType r, Str s) => Argument r -> s -> (r, s)
- File.Binary: ts :: Str a => a -> String
- File.Binary: zero :: Str a => a
- File.Binary.Data.BigEndian: instance RetType Int
- File.Binary.Data.LittleEndian: instance RetType Int
+ File.Binary: class Binary a
+ File.Binary: class Field r where type family FieldArgument r
+ File.Binary: concatBinary :: Binary a => [a] -> a
+ File.Binary: emptyBinary :: Binary a => a -> Bool
+ File.Binary: fromBinary :: (Field r, Binary s) => FieldArgument r -> s -> (r, s)
+ File.Binary: getBytes :: Binary a => Int -> a -> (ByteString, a)
+ File.Binary: makeBinary :: Binary a => ByteString -> a
+ File.Binary: toBinary :: (Field r, Binary s) => FieldArgument r -> r -> s
+ File.Binary.Data.BigEndian: instance Field Int
+ File.Binary.Data.BigEndian: lintToBin :: Int -> Integer -> String
+ File.Binary.Data.LittleEndian: instance Field Int
- File.Binary: fii :: Str a => Int -> Int -> a
+ File.Binary: fii :: Binary a => Int -> Int -> a
- File.Binary: tii :: Str a => Int -> a -> (Int, a)
+ File.Binary: tii :: Binary a => Int -> a -> (Int, a)

Files

binary-file.cabal view
@@ -2,7 +2,7 @@ cabal-version:	>= 1.8  name:		binary-file-version:	0.12.8+version:	0.13.1 stability:	experimental author:		Yoshikuni Jujo <PAF01143@nifty.ne.jp> maintainer:	Yoshikuni Jujo <PAF01143@nifty.ne.jp>@@ -14,65 +14,56 @@ synopsis:	read/write binary file description: -    > runghc -XQuasiQuotes exam.hs some.bmp out.bmp+    > runghc -XQuasiQuotes -XTypeFamilies -XFlexibleInstances exam.hs some.bmp     .     exam.hs:     .     > import File.Binary     > import File.Binary.Data.LittleEndian     > import System.Environment-    > import Data.ByteString as BS+    > import Data.ByteString.Lazy as BSL     >     > main = do-    >	[inf, outf] <- getArgs-    >+    >	[inf] <- getArgs     >   cnt <- BS.readFile inf-    >	let bmp = readBitmap $ cnt `BS.append` replicate 20 ' '+    >	let (bmp, rest) = fromBinary () cnt :: (Bitmap, String)     >	print bmp     >-    >	let out = writeBitmap bmp {-    >		authorFirst = "Yoshikuni ",-    >		authorSecond = "Jujo      "-    >	 }-    >   BS.writeFile outf out-    >-    > instance RetType (Int, Int, Int) where-    >    type Argument (Int, Int, Int) = ()-    >    fromType _ (b, g, r) = cc $ [-    >        fromType 1 b, fromType 1 g, fromType 1 r, zero]-    >    toType _ str = let-    >        (b, rest) = toType 1 str+    > instance Field (Int, Int, Int) where+    >    type FieldArgument (Int, Int, Int) = ()+    >    fromBinary _ s = let+    >        (b, rest) = toType 1 s     >        (g, rest') = toType 1 rest     >        (r, rest'') = toType 1 rest' in-    >        ((b, g, r), dp 1 rest'')+    >        ((b, g, r), snd $ getBytes 1 1 rest'')+    >    toBinary _ (b, g, r) = concatBinary [+    >        fromType 1 b, fromType 1 g, fromType 1 r,+    >        makeBinary $ BSL.singleton 0]     >     > [binary|     >     > Bitmap     >     > 2: "BM"-    > 4: fileSize+    > 4: file_size     > 2: 0     > 2: 0     > 4: offset     >     > 4: 40-    > 4: bitmapWidth-    > 4: bitmapHeight+    > 4: width+    > 4: height     > 2: 1-    > 2: bitsPerPixel-    > 4: compressionMethod-    > 4: imageSize-    > 4: horizontalResolution-    > 4: verticalResolution-    > 4: numberOfColors-    > 4: importantColors-    > ((), Just numberOfColors)<[(Int, Int, Int)]>: colors-    > imageSize<BS.ByteString>: image+    > 2: bits_per_pixel+    > 4: compression+    > 4: image_size+    > 4: resolutionH+    > 4: resolutionV+    > 4: color_num+    > 4: important_color_num+    > ((), Just color_num)<[(Int, Int, Int)]>: colors+    > ((), image_size)<String>: image     >-    > ((), Just 10)<String>: authorFirst-    > ((), Just 10)<String>: authorSecond-    >      > |]     . @@ -85,7 +76,7 @@ source-repository	this     type:	git     location:	git://github.com/YoshikuniJujo/binary-file.git-    tag:	0.12.7+    tag:	0.13.1  library     hs-source-dirs:	src
examples/readPNG.hs view
@@ -5,35 +5,104 @@ import System.Environment import Data.Word import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as BSC+import qualified Data.ByteString.Lazy as BSL+import qualified Data.ByteString.Lazy.Char8 as BSLC+import Codec.Compression.Zlib+import CRC (crc)+import Control.Applicative  main = do 	[fin, fout] <- getArgs-	cnt <- readBinaryFile fin-	let (png, rest) = readPNG () cnt-	print $ png-	writeBinaryFile fout $ writePNG () png+--	cnt <- readBinaryFile fin+	cnt <- BS.readFile fin+	let (png, rest) = fromBinary () cnt -test = readPNG () `fmap` readBinaryFile "tmp/out.png"+	putStrLn $ take 1000 (show png) ++ "..." -instance RetType Word32 where-	type Argument Word32 = Int-	fromType n = rev . fi n . fromIntegral-	toType n s = (fromIntegral $ ti $ rev $ tk n s, dp n s)+--	writeBinaryFile fout $ toBinary () png+--	BS.writeFile fout $ writePNG () png -instance RetType Chank where-	type Argument Chank = ()-	fromType = writeChank-	toType = readChank+	let	ChankIDAT idt = chankData $ chanks png !! 6+		dat = idat idt+{- ---+		dec = decompress dat+		recomp = compressWith defaultCompressParams {+			compressLevel = bestCompression,+--			compressLevel = bestSpeed,+			compressWindowBits = WindowBits 15+		 } dec+{-+	print $ length dat+	print $ length recomp+-} -instance RetType (Int, Int, Int) where-	type Argument (Int, Int, Int) = ()-	fromType _ (b, g, r) = cc [fromType 1 b, fromType 1 g, fromType 1 r]-	toType _ s = let-		(b, rest) = toType 1 s-		(g, rest') = toType 1 rest-		(r, rest'') = toType 1 rest' in-		((b, g, r), rest'')+	let	chank6 = chanks png !! 6+		newDat = chank6 {+			chankSize = fromIntegral $ BSL.length recomp,+			chankData = ChankIDAT $ IDAT recomp,+			chankCRC = crc $ "IDAT" ++ BSL.unpack recomp+		 }+		new = png {+			chanks = take 6 (chanks png) ++ [newDat] +++				drop 7 (chanks png)+		 }+{-+	print new+-} +	print $ dat == recomp+--- -}++--	BS.writeFile fout $ toBinary () new++	let	dat = makeData png+		decomp = decompress dat+		recomp = compressWith defaultCompressParams {+			compressLevel = bestCompression,+--			compressLevel = bestSpeed,+			compressWindowBits = WindowBits 10+		 } decomp+		newData = makeDataChank recomp+		newnew = png {+			chanks = headerChanks png ++ newData +++				footerChanks png+		 }+{-+		newnew = png {+			chanks = head (chanks png) : newData +++				[last $ chanks png]+		 }+-}+	BS.writeFile fout $ toBinary () newnew+	print $ dat == recomp++headerChanks :: PNG -> [Chank]+headerChanks PNG{ chanks = cs } =+	filter ((`notElem` ["IEND", "IDAT"]) . chankName) cs++footerChanks :: PNG -> [Chank]+footerChanks PNG{ chanks = cs } = filter ((== "IEND") . chankName) cs++makeData :: PNG -> BSL.ByteString+makeData PNG{ chanks = cs } =+	BSL.concat $ map (idat . cidat . chankData) $+		filter ((== "IDAT") . chankName) cs++makeDataChank :: BSL.ByteString -> [Chank]+makeDataChank = map makeOneDataChank . BSL.toChunks++makeOneDataChank :: BS.ByteString -> Chank+makeOneDataChank bs = Chank {+	chankSize = fromIntegral $ BS.length bs,+	chankName = "IDAT",+	chankData = ChankIDAT $ IDAT $ BSL.fromChunks [bs],+	chankCRC = crc $ "IDAT" ++ BSC.unpack bs+ }++test :: IO PNG+test = fst . fromBinary () <$> readBinaryFile "tmp/sample.png"+ [binary|  PNG@@ -47,6 +116,38 @@  |] +[binary|++Chank++4: chankSize+((), Just 4)<String>: chankName+(chankSize, chankName)<ChankBody>: chankData+4<Word32>:chankCRC++|]++instance Field Word32 where+	type FieldArgument Word32 = Int+	toBinary n = makeBinary . BSLC.pack . reverse . lintToBin n . fromIntegral+	fromBinary n s = (fromIntegral $ toIntgr $ BSL.reverse t, d)+		where+		(t, d) = getBytes n s++instance Field BSL.ByteString where+	type FieldArgument BSL.ByteString = Int+	toBinary _ = makeBinary -- . BS.concat . BSL.toChunks+	fromBinary n s = (t, d) -- (BSL.fromChunks [t], d)+		where+		(t, d) = getBytes n s++toIntgr :: BSL.ByteString -> Integer+toIntgr = mkNum . map fromIntegral . BSL.unpack++mkNum :: [Integer] -> Integer+mkNum [] = 0+mkNum (x : xs) = x + 2 ^ 8 * mkNum xs+ data ChankBody 	= ChankIHDR IHDR 	| ChankGAMA GAMA@@ -54,59 +155,47 @@ 	| ChankCHRM CHRM 	| ChankPLTE PLTE 	| ChankBKGD BKGD-	| ChankIDAT IDAT+	| ChankIDAT { cidat :: IDAT } 	| ChankTEXT TEXT 	| ChankIEND IEND 	| Others String 	deriving Show -instance RetType ChankBody where-	type Argument ChankBody = (Int, String)-	fromType _ (ChankIHDR ihdr) = writeIHDR () ihdr-	fromType _ (ChankGAMA gama) = writeGAMA () gama-	fromType _ (ChankSRGB srgb) = writeSRGB () srgb-	fromType _ (ChankCHRM chrm) = writeCHRM () chrm-	fromType (n, _) (ChankPLTE plte) = writePLTE n plte-	fromType _ (ChankBKGD bkgd) = writeBKGD () bkgd-	fromType (n, _) (ChankIDAT idat) = writeIDAT n idat-	fromType (n, _) (ChankTEXT text) = writeTEXT n text-	fromType _ (ChankIEND iend) = writeIEND () iend-	fromType (n, _) (Others str) = fromType ((), Just n) str-	toType (_, "IHDR") str = let (ihdr, rest) = readIHDR () str in+instance Field ChankBody where+	type FieldArgument ChankBody = (Int, String)+	toBinary _ (ChankIHDR ihdr) = toBinary () ihdr+	toBinary _ (ChankGAMA gama) = toBinary () gama+	toBinary _ (ChankSRGB srgb) = toBinary () srgb+	toBinary (n, _) (ChankCHRM chrm) = toBinary n chrm+	toBinary (n, _) (ChankPLTE plte) = toBinary n plte+	toBinary _ (ChankBKGD bkgd) = toBinary () bkgd+	toBinary (n, _) (ChankIDAT idat) = toBinary n idat+	toBinary (n, _) (ChankTEXT text) = toBinary n text+	toBinary _ (ChankIEND iend) = toBinary () iend+	toBinary (n, _) (Others str) = toBinary ((), Just n) str+	fromBinary (_, "IHDR") str = let (ihdr, rest) = fromBinary () str in 		(ChankIHDR ihdr, rest)-	toType (_, "gAMA") str = let (gama, rest) = readGAMA () str in+	fromBinary (_, "gAMA") str = let (gama, rest) = fromBinary () str in 		(ChankGAMA gama, rest)-	toType (_, "sRGB") str = let (srgb, rest) = readSRGB () str in+	fromBinary (_, "sRGB") str = let (srgb, rest) = fromBinary () str in 		(ChankSRGB srgb, rest)-	toType (_, "cHRM") str = let (chrm, rest) = readCHRM () str in+	fromBinary (n, "cHRM") str = let (chrm, rest) = fromBinary n str in 		(ChankCHRM chrm, rest)-	toType (n, "PLTE") str = let (plte, rest) = readPLTE n str in+	fromBinary (n, "PLTE") str = let (plte, rest) = fromBinary n str in 		(ChankPLTE plte, rest)-	toType (_, "bKGD") str = let (bkgd, rest) = readBKGD () str in+	fromBinary (_, "bKGD") str = let (bkgd, rest) = fromBinary () str in 		(ChankBKGD bkgd, rest)-	toType (n, "IDAT") str = let (idat, rest) = readIDAT n str in+	fromBinary (n, "IDAT") str = let (idat, rest) = fromBinary n str in 		(ChankIDAT idat, rest)-	toType (n, "tEXt") str = let (text, rest) = readTEXT n str in+	fromBinary (n, "tEXt") str = let (text, rest) = fromBinary n str in 		(ChankTEXT text, rest)-	toType (_, "IEND") str = let (iend, rest) = readIEND () str in+	fromBinary (_, "IEND") str = let (iend, rest) = fromBinary () str in 		(ChankIEND iend, rest)-	toType (n, _) str = let (others, rest) = toType ((), Just n) str in+	fromBinary (n, _) str = let (others, rest) = fromBinary ((), Just n) str in 		(Others others, rest)  [binary| -Chank--4: chankSize-((), Just 4)<String>: chankName-(chankSize, chankName)<ChankBody>: chankData--- ((), Just chankSize)<String>: chankData-4<Word32>:chankCRC--|]--[binary|- IHDR  4: width@@ -139,15 +228,10 @@  CHRM -4: chrm1-4: chrm2-4: chrm3-4: chrm4-4: chrm5-4: chrm6-4: chrm7-4: chrm8+<Int> +(4, Just (arg `div` 4))<[Int]>: chrms+ |]  [binary|@@ -160,6 +244,15 @@  |] +instance Field (Int, Int, Int) where+	type FieldArgument (Int, Int, Int) = ()+	toBinary _ (b, g, r) = concatBinary [toBinary 1 b, toBinary 1 g, toBinary 1 r]+	fromBinary _ s = let+		(b, rest) = fromBinary 1 s+		(g, rest') = fromBinary 1 rest+		(r, rest'') = fromBinary 1 rest' in+		((b, g, r), rest'')+ [binary|  BKGD@@ -174,7 +267,8 @@  <Int> -arg<BS.ByteString>: idat+arg<BSL.ByteString>: idat+--((), Just arg)<String>: idat  |] @@ -188,8 +282,4 @@  |] -[binary|--IEND--|]+[binary|IEND|]
src/Classes.hs view
@@ -1,20 +1,23 @@ {-# LANGUAGE-	TemplateHaskell, 	TypeSynonymInstances, 	FlexibleInstances, 	TypeFamilies, 	OverloadedStrings #-}  module Classes (-	RetType(..),-	Str(..),-	fii, fiiBE,-	tii, tiiBE,-	readInt+	Field(..),+	Binary(..),+	fii, tii,+	readInt,+	dp, fs, ti, cc,+	lintToBin ) where  import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BSL+import qualified Data.ByteString.Lazy.Char8 as BSLC import Data.Char+import Control.Arrow  data Endian = BigEndian | LittleEndian deriving Show @@ -23,85 +26,82 @@ readInt LittleEndian (c : cs) = fromIntegral (ord c) + 2 ^ (8 :: Integer) * readInt LittleEndian cs readInt BigEndian str = readInt LittleEndian $ reverse str -class RetType r where-	type Argument r-	fromType :: Str s => Argument r -> r -> s-	toType :: Str s => Argument r -> s -> (r, s)+class Field r where+	type FieldArgument r+	fromBinary :: Binary s => FieldArgument r -> s -> (r, s)+	toBinary :: Binary s => FieldArgument r -> r -> s -instance RetType r => RetType [r] where-	type Argument [r] = (Argument r, Maybe Int)-	fromType (a, _) rs = cc $ map (fromType a) rs-	toType (a, Just b) s = (b `times` toType a) s-	toType (a, Nothing) s = whole (toType a) s+instance Field r => Field [r] where+	type FieldArgument [r] = (FieldArgument r, Maybe Int)+	fromBinary (a, Just b) s = (b `times` fromBinary a) s+	fromBinary (a, Nothing) s = whole (fromBinary a) s+	toBinary (a, _) rs = cc $ map (toBinary a) rs -instance RetType Char where-	type Argument Char = ()-	fromType _ = fs . (: [])-	toType _ str = (head $ ts str, dp 1 str)+instance Field Char where+	type FieldArgument Char = ()+	fromBinary _ str = (head $ BSLC.unpack t, d)+		where+		(t, d) = getBytes 1 str+	toBinary _ = fs . (: []) -instance RetType BS.ByteString where-	type Argument BS.ByteString = Int-	fromType _ = fbs-	toType n str = (tbs $ tk n str, dp n str)+instance Field BS.ByteString where+	type FieldArgument BS.ByteString = Int+	fromBinary n str =+		first (BS.concat . BSL.toChunks) $ getBytes n str+	toBinary _ = makeBinary . BSL.fromChunks . (: []) -class Str a where-	tk :: Int -> a -> a-	dp :: Int -> a -> a-	ts :: a -> String-	fs :: String -> a-	fbs :: BS.ByteString -> a-	tbs :: a -> BS.ByteString-	ti :: a -> Integer-	fi :: Int -> Integer -> a-	tiBE :: a -> Integer-	fiBE :: Int -> Integer -> a-	cc :: [a] -> a-	zero :: a-	len :: a -> Int-	empty :: a -> Bool-	rev :: a -> a+class Binary a where+	getBytes :: Int -> a -> (BSL.ByteString, a)+	makeBinary :: BSL.ByteString -> a+	concatBinary :: [a] -> a+	emptyBinary :: a -> Bool -instance Str String where-	tk = take-	dp = drop-	ts = id-	fs = id-	fbs = ts-	tbs = fs-	ti = readInt LittleEndian-	fi = intToBin LittleEndian-	tiBE = readInt BigEndian-	fiBE = intToBin BigEndian-	cc = concat-	zero = "\0"-	len = length-	empty = null-	rev = reverse+empty :: Binary a => a -> Bool+empty = emptyBinary -fii, fiiBE :: Str a => Int -> Int -> a-fii n = fi n . fromIntegral-fiiBE n = fiBE n . fromIntegral-tii, tiiBE :: Str a => Int -> a -> (Int, a)-tii _ str = (fromIntegral $ ti $ tk 4 str, dp 4 str)-tiiBE _ str = (fromIntegral $ tiBE $ tk 4 str, dp 4 str)+cc :: Binary a => [a] -> a+cc = concatBinary -instance Str BS.ByteString where-	tk = BS.take-	dp = BS.drop-	ts = map (chr . fromIntegral) . BS.unpack-	fs = BS.pack . map (fromIntegral . ord)-	fbs = id-	tbs = id-	ti = readInt LittleEndian . map (chr . fromIntegral) . BS.unpack-	fi n = BS.pack . map (fromIntegral . ord) . intToBin LittleEndian n-	tiBE = readInt BigEndian . map (chr . fromIntegral) . BS.unpack-	fiBE n = BS.pack . map (fromIntegral . ord) . intToBin BigEndian n-	cc = BS.concat-	zero = BS.singleton 0-	len = BS.length-	empty = (== 0) . BS.length-	rev = BS.reverse+ti :: Binary a => a -> Integer+ti = readInt LittleEndian . BSLC.unpack . fst . getBytes 100 +fs :: Binary a => String -> a+fs = makeBinary . BSLC.pack++dp :: Binary a => Int -> a -> a+dp n = snd . getBytes n++instance Binary String where+	getBytes n = BSLC.pack . take n &&& drop n+	makeBinary = BSLC.unpack++	concatBinary = concat+	emptyBinary = null++fii :: Binary a => Int -> Int -> a+fii n = makeBinary . BSLC.pack . intToBin LittleEndian n . fromIntegral+tii :: Binary a => Int -> a -> (Int, a)+tii _ str = let+	(t, d) = getBytes 4 str in+	(fromIntegral $ ti t, d)++instance Binary BSL.ByteString where+	getBytes n = BSL.take (fromIntegral n) &&& BSL.drop (fromIntegral n)+	makeBinary = id++	concatBinary = BSL.concat+	emptyBinary = (== 0) . BSL.length++instance Binary BS.ByteString where+	getBytes n = BSL.fromChunks . (: []) . BS.take n &&& BS.drop n+	makeBinary = BS.concat . BSL.toChunks++	concatBinary = BS.concat+	emptyBinary = (== 0) . BS.length++lintToBin :: Int -> Integer -> String+lintToBin = intToBin LittleEndian+ intToBin :: Endian -> Int -> Integer -> String intToBin LittleEndian 0 _ = "" intToBin LittleEndian n x = chr (fromIntegral $ x `mod` 256) :@@ -115,7 +115,7 @@ 	(rets, rest') = times (n - 1) f rest in 	(ret : rets, rest') -whole :: Str s => (s -> (ret, s)) -> s -> ([ret], s)+whole :: Binary s => (s -> (ret, s)) -> s -> ([ret], s) whole f s 	| empty s = ([], s) 	| otherwise = let
src/File/Binary.hs view
@@ -2,10 +2,10 @@ 	readBinaryFile, 	writeBinaryFile, 	binary,-	RetType(..),-	Str(..),-	tii, tiiBE,-	fii, fiiBE+	Field(..),+	Binary(..),+	tii, -- tiiBE,+	fii, -- fiiBE --	times  ) where 
src/File/Binary/Data/BigEndian.hs view
@@ -1,12 +1,15 @@-{-# LANGUAGE TemplateHaskell, TypeFamilies #-}+{-# LANGUAGE TypeFamilies #-} -module File.Binary.Data.BigEndian where+module File.Binary.Data.BigEndian (+	lintToBin+) where  import Classes+import qualified Data.ByteString.Lazy.Char8 as BSLC  -- retTypeInt BigEndian -instance RetType Int where-	type Argument Int = Int-	fromType n = rev . fi n . fromIntegral-	toType n s = (fromIntegral $ ti $ rev $ tk n s, dp n s)+instance Field Int where+	type FieldArgument Int = Int+	fromBinary n s = (fromIntegral $ ti $ BSLC.reverse $ fst $ getBytes n s, dp n s)+	toBinary n = makeBinary . BSLC.pack . reverse . lintToBin n . fromIntegral
src/File/Binary/Data/LittleEndian.hs view
@@ -1,12 +1,15 @@-{-# LANGUAGE TemplateHaskell, TypeFamilies #-}+{-# LANGUAGE TypeFamilies #-}  module File.Binary.Data.LittleEndian where  import Classes+import qualified Data.ByteString.Lazy.Char8 as BSLC  -- retTypeInt LittleEndian -instance RetType Int where-	type Argument Int = Int-	fromType n = fi n . fromIntegral-	toType n s = (fromIntegral $ ti $ tk n s, dp n s)+instance Field Int where+	type FieldArgument Int = Int+	fromBinary n s = (fromIntegral $ ti t, d)+		where+		(t, d) = getBytes n s+	toBinary n = makeBinary . BSLC.pack . reverse . lintToBin n . fromIntegral
src/ParseBinaryStructure.hs view
@@ -20,10 +20,11 @@ 	valueOf,  	Expression,-	Str(..),-	RetType(..),-	fii, fiiBE,-	tii, tiiBE+	Binary(..),+	Field(..),+	fii, -- fiiBE,+	tii, -- tiiBE,+	dp, fs, cc ) where  import Text.Peggy
src/QuoteBinaryStructure.hs view
@@ -7,10 +7,10 @@  module QuoteBinaryStructure ( 	binary,-	RetType(..),-	Str(..),-	fii, fiiBE,-	tii, tiiBE,+	Field(..),+	Binary(..),+	fii, -- fiiBE,+	tii, -- tiiBE, 	times ) where @@ -21,6 +21,7 @@ import Data.Traversable hiding (mapM) import Data.Either import Data.Maybe+import qualified Data.ByteString.Lazy.Char8 as BSLC  import ParseBinaryStructure @@ -35,20 +36,28 @@ mkHaskellTree :: BinaryStructure -> DecsQ mkHaskellTree bs = do 		d <- mkData bsn body-		r <- mkReader bsn body-		w <- mkWriter bsn body-		return $ d ++ [r, w]+		i <- mkInst bsn typ body+		return $ d ++ [i] 	where 	bsn = binaryStructureName bs+	typ = binaryStructureArgType bs 	body = binaryStructureBody bs -mkWriter :: String -> [BinaryStructureItem] -> DecQ-mkWriter bsn body = do+mkInst :: String -> TypeQ -> [BinaryStructureItem] -> DecQ+mkInst bsn typ body =+	instanceD (cxt []) (appT (conT ''Field) (conT $ mkName bsn)) [+		tySynInstD ''FieldArgument [conT $ mkName bsn] typ,+		reading "fromBinary" bsn body,+		writing "toBinary" body+	 ]++writing :: String -> [BinaryStructureItem] -> DecQ+writing name body = do 	arg <- newName "arg" 	bs <- newName "bs" 	let run = appE (varE 'cc) $ listE $ map 		(\bsi -> writeField bs arg (bytesOf bsi) (valueOf bsi)) body-	funD (mkName $ "write" ++ bsn)+	funD (mkName name) 		[clause [varP arg, varP bs] (normalB run) []]  writeField :: Name -> Name -> Expression -> Either (Either Int String) String -> ExpQ@@ -56,7 +65,7 @@ 	appsE [fiend', expression bs arg size, sigE (litE $ integerL $ fromIntegral n) 		(conT ''Int)] 	where-	fiend' = varE 'fromType+	fiend' = varE 'toBinary writeField _ _ _ (Left (Right s)) = 	appsE [varE 'fs, litE $ stringL s] writeField bs arg bytes (Right v) =@@ -64,19 +73,18 @@  fieldValueToStr :: Name -> Name -> Expression -> Bool -> ExpQ -> ExpQ fieldValueToStr bs arg size False =-	appE $ appE (varE 'fromType) (expression bs arg size)+	appE $ appE (varE 'toBinary) (expression bs arg size) fieldValueToStr bs arg size True = \val -> 	appE (varE 'cc) $ appsE [-		varE 'map, appE (varE 'fromType) (expression bs arg size), val]+		varE 'map, appE (varE 'toBinary) (expression bs arg size), val] -mkReader :: String -> [BinaryStructureItem] -> DecQ-mkReader bsn body = do+reading :: String -> String -> [BinaryStructureItem] -> DecQ+reading name bsn body = do 	arg <- newName "arg" 	cs <- newName "cs" 	ret <- newName "ret"-	funD (mkName $ "read" ++ bsn)-		[clause [varP arg, varP cs] (normalB $ mkLetRec ret $-			mkBody bsn arg body cs) []]+	funD (mkName name) [clause [varP arg, varP cs]+		(normalB $ mkLetRec ret $ mkBody bsn arg body cs) []]  mkLetRec :: Name -> (Name -> ExpQ) -> ExpQ mkLetRec n f = do@@ -97,10 +105,11 @@ 	mkDef np item cs' 	    | Left (Left val) <- valueOf item = do 		cs'' <- newName "cs"-		let t = dropE' n $ varE cs'-		let p = val `equal` appE (varE 'fst)-			(appE (appE (varE 'toType) arg') $ takeE' n $ varE cs')-		let e = [e| error "bad value" |]+		let	t = dropE' n $ varE cs'+			p = val `equal` appE (varE 'fst)+				(appE (appE (varE 'fromBinary) arg') $+					takeE' n $ varE cs')+			e = [e| error "bad value" |] 		d <- valD (varP cs'') (normalB $ condE p t e) [] 		return ([d], cs'') 	    | Left (Right val) <- valueOf item = do@@ -113,7 +122,7 @@ 	    | Right var <- valueOf item = do 		cs'' <- newName "cs" 		def <- valD (tupP [varP $ fromJust $ lookup var np, varP cs''])-			(normalB $ appE (appE (varE 'toType) arg') $ varE cs') []+			(normalB $ appE (appE (varE 'fromBinary) arg') $ varE cs') [] 		return ([def], cs'') 	    | otherwise = error "bad" 	    where@@ -134,7 +143,8 @@ equal' x y = infixE (Just $ litE $ stringL x) (varE '(==)) (Just y)  takeE' :: ExpQ -> ExpQ -> ExpQ-takeE' n xs = appE (varE 'ts) $ appsE [varE 'tk, n, xs]+takeE' n xs = -- appE (varE 'ts) $ appsE [varE 'tk, n, xs]+	appE (varE 'BSLC.unpack) $ appE (varE 'fst) $ appsE [varE 'getBytes, n, xs]  dropE' :: ExpQ -> ExpQ -> ExpQ dropE' n xs = appsE [varE 'dp, n, xs]@@ -148,10 +158,10 @@  mkInstance :: String -> DecQ mkInstance name =-	instanceD (cxt []) (appT (conT ''RetType) (conT $ mkName name)) [-		valD (varP $ 'fromType)+	instanceD (cxt []) (appT (conT ''Field) (conT $ mkName name)) [+		valD (varP $ 'toBinary) 			(normalB $ varE $ mkName $ "write" ++ name) [],-		valD (varP $ 'toType)+		valD (varP $ 'fromBinary) 			(normalB $ varE $ mkName $ "read" ++ name) [] 	 ]