diff options
| author | Roman Smrž <roman.smrz@seznam.cz> | 2019-05-02 22:12:11 +0200 | 
|---|---|---|
| committer | Roman Smrž <roman.smrz@seznam.cz> | 2019-05-02 22:12:11 +0200 | 
| commit | d6ae20e484eed27e5f7b9cb36905b529fdeec2fa (patch) | |
| tree | b7f1505017681e06b531e0fec1caa0756a4ec4b5 | |
| parent | 1c318c639bde0a1ed5520193044534860fc49b84 (diff) | |
Storage: parsing multiple objects from one bytestring
| -rw-r--r-- | src/Storage.hs | 19 | 
1 files changed, 13 insertions, 6 deletions
| diff --git a/src/Storage.hs b/src/Storage.hs index 3e12506..f1b6dd4 100644 --- a/src/Storage.hs +++ b/src/Storage.hs @@ -6,7 +6,7 @@ module Storage (      readRef, showRef,      Object(..), RecItem(..), -    serializeObject, deserializeObject, +    serializeObject, deserializeObject, deserializeObjects,      storeRawBytes, lazyLoadBytes,      Head, @@ -49,6 +49,7 @@ import Codec.Compression.Zlib  import qualified Codec.MIME.Type as MIME  import qualified Codec.MIME.Parse as MIME +import Control.Arrow  import Control.Exception  import Control.Monad  import Control.Monad.Except @@ -207,17 +208,18 @@ lazyLoadObject' ref@(Ref st rhash) = unsafePerformIO $ do      when (chash /= rhash) $ error $ "Hash mismatch on object " ++ BC.unpack (showRef ref) {- TODO throw -}      let obj = case runExcept $ deserializeObject st file of                     Left err -> error $ err ++ ", ref " ++ BC.unpack (showRef ref) {- TODO throw -} -                   Right x  -> x +                   Right (x, rest) | BL.null rest -> x +                                   | otherwise -> error $ "Superfluous content after " ++ BC.unpack (showRef ref) {- TODO throw -}      return (obj, file) -deserializeObject :: Storage -> BL.ByteString -> Except String Object -deserializeObject _  bytes | BL.null bytes = return ZeroObject +deserializeObject :: Storage -> BL.ByteString -> Except String (Object, BL.ByteString) +deserializeObject _  bytes | BL.null bytes = return (ZeroObject, bytes)  deserializeObject st bytes =      case BLC.break (=='\n') bytes of          (line, rest) | Just (otype, len) <- splitObjPrefix line -> do -            let content = BL.toStrict $ BL.drop 1 rest +            let (content, next) = first BL.toStrict $ BL.splitAt (fromIntegral len) $ BL.drop 1 rest              guard $ B.length content == len -            case otype of +            (,next) <$> case otype of                   _ | otype == BC.pack "blob" -> return $ Blob content                     | otype == BC.pack "rec" -> maybe (throwError $ "Malformed record item ")                                                     (return . Rec) $ sequence $ map parseRecLine $ BC.lines content @@ -249,6 +251,11 @@ deserializeObject st bytes =                            _   -> Nothing                return (name, val) +deserializeObjects :: Storage -> BL.ByteString -> Except String [Object] +deserializeObjects _  bytes | BL.null bytes = return [] +deserializeObjects st bytes = do (obj, rest) <- deserializeObject st bytes +                                 (obj:) <$> deserializeObjects st rest +  data Head = Head String Ref      deriving (Show) |