~ubuntu-branches/ubuntu/lucid/rabbitmq-server/lucid

« back to all changes in this revision

Viewing changes to src/rabbit_binary_generator.erl

  • Committer: Bazaar Package Importer
  • Author(s): John Leuner
  • Date: 2010-02-19 17:30:57 UTC
  • mfrom: (0.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20100219173057-84hlnj2bsm1rvoaf
Tags: 1.7.2-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
%%   are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
19
19
%%   Technologies LLC, and Rabbit Technologies Ltd.
20
20
%%
21
 
%%   Portions created by LShift Ltd are Copyright (C) 2007-2009 LShift
 
21
%%   Portions created by LShift Ltd are Copyright (C) 2007-2010 LShift
22
22
%%   Ltd. Portions created by Cohesive Financial Technologies LLC are
23
 
%%   Copyright (C) 2007-2009 Cohesive Financial Technologies
 
23
%%   Copyright (C) 2007-2010 Cohesive Financial Technologies
24
24
%%   LLC. Portions created by Rabbit Technologies Ltd are Copyright
25
 
%%   (C) 2007-2009 Rabbit Technologies Ltd.
 
25
%%   (C) 2007-2010 Rabbit Technologies Ltd.
26
26
%%
27
27
%%   All Rights Reserved.
28
28
%%
46
46
         build_heartbeat_frame/0]).
47
47
-export([generate_table/1, encode_properties/2]).
48
48
-export([check_empty_content_body_frame_size/0]).
 
49
-export([ensure_content_encoded/1, clear_encoded_content/1]).
49
50
 
50
51
-import(lists).
51
52
 
60
61
-spec(build_simple_content_frames/3 ::
61
62
      (channel_number(), content(), non_neg_integer()) -> [frame()]).
62
63
-spec(build_heartbeat_frame/0 :: () -> frame()).
63
 
-spec(generate_table/1 :: (amqp_table()) -> binary()). 
 
64
-spec(generate_table/1 :: (amqp_table()) -> binary()).
64
65
-spec(encode_properties/2 :: ([amqp_property_type()], [any()]) -> binary()).
65
66
-spec(check_empty_content_body_frame_size/0 :: () -> 'ok').
 
67
-spec(ensure_content_encoded/1 :: (content()) -> encoded_content()).
 
68
-spec(clear_encoded_content/1 :: (content()) -> unencoded_content()).
66
69
 
67
70
-endif.
68
71
 
132
135
%% I, D, T and F, as well as the QPid extensions b, d, f, l, s, t, x,
133
136
%% and V.
134
137
 
135
 
table_field_to_binary({FName, longstr, Value}) ->
136
 
    [short_string_to_binary(FName), "S", long_string_to_binary(Value)];
137
 
 
138
 
table_field_to_binary({FName, signedint, Value}) ->
139
 
    [short_string_to_binary(FName), "I", <<Value:32/signed>>];
140
 
 
141
 
table_field_to_binary({FName, decimal, {Before, After}}) ->
142
 
    [short_string_to_binary(FName), "D", Before, <<After:32>>];
143
 
 
144
 
table_field_to_binary({FName, timestamp, Value}) ->
145
 
    [short_string_to_binary(FName), "T", <<Value:64>>];
146
 
 
147
 
table_field_to_binary({FName, table, Value}) ->
148
 
    [short_string_to_binary(FName), "F", table_to_binary(Value)];
149
 
 
150
 
table_field_to_binary({FName, byte, Value}) ->
151
 
    [short_string_to_binary(FName), "b", <<Value:8/unsigned>>];
152
 
 
153
 
table_field_to_binary({FName, double, Value}) ->
154
 
    [short_string_to_binary(FName), "d", <<Value:64/float>>];
155
 
 
156
 
table_field_to_binary({FName, float, Value}) ->
157
 
    [short_string_to_binary(FName), "f", <<Value:32/float>>];
158
 
 
159
 
table_field_to_binary({FName, long, Value}) ->
160
 
    [short_string_to_binary(FName), "l", <<Value:64/signed>>];
