|
1 | 1 | %% |
2 | 2 | %% MessagePack for Erlang |
3 | 3 | %% |
4 | | -%% Copyright (C) 2009-2013 UENISHI Kota |
| 4 | +%% Copyright (C) 2009-2016 UENISHI Kota |
5 | 5 | %% |
6 | 6 | %% Licensed under the Apache License, Version 2.0 (the "License"); |
7 | 7 | %% you may not use this file except in compliance with the License. |
|
45 | 45 |
|
46 | 46 | -include("msgpack.hrl"). |
47 | 47 |
|
48 | | -%% for export |
49 | | --export_type([object/0, msgpack_map/0, options/0]). |
| 48 | +-export_type([object/0, msgpack_map/0, options/0, ext_packer/0, ext_unpacker/0]). |
50 | 49 | -type object() :: msgpack_term(). |
51 | | --type options() :: msgpack_list_options(). |
| 50 | + |
| 51 | +-type options() :: |
| 52 | + [{spec, new|old} | |
| 53 | + {allow_atom, none|pack} | |
| 54 | + {known_atoms, [atom()]} | |
| 55 | + {unpack_str, as_binary|as_list} | |
| 56 | + {validate_string, boolean()} | |
| 57 | + {pack_str, from_binary|from_list|none} | |
| 58 | + {map_format, map|jiffy|jsx} | |
| 59 | + {ext, {msgpack:ext_packer(), msgpack:ext_unpacker()} | module()}]. |
| 60 | + |
| 61 | +-type opt_record() :: ?OPTION{}. |
| 62 | +-export_type([opt_record/0]). |
| 63 | + |
| 64 | +%% @doc ext_packer that packs only tuples with length > 2 |
| 65 | +-type ext_packer() :: fun((tuple(), msgpack:options()) -> |
| 66 | + {ok, {Type::byte(), Data::binary()}} | |
| 67 | + {error, any()}). |
| 68 | +-type ext_unpacker() :: |
| 69 | + fun((byte(), binary(), msgpack:options()) -> |
| 70 | + {ok, msgpack_term()} | {error, any()}) |
| 71 | + | fun((byte(), binary()) -> |
| 72 | + {ok, msgpack_term()} | {error, any()}). |
| 73 | + |
52 | 74 |
|
53 | 75 | -spec term_to_binary(term()) -> binary(). |
54 | 76 | term_to_binary(Term) -> |
@@ -114,39 +136,43 @@ unpack_stream(Bin, Opts0) when is_binary(Bin) -> |
114 | 136 | unpack_stream(Other, _) -> {error, {badarg, Other}}. |
115 | 137 |
|
116 | 138 | %% @private |
117 | | --spec parse_options(msgpack:options()) -> msgpack_option(). |
| 139 | +-spec parse_options(msgpack:options()) -> ?OPTION{}. |
118 | 140 |
|
119 | 141 | parse_options(Opt) -> |
120 | 142 | parse_options(Opt, ?OPTION{original_list=Opt}). |
121 | 143 |
|
122 | 144 | %% @private |
123 | | --spec parse_options(msgpack:options(), msgpack_option()) -> msgpack_option(). |
| 145 | +-spec parse_options(msgpack:options(), ?OPTION{}) -> ?OPTION{}. |
124 | 146 | parse_options([], Opt) -> Opt; |
125 | 147 |
|
126 | | -parse_options([jsx|TL], Opt0) -> |
127 | | - Opt = Opt0?OPTION{interface=jsx, |
128 | | - map_unpack_fun=msgpack_unpacker:map_unpacker(jsx)}, |
129 | | - parse_options(TL, Opt); |
130 | | -parse_options([jiffy|TL], Opt0) -> |
131 | | - Opt = Opt0?OPTION{interface=jiffy, |
132 | | - map_unpack_fun=msgpack_unpacker:map_unpacker(jiffy)}, |
133 | | - parse_options(TL, Opt); |
134 | | -parse_options([{format,Type}|TL], Opt0) |
135 | | - when Type =:= jsx; Type =:= jiffy; Type =:= map-> |
136 | | - Opt = Opt0?OPTION{interface=Type, |
137 | | - map_unpack_fun=msgpack_unpacker:map_unpacker(Type)}, |
138 | | - parse_options(TL, Opt); |
| 148 | +parse_options([{spec, Spec}|T], Opt0) when Spec =:= new orelse Spec =:= old -> |
| 149 | + parse_options(T, Opt0?OPTION{spec = Spec}); |
139 | 150 |
|
140 | | -parse_options([{allow_atom,Type}|TL], Opt0) -> |
| 151 | +parse_options([{allow_atom,Type}|T], Opt0) -> |
141 | 152 | Opt = case Type of |
142 | 153 | none -> Opt0?OPTION{allow_atom=none}; |
143 | 154 | pack -> Opt0?OPTION{allow_atom=pack} |
144 | 155 | end, |
145 | | - parse_options(TL, Opt); |
| 156 | + parse_options(T, Opt); |
146 | 157 |
|
147 | | -parse_options([{enable_str,Bool}|TL], Opt0) -> |
148 | | - Opt = Opt0?OPTION{enable_str=Bool}, |
149 | | - parse_options(TL, Opt); |
| 158 | +parse_options([{known_atoms, Atoms}|T], Opt0) when is_list(Atoms) -> |
| 159 | + parse_options(T, Opt0?OPTION{known_atoms=Atoms}); |
| 160 | + |
| 161 | +parse_options([{unpack_str, As}|T], Opt0) when As =:= as_binary orelse As =:= as_list -> |
| 162 | + parse_options(T, Opt0?OPTION{unpack_str=As}); |
| 163 | + |
| 164 | +parse_options([{validate_string, Bool}|T], Opt) when is_boolean(Bool) -> |
| 165 | + parse_options(T, Opt?OPTION{validate_string=Bool}); |
| 166 | + |
| 167 | +parse_options([{pack_str, From}|T], Opt) |
| 168 | + when From =:= from_binary orelse From =:= from_list orelse From =:= none -> |
| 169 | + parse_options(T, Opt?OPTION{pack_str=From}); |
| 170 | + |
| 171 | +parse_options([{map_format,Type}|T], Opt0) |
| 172 | + when Type =:= jsx; Type =:= jiffy; Type =:= map -> |
| 173 | + Opt = Opt0?OPTION{map_format=Type, |
| 174 | + map_unpack_fun=msgpack_unpacker:map_unpacker(Type)}, |
| 175 | + parse_options(T, Opt); |
150 | 176 |
|
151 | 177 | parse_options([{ext, Module}|TL], Opt0) when is_atom(Module) -> |
152 | 178 | Opt = Opt0?OPTION{ext_packer=fun Module:pack_ext/2, |
@@ -200,10 +226,10 @@ test_data()-> |
200 | 226 | -endif. |
201 | 227 |
|
202 | 228 | enable_str_test() -> |
203 | | - ?assertEqual(<<167:8, (<<"saitama">>)/binary >>, |
204 | | - msgpack:pack(<<"saitama">>, [{enable_str, false}])), |
205 | | - ?assertEqual(<<196,7,115,97,105,116,97,109,97>>, |
206 | | - msgpack:pack(<<"saitama">>, [{enable_str, true}])). |
| 229 | + ?assertEqual(<<167:8, "saitama">>, |
| 230 | + msgpack:pack(<<"saitama">>, [{spec,old}])), |
| 231 | + ?assertEqual(<<2#101:3, 7:5, "saitama">>, %% binary becomes str8 from_binary |
| 232 | + msgpack:pack(<<"saitama">>, [{spec,new},{pack_str,from_binary}])). |
207 | 233 |
|
208 | 234 | basic_test()-> |
209 | 235 | Tests = test_data(), |
@@ -240,9 +266,9 @@ other_test()-> |
240 | 266 | ?assertEqual({error,incomplete},msgpack:unpack(<<>>)). |
241 | 267 |
|
242 | 268 | error_test()-> |
243 | | - ?assertEqual({error,{badarg, atom}}, msgpack:pack(atom)), |
| 269 | + ?assertEqual({error,{badarg, atom}}, msgpack:pack(atom, [{allow_atom, none}])), |
244 | 270 | Term = {"hoge", "hage", atom}, |
245 | | - ?assertEqual({error,{badarg, Term}}, msgpack:pack(Term)). |
| 271 | + ?assertEqual({error,{badarg, Term}}, msgpack:pack(Term, [{allow_atom, none}])). |
246 | 272 |
|
247 | 273 | long_binary_test()-> |
248 | 274 | A = msgpack:pack(1), |
|
0 commit comments