blob: 8fa060ea5c0fb370dfbe943bfc57cf3c2640bcdf [file] [log] [blame]
Bryan Duxbury0781f2b2009-04-07 23:29:42 +00001--
2-- Licensed to the Apache Software Foundation (ASF) under one
3-- or more contributor license agreements. See the NOTICE file
4-- distributed with this work for additional information
5-- regarding copyright ownership. The ASF licenses this file
6-- to you under the Apache License, Version 2.0 (the
7-- "License"); you may not use this file except in compliance
8-- with the License. You may obtain a copy of the License at
9--
10-- http://www.apache.org/licenses/LICENSE-2.0
11--
12-- Unless required by applicable law or agreed to in writing,
13-- software distributed under the License is distributed on an
14-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15-- KIND, either express or implied. See the License for the
16-- specific language governing permissions and limitations
17-- under the License.
18--
19
20module Thrift.Protocol
21 ( Protocol(..)
22 , skip
23 , MessageType(..)
24 , ThriftType(..)
25 , ProtocolExn(..)
26 , ProtocolExnType(..)
27 ) where
28
29import Control.Monad ( replicateM_, unless )
30import Control.Exception
31
32import Data.Typeable ( Typeable )
33import Data.Int
34
35import Thrift.Transport
36
37
38data ThriftType
39 = T_STOP
40 | T_VOID
41 | T_BOOL
42 | T_BYTE
43 | T_DOUBLE
44 | T_I16
45 | T_I32
46 | T_I64
47 | T_STRING
48 | T_STRUCT
49 | T_MAP
50 | T_SET
51 | T_LIST
52 deriving ( Eq )
53
54instance Enum ThriftType where
55 fromEnum T_STOP = 0
56 fromEnum T_VOID = 1
57 fromEnum T_BOOL = 2
58 fromEnum T_BYTE = 3
59 fromEnum T_DOUBLE = 4
60 fromEnum T_I16 = 6
61 fromEnum T_I32 = 8
62 fromEnum T_I64 = 10
63 fromEnum T_STRING = 11
64 fromEnum T_STRUCT = 12
65 fromEnum T_MAP = 13
66 fromEnum T_SET = 14
67 fromEnum T_LIST = 15
68
69 toEnum 0 = T_STOP
70 toEnum 1 = T_VOID
71 toEnum 2 = T_BOOL
72 toEnum 3 = T_BYTE
73 toEnum 4 = T_DOUBLE
74 toEnum 6 = T_I16
75 toEnum 8 = T_I32
76 toEnum 10 = T_I64
77 toEnum 11 = T_STRING
78 toEnum 12 = T_STRUCT
79 toEnum 13 = T_MAP
80 toEnum 14 = T_SET
81 toEnum 15 = T_LIST
82
83data MessageType
84 = M_CALL
85 | M_REPLY
86 | M_EXCEPTION
87 deriving ( Eq )
88
89instance Enum MessageType where
90 fromEnum M_CALL = 1
91 fromEnum M_REPLY = 2
92 fromEnum M_EXCEPTION = 3
93
94 toEnum 1 = M_CALL
95 toEnum 2 = M_REPLY
96 toEnum 3 = M_EXCEPTION
97
98
99class Protocol a where
100 getTransport :: Transport t => a t -> t
101
102 writeMessageBegin :: Transport t => a t -> (String, MessageType, Int) -> IO ()
103 writeMessageEnd :: Transport t => a t -> IO ()
104
105 writeStructBegin :: Transport t => a t -> String -> IO ()
106 writeStructEnd :: Transport t => a t -> IO ()
107 writeFieldBegin :: Transport t => a t -> (String, ThriftType, Int) -> IO ()
108 writeFieldEnd :: Transport t => a t -> IO ()
109 writeFieldStop :: Transport t => a t -> IO ()
110 writeMapBegin :: Transport t => a t -> (ThriftType, ThriftType, Int) -> IO ()
111 writeMapEnd :: Transport t => a t -> IO ()
112 writeListBegin :: Transport t => a t -> (ThriftType, Int) -> IO ()
113 writeListEnd :: Transport t => a t -> IO ()
114 writeSetBegin :: Transport t => a t -> (ThriftType, Int) -> IO ()
115 writeSetEnd :: Transport t => a t -> IO ()
116
117 writeBool :: Transport t => a t -> Bool -> IO ()
118 writeByte :: Transport t => a t -> Int -> IO ()
119 writeI16 :: Transport t => a t -> Int -> IO ()
120 writeI32 :: Transport t => a t -> Int -> IO ()
121 writeI64 :: Transport t => a t -> Int64 -> IO ()
122 writeDouble :: Transport t => a t -> Double -> IO ()
123 writeString :: Transport t => a t -> String -> IO ()
124 writeBinary :: Transport t => a t -> String -> IO ()
125
126
127 readMessageBegin :: Transport t => a t -> IO (String, MessageType, Int)
128 readMessageEnd :: Transport t => a t -> IO ()
129
130 readStructBegin :: Transport t => a t -> IO String
131 readStructEnd :: Transport t => a t -> IO ()
132 readFieldBegin :: Transport t => a t -> IO (String, ThriftType, Int)
133 readFieldEnd :: Transport t => a t -> IO ()
134 readMapBegin :: Transport t => a t -> IO (ThriftType, ThriftType, Int)
135 readMapEnd :: Transport t => a t -> IO ()
136 readListBegin :: Transport t => a t -> IO (ThriftType, Int)
137 readListEnd :: Transport t => a t -> IO ()
138 readSetBegin :: Transport t => a t -> IO (ThriftType, Int)
139 readSetEnd :: Transport t => a t -> IO ()
140
141 readBool :: Transport t => a t -> IO Bool
142 readByte :: Transport t => a t -> IO Int
143 readI16 :: Transport t => a t -> IO Int
144 readI32 :: Transport t => a t -> IO Int
145 readI64 :: Transport t => a t -> IO Int64
146 readDouble :: Transport t => a t -> IO Double
147 readString :: Transport t => a t -> IO String
148 readBinary :: Transport t => a t -> IO String
149
150
151skip :: (Protocol p, Transport t) => p t -> ThriftType -> IO ()
152skip p T_STOP = return ()
153skip p T_VOID = return ()
154skip p T_BOOL = readBool p >> return ()
155skip p T_BYTE = readByte p >> return ()
156skip p T_I16 = readI16 p >> return ()
157skip p T_I32 = readI32 p >> return ()
158skip p T_I64 = readI64 p >> return ()
159skip p T_DOUBLE = readDouble p >> return ()
160skip p T_STRING = readString p >> return ()
161skip p T_STRUCT = do readStructBegin p
162 skipFields p
163 readStructEnd p
164skip p T_MAP = do (k, v, s) <- readMapBegin p
165 replicateM_ s (skip p k >> skip p v)
166 readMapEnd p
167skip p T_SET = do (t, n) <- readSetBegin p
168 replicateM_ n (skip p t)
169 readSetEnd p
170skip p T_LIST = do (t, n) <- readListBegin p
171 replicateM_ n (skip p t)
172 readListEnd p
173
174
175skipFields :: (Protocol p, Transport t) => p t -> IO ()
176skipFields p = do
177 (_, t, _) <- readFieldBegin p
178 unless (t == T_STOP) (skip p t >> readFieldEnd p >> skipFields p)
179
180
181data ProtocolExnType
182 = PE_UNKNOWN
183 | PE_INVALID_DATA
184 | PE_NEGATIVE_SIZE
185 | PE_SIZE_LIMIT
186 | PE_BAD_VERSION
187 deriving ( Eq, Show, Typeable )
188
189data ProtocolExn = ProtocolExn ProtocolExnType String
190 deriving ( Show, Typeable )
191instance Exception ProtocolExn