2011-10-26 7 views
0

長さエンコードされたバイナリストリームを解析しています。このコードをコンパイルしようとしています。コンビナトレーションコード(https://github.com/jlouis/combinatorrent/blob/master/src/Protocol/Wire.hs)は私の動きを助けるのにとても役に立ちましたが、今は固まっています。 return文でframe_lengthを使用するにはどうすればよいですか?Attoparsecの条件付き解析とキャスト

data FrameCont = FINAL | MORE | BADCONT 
    deriving (Show, Eq) 
frame_cont 0x00  = FINAL 
frame_cont 0x01  = MORE 
frame_cont otherwise = BADCONT 

data FrameSize = Small Word8 | Jumbo B.ByteString 
    deriving (Show) 

get_fc = do 
    raw_cont <- AP.anyWord8 
    guard((frame_cont raw_cont) /= BADCONT) AP.<?> "State must be either MORE or FINAL" 
    return raw_cont 

parser = do 
    frame_length <- AP.anyWord8 
    case frame_length of 
     0x255  -> return (Jumbo <$> AP.take 8, get_fc, AP.take (fromIntegral frame_length)) 
     otherwise -> return (Small otherwise, get_fc, AP.take (fromIntegral frame_length)) 

また、Word64にパス(AP.take 8)を使用するにはどうすればよいですか?

+0

これ以上のコンテキストがなければ、私たちは推測できます。 'parser'にはどのような型がありますか?それは何をすべきか?私が最後の質問を正しく理解していれば、 'AP.take 8 'から8バイトのByteStringを' foldl'(\ wb - >(shiftL w 8))を介して 'Word64 'に変換することができます。 fromInternet b)0。解凍する。 –

+0

私は先に進み、より多くの文脈を追加しました。私はWord8とByteStringの両方をカプセル化する型を持っています。私は将来、Word64にバイトコードを変更したいと思うでしょう。 – xrl

答えて

1

パーサーの2つのブランチの最初のコンポーネントは異なるタイプを持ち、JumboブランチはParser FrameSizeであり、もう1つは平文FrameSizeです。 parserのタイプがParser (Parser FrameSize, Parser Word8, Parser ByteString)の場合は、2番目のブランチの最初のコンポーネントをreturn (Small otherwise)に変更するだけです。しかし、parser :: Parser (FrameSize, Word8, ByteString)が必要な可能性が高いので、他のパーサーをparserの中で実行する必要があります。私は思う。

parser = do 
    frame_length <- AP.anyWord8 
    frame_size <- case frame_length of 
        0xFF -> Jumbo <$> AP.take 8 -- 0xFF == 255, 0x255 == 597 
        flen -> return (Small flen) 
    fc <- get_fc 
    bs <- AP.take (fromIntegral frame_length) 
    return (frame_size, fc, bs) 

は少なくともあなたが望むものに近い。

スタイルに関する注記:camelCaseとunderscore_separatedの単語を混ぜて、より良いものにします(Haskellの主なスタイルはcamelCaseですので、選択することをお勧めします)。

+0

彼はパターンを持っています:大文字の単語はCamelCaseを使用し、小文字の単語はuse_underscoresです。それは少し珍しいですが、矛盾していません。 – Zopa

+0

はい、一貫しています。彼の*コードで少なくとも。しかし、キャメルケースのライブラリ機能を使用することで、彼は両方のスタイルが混在しています。彼がアンダースコアをあまり好きでないなら、私は支配的なスタイルに従う方が良いと思う。 –