161
 
 
162
 
table_field_to_binary({FName, short, Value}) ->
163
 
    [short_string_to_binary(FName), "s", <<Value:16/signed>>];
164
 
 
165
 
table_field_to_binary({FName, bool, Value}) ->
166
 
    [short_string_to_binary(FName), "t", if Value -> 1; true -> 0 end];
167
 
 
168
 
table_field_to_binary({FName, binary, Value}) ->
169
 
    [short_string_to_binary(FName), "x", long_string_to_binary(Value)];
170
 
 
171
 
table_field_to_binary({FName, void, _Value}) ->
172
 
    [short_string_to_binary(FName), "V"].
 
138
table_field_to_binary({FName, Type, Value}) ->
 
139
    [short_string_to_binary(FName) | field_value_to_binary(Type, Value)].
 
140
 
 
141
field_value_to_binary(longstr, Value) ->
 
142
    ["S", long_string_to_binary(Value)];
 
143
 
 
144
field_value_to_binary(signedint, Value) ->
 
145
    ["I", <<Value:32/signed>>];
 
146
 
 
147
field_value_to_binary(decimal, {Before, After}) ->
 
148
    ["D", Before, <<After:32>>];
 
149
 
 
150
field_value_to_binary(timestamp, Value) ->
 
151
    ["T", <<Value:64>>];
 
152
 
 
153
field_value_to_binary(table, Value) ->
 
154
    ["F", table_to_binary(Value)];
 
155
 
 
156
field_value_to_binary(array, Value) ->
 
157
    ["A", array_to_binary(Value)];
 
158
 
 
159
field_value_to_binary(byte, Value) ->
 
160
    ["b", <<Value:8/unsigned>>];
 
161
 
 
162
field_value_to_binary(double, Value) ->
 
163
    ["d", <<Value:64/float>>];
 
164
 
 
165
field_value_to_binary(float, Value) ->
 
166
    ["f", <<Value:32/float>>];
 
167
 
 
168
field_value_to_binary(long, Value) ->
 
169
    ["l", <<Value:64/signed>>];
 
170
 
 
171
field_value_to_binary(short, Value) ->
 
172
    ["s", <<Value:16/signed>>];
 
173
 
 
174
field_value_to_binary(bool, Value) ->
 
175
    ["t", if Value -> 1; true -> 0 end];
 
176
 
 
177
field_value_to_binary(binary, Value) ->
 
178
    ["x", long_string_to_binary(Value)];
 
179
 
 
180
field_value_to_binary(void, _Value) ->
 
181
    ["V"].
173
182
 
174
183
table_to_binary(Table) when is_list(Table) ->
175
184
    BinTable = generate_table(Table),
176
185
    [<<(size(BinTable)):32>>, BinTable].
177
186
 
 
187
array_to_binary(Array) when is_list(Array) ->
 
188
    BinArray = generate_array(Array),
 
189
    [<<(size(BinArray)):32>>, BinArray].
 
190
 
178
191
generate_table(Table) when is_list(Table) ->
179
192
    list_to_binary(lists:map(fun table_field_to_binary/1, Table)).
180
193
 
 
194
generate_array(Array) when is_list(Array) ->
 
195
    list_to_binary(lists:map(
 
196
                     fun ({Type, Value}) -> field_value_to_binary(Type, Value) end,
 
197
                     Array)).
181
198
 
182
 
short_string_to_binary(String) when is_binary(String) and (size(String) < 256) ->
183
 
    [<<(size(String)):8>>, String];
 
199
short_string_to_binary(String) when is_binary(String) ->
 
200
    Len = size(String),
 
201
    if Len < 256 -> [<<(size(String)):8>>, String];
 
202
       true      -> exit(content_properties_shortstr_overflow)
 
203
    end;
184
204
short_string_to_binary(String) ->
185
205
    StringLength = length(String),
186
 
    true = (StringLength < 256), % assertion
187
 
    [<<StringLength:8>>, String].
188
 
 
 
206
    if StringLength < 256 -> [<<StringLength:8>>, String];
 
207
       true               -> exit(content_properties_shortstr_overflow)
 
208
    end.
189
209
 
190
210
long_string_to_binary(String) when is_binary(String) ->
191
211
    [<<(size(String)):32>>, String];
192
212
long_string_to_binary(String) ->
193
213
    [<<(length(String)):32>>, String].
194
214
 
195
 
 
196
215
encode_properties([], []) ->
197
216
    <<0, 0>>;
198
217
encode_properties(TypeList, ValueList) ->
224
243
    end.
225
244
 
226
245
encode_property(shortstr, String) ->
227
 
    Len = size(String), <<Len:8/unsigned, String:Len/binary>>;
 
246
    Len = size(String),
 
247
    if Len < 256 -> <<Len:8/unsigned, String:Len/binary>>;
 
248
       true      -> exit(content_properties_shortstr_overflow)
 
249
    end;
228
250
encode_property(longstr, String) ->
229
251
    Len = size(String), <<Len:32/unsigned, String:Len/binary>>;
230
252
encode_property(octet, Int) ->
238
260
encode_property(timestamp, Int) ->
239
261
    <<Int:64/unsigned>>;
240
262
encode_property(table, Table) ->
241
 
    encode_table(Table).
242
 
 
243
 
 
244
 
encode_table(Table) ->
245
 
    TableBin = list_to_binary(lists:map(fun encode_table_entry/1, Table)),
246
 
    Len = size(TableBin),
247
 
    <<Len:32/unsigned, TableBin:Len/binary>>.
248
 
 
249
 
 
250
 
encode_table_entry({Name, longstr, Value}) ->
251
 
    NLen = size(Name),
252
 
    VLen = size(Value),
253
 
    <<NLen:8/unsigned, Name:NLen/binary, "S", VLen:32/unsigned, Value:VLen/binary>>;
254
 
encode_table_entry({Name, signedint, Value}) ->
255
 
    NLen = size(Name),
256
 
    <<NLen:8/unsigned, Name:NLen/binary, "I", Value:32/signed>>;
257
 
encode_table_entry({Name, decimal, {Before, After}}) ->
258
 
    NLen = size(Name),
259
 
    <<NLen:8/unsigned, Name:NLen/binary, "D", Before:8/unsigned, After:32/unsigned>>;
260
 
encode_table_entry({Name, timestamp, Value}) ->
261
 
    NLen = size(Name),
262
 
    <<NLen:8/unsigned, Name:NLen/binary, "T", Value:64/unsigned>>;
263
 
encode_table_entry({Name, table, Value}) ->
264
 
    NLen = size(Name),
265
 
    TableBin = encode_table(Value),
266
 
    <<NLen:8/unsigned, Name:NLen/binary, "F", TableBin/binary>>.
 
263
    table_to_binary(Table).
267
264
 
268
265
check_empty_content_body_frame_size() ->
269
266
    %% Intended to ensure that EMPTY_CONTENT_BODY_FRAME_SIZE is
275
272
            exit({incorrect_empty_content_body_frame_size,
276
273
                  ComputedSize, ?EMPTY_CONTENT_BODY_FRAME_SIZE})
277
274
    end.
 
275
 
 
276
ensure_content_encoded(Content = #content{properties_bin = PropsBin})
 
277
  when PropsBin =/= 'none' ->
 
278
    Content;
 
279
ensure_content_encoded(Content = #content{properties = Props}) ->
 
280
    Content #content{properties_bin = rabbit_framing:encode_properties(Props)}.
 
281
 
 
282
clear_encoded_content(Content = #content{properties_bin = none}) ->
 
283
    Content;
 
284
clear_encoded_content(Content = #content{properties = none}) ->
 
285
    %% Only clear when we can rebuild the properties_bin later in
 
286
    %% accordance to the content record definition comment - maximum
 
287
    %% one of properties and properties_bin can be 'none'
 
288
    Content;
 
289
clear_encoded_content(Content = #content{}) ->
 
290
    Content#content{properties_bin = none}.