【发布时间】:2021-05-19 06:43:35
【问题描述】:
我正在构建一个从文件中读取 381 个字节并尝试解码输入的脚本。我对我标记为“预设”的那些字节中的 348 个感兴趣。预设的 ByteString 的 3 字节块可以解码成单个 Int16,下面的“值”是我感兴趣的 116 Int16...
decodeFile :: FilePath -> IO [Maybe PresetValue]
decodeFile filename =
do h <- openFile (dir ++ filename) ReadMode
header <- h `BL.hGet` 32
presets <- h `BL.hGet` 348
f7 <- h `BL.hGet` 1
let values = Bin.runGet getPresets presets
hClose h
return values
getPresets = do
empty <- Bin.isEmpty
if empty
then return []
else do p <- getAndDecodeTriple
ps <- getPresets
return (p:ps)
getAndDecodeTriple = do
b1 <- Bin.getWord8
b2 <- Bin.getWord8
b3 <- Bin.getWord8
return $ decode (b1,b2,b3)
我遇到的问题是解码一个 3 字节的块,因为我知道它是如何在 C++ 中编码的
这里是 C++ 编码
void SysexReader::sx_encode(int val, char* dest)
{
char encode;
// Encode Byte 1 (4 bits of payload)
encode = 0x40 | ((val >> 12) & 0x000F);
*dest++ = encode;
// Encode Byte 2 (6 bits of payload)
encode = (val >> 6) & 0x003F;
*dest++ = encode;
// Encode Byte 3 (6 bits of payload)
encode = val & 0x003F;
*dest = encode;
}
这是翻译成 Haskell 的 C++ 编码...
type Encoding a = (a,a,a)
type PresetValue = Int16
encode :: Integral a => PresetValue -> Encoding a
encode val =
let f = fromIntegral
in (f $ enc1 val, f $ enc2 val, f $ enc3 val)
where
enc1 = or40 . and000F . (flip shiftR 12)
where and000F = (0x000F .&.)
or40 = (0x40 .|.)
enc2 = enc3 . flip shiftR 6
enc3 = (0x003F .&.)
我的解码尝试使用了我有编码程序并且我知道 PresetValue 只能在 (0,127) 范围内的事实
-- (3 Sysex Bytes) -> (Preset Value) --
-------------------------------------------------------
decode :: Integral a => (a,a,a) -> Maybe PresetValue
decode encoded =
case match of
[value] -> Just value
[] -> Nothing --error "encode not surjective"
many -> error "encode not injective"
where
match = filter (\x -> encode x == encoded) [0..127]
很遗憾,我无法解码所有值,正如您从下面的 116 条目列表中看到的那样,很多地方都没有包含任何内容。
[Just 14,Just 84,Just 97,Just 117,Just 114,Just 117,Just 115,Just 32,Just 73,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Nothing,Nothing,Just 0,Nothing,Nothing,Nothing,Just 0,Nothing,Nothing,Just 0,Just 0,Nothing,Nothing,Just 0,Just 1,Nothing,Just 0,Nothing,Nothing,Just 0,Just 0,Just 0,Just 1,
Just 0,Just 0,Nothing,Just 5,Just 0,Just 1,Just 0,Just 0,Just 0,Nothing,Nothing,
Just 3,Just 2,Just 0,Just 0,Nothing,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Nothing,Nothing,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Just 0,Nothing]
我做错了什么?我觉得它一定是我用来表示传入文件中每个块的类型。或者也许我正在使用 fromIntegral 丢失信息。
我已经做了一段时间的开发人员,从来没有在这里发布过问题,并且一直在努力寻找答案,但我真的迷失了这个问题。谢谢。
【问题讨论】:
-
在某处插入
`mod` 256? -
我刚试过。不工作;我得到了一堆什么都没有。为什么这行得通?这可能会让我找到答案。
标签: haskell