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