module Text.Search.Sphinx.Get where
import Data.Binary.Get
import Data.Int (Int64)
import Prelude hiding (readList)
import Data.ByteString.Lazy hiding (pack, length, map, groupBy)
import Control.Monad
import Text.Search.Sphinx.Types
getNum :: Get Int
getNum = getWord32be >>= return . fromEnum
getNum64 :: Get Int64
getNum64 = getWord64be >>= return . fromIntegral
getNums = readList getNum
readList f = do num <- getNum
num `times` f
times = replicateM
readField = readStr
readStr = do len <- getNum
getLazyByteString (fromIntegral len)
getResult :: Get SearchResult
getResult = do
status <- getNum
fields <- readList readField
attrs <- readList readAttr
matchCount <- getNum
id64 <- getNum
matches <- matchCount `times` readMatch (id64 > 0) (map snd attrs)
[total, totalFound, time, numWords] <- 4 `times` getNum
wrds <- numWords `times` readWord
return (SearchResult matches total totalFound wrds)
readWord = do s <- readStr
[doc, hits] <- 2 `times` getNum
return (s, doc, hits)
readMatch isId64 attrs = do
doc <- if isId64 then getNum64 else (getNum >>= return . fromIntegral)
weight <- getNum
matchAttrs <- mapM readMatchAttr attrs
return $ Match doc weight matchAttrs
readMatchAttr AttrTFloat = error "readMatchAttr for AttrFloat not implemented yet."
readMatchAttr AttrTMulti = getNums >>= return . AttrMulti
readMatchAttr _ = getNum >>= return . AttrNum
readAttr = do
s <- readStr
t <- getNum
return (s, toEnum t)
readHeader = runGet $ do status <- getWord16be
version <- getWord16be
length <- getWord32be
return (status, version, length)