PutをBitPutにするとflushされてしまう
Binary
処理が定義されているとします。
例えば、下記は1Byteの処理です。
> :t example_ColFlags example_ColFlags :: ColFlags > :t put example_ColFlags put example_ColFlags :: Put >
> BSL.writeFile "work\\colflags.bin" (runPut $ put example_ColFlags) >
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000: FF .
このようなPut
が定義されているときに、前後にbit
単位の処理を追加することを考えます。
joinPut
を使うと、直掩までのBit処理がflush
されてしまいます。
> let foo = putBool True >> (joinPut $ put (example_ColFlags ::ColFlags)) >> putBool True > BSL.writeFile "work\\colflags.bin" (runPut $ runBitPut foo) >
ここでは、1bitを出しているので、ゼロフィルされて80
が出力されてしまいます。この挙動はドキュメントに記載されています。
Run a Put inside BitPut. Any partially written bytes will be flushed before Put executes to ensure byte alignment.
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000: 80 FF 80 ...
flush
を避けるため、仕方がないので、バイト単位の処理はいったんByteString
にして、それをBit処理しました。
> let foo = putBool True >> (Bit.putByteString $ BSL.toStrict $ runPut $ put (example_ColFlags ::ColFlags)) >> putBool True > BSL.writeFile "work\\colflags.bin" (runPut $ runBitPut foo)
Offset: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000: FF C0 .@