summaryrefslogtreecommitdiff
path: root/haskell/src/Data/MessagePack/Stream.hs
blob: bd17f4678ed336b07abc81993e13ae06d29a12c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
--------------------------------------------------------------------
-- |
-- Module    : Data.MessagePack.Stream
-- Copyright : (c) Hideyuki Tanaka, 2009
-- License   : BSD3
--
-- Maintainer:  tanaka.hideyuki@gmail.com
-- Stability :  experimental
-- Portability: portable
--
-- Lazy Stream Serializers and Deserializers
--
--------------------------------------------------------------------

module Data.MessagePack.Stream(
  unpackObjects,
  unpackObjectsFromFile,
  unpackObjectsFromHandle,
  unpackObjectsFromString,
  ) where

import Control.Monad
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import System.IO
import System.IO.Unsafe

import Data.MessagePack.Base
import Data.MessagePack.Feed

-- | Unpack objects using given feeder.
unpackObjects :: Feeder -> IO [Object]
unpackObjects feeder = do
  up <- newUnpacker defaultInitialBufferSize
  f up
  where
  f up = unsafeInterleaveIO $ do
    mbo <- unpackOnce up
    case mbo of
      Just o -> do
        os <- f up
        return $ o:os
      Nothing ->
        return []

  unpackOnce up = do
    resp <- unpackerExecute up
    case resp of
      0 -> do
        r <- feedOnce up
        if r
          then unpackOnce up
          else return Nothing
      1 -> do
        obj <- unpackerData up
        freeZone =<< unpackerReleaseZone up
        unpackerReset up
        return $ Just obj
      _ ->
        error $ "unpackerExecute fails: " ++ show resp

  feedOnce up = do
    dat <- feeder
    case dat of
      Nothing ->
        return False
      Just bs -> do
        unpackerFeed up bs
        return True

-- | Unpack objects from file.
unpackObjectsFromFile :: FilePath -> IO [Object]
unpackObjectsFromFile fname =
  unpackObjects =<< feederFromFile fname

-- | Unpack objects from handle.
unpackObjectsFromHandle :: Handle -> IO [Object]
unpackObjectsFromHandle h =
  unpackObjects =<< feederFromHandle h
  
-- | Unpack oobjects from given byte sequence.
unpackObjectsFromString :: ByteString -> IO [Object]
unpackObjectsFromString bs =
  unpackObjects =<< feederFromString bs