@@ -28,131 +28,135 @@ defmodule Msgpax.Unpacker do
2828 unpack ( buffer , [ ] , options , [ :root ] , 0 , 1 )
2929 end
3030
31- formats = % {
32- quote ( do: [ 0xC0 ] ) => { :value , quote ( do: nil ) } ,
33- quote ( do: [ 0xC2 ] ) => { :value , quote ( do: false ) } ,
34- quote ( do: [ 0xC3 ] ) => { :value , quote ( do: true ) } ,
35-
36- # String
37- quote ( do: [ 0b101 :: 3 , length :: 5 , value :: size ( length ) - bytes ] ) => { :value , quote ( do: value ) } ,
38- quote ( do: [ 0xD9 , length :: integer , value :: size ( length ) - bytes ] ) => { :value , quote ( do: value ) } ,
39- quote ( do: [ 0xDA , length :: 16 - integer , value :: size ( length ) - bytes ] ) => { :value , quote ( do: value ) } ,
40- quote ( do: [ 0xDB , length :: 32 - integer , value :: size ( length ) - bytes ] ) => { :value , quote ( do: value ) } ,
41-
42- # Binary
43- quote ( do: [ 0xC4 , len :: integer , val :: size ( len ) - bytes ] ) => { :call , quote ( do: unpack_binary ( val ) ) } ,
44- quote ( do: [ 0xC5 , len :: 16 - integer , val :: size ( len ) - bytes ] ) => { :call , quote ( do: unpack_binary ( val ) ) } ,
45- quote ( do: [ 0xC6 , len :: 32 - integer , val :: size ( len ) - bytes ] ) => { :call , quote ( do: unpack_binary ( val ) ) } ,
46-
47- # Float
48- quote ( do: [ 0xCA , val :: 32 - big - float ] ) => { :value , quote ( do: val ) } ,
49- quote ( do: [ 0xCB , val :: 64 - big - float ] ) => { :value , quote ( do: val ) } ,
50-
51- # Integer
52- quote ( do: [ 0 :: 1 , val :: 7 ] ) => { :value , quote ( do: val ) } ,
53- quote ( do: [ 0xCC , val ] ) => { :value , quote ( do: val ) } ,
54- quote ( do: [ 0xCD , val :: 16 ] ) => { :value , quote ( do: val ) } ,
55- quote ( do: [ 0xCE , val :: 32 ] ) => { :value , quote ( do: val ) } ,
56- quote ( do: [ 0xCF , val :: 64 ] ) => { :value , quote ( do: val ) } ,
57- quote ( do: [ 0b111 :: 3 , val :: 5 ] ) => { :value , quote ( do: val - 0b100000 ) } ,
58- quote ( do: [ 0xD0 , val :: signed - integer ] ) => { :value , quote ( do: val ) } ,
59- quote ( do: [ 0xD1 , val :: 16 - signed - integer ] ) => { :value , quote ( do: val ) } ,
60- quote ( do: [ 0xD2 , val :: 32 - signed - integer ] ) => { :value , quote ( do: val ) } ,
61- quote ( do: [ 0xD3 , val :: 64 - signed - integer ] ) => { :value , quote ( do: val ) } ,
62-
63- # Array
64- quote ( do: [ 0b1001 :: 4 , len :: 4 ] ) => { :collection , :list } ,
65- quote ( do: [ 0xDC , len :: 16 ] ) => { :collection , :list } ,
66- quote ( do: [ 0xDD , len :: 32 ] ) => { :collection , :list } ,
67-
68- # Map
69- quote ( do: [ 0b1000 :: 4 , len :: 4 ] ) => { :collection , :map } ,
70- quote ( do: [ 0xDE , len :: 16 ] ) => { :collection , :map } ,
71- quote ( do: [ 0xDF , len :: 32 ] ) => { :collection , :map } ,
72-
73- # Extension
74- quote ( do: [ 0xD4 , type , val :: 1 - bytes ] ) => { :call , quote ( do: unpack_ext ( type , val ) ) } ,
75- quote ( do: [ 0xD5 , type , val :: 2 - bytes ] ) => { :call , quote ( do: unpack_ext ( type , val ) ) } ,
76- quote ( do: [ 0xD6 , type , val :: 4 - bytes ] ) => { :call , quote ( do: unpack_ext ( type , val ) ) } ,
77- quote ( do: [ 0xD7 , type , val :: 8 - bytes ] ) => { :call , quote ( do: unpack_ext ( type , val ) ) } ,
78- quote ( do: [ 0xD8 , type , val :: 16 - bytes ] ) => { :call , quote ( do: unpack_ext ( type , val ) ) } ,
79- quote ( do: [ 0xC7 , len , type , val :: size ( len ) - bytes ] ) => { :call , quote ( do: unpack_ext ( type , val ) ) } ,
80- quote ( do: [ 0xC8 , len :: 16 , type , val :: size ( len ) - bytes ] ) => { :call , quote ( do: unpack_ext ( type , val ) ) } ,
81- quote ( do: [ 0xC9 , len :: 32 , type , val :: size ( len ) - bytes ] ) => { :call , quote ( do: unpack_ext ( type , val ) ) } ,
31+ defp unpack ( << buffer :: bits >> , result , options , [ kind , index , length | outer ] , count , count ) do
32+ unpack ( buffer , build_collection ( result , count , kind ) , options , outer , index + 1 , length )
33+ end
34+
35+ primitives = % {
36+ [ quote ( do: [ 0xC0 ] ) ] => quote ( do: nil ) ,
37+ [ quote ( do: [ 0xC2 ] ) ] => quote ( do: false ) ,
38+ [ quote ( do: [ 0xC3 ] ) ] => quote ( do: true ) ,
39+ [ # Strings
40+ quote ( do: [ 0b101 :: 3 , length :: 5 , value :: size ( length ) - bytes ] ) ,
41+ quote ( do: [ 0xD9 , length :: 8 , value :: size ( length ) - bytes ] ) ,
42+ quote ( do: [ 0xDA , length :: 16 , value :: size ( length ) - bytes ] ) ,
43+ quote ( do: [ 0xDB , length :: 32 , value :: size ( length ) - bytes ] ) ,
44+
45+ # Floats
46+ quote ( do: [ 0xCA , value :: 32 - float ] ) ,
47+ quote ( do: [ 0xCB , value :: 64 - float ] ) ,
48+
49+ # Integers
50+ quote ( do: [ 0 :: 1 , value :: 7 ] ) ,
51+ quote ( do: [ 0xCC , value :: 8 ] ) ,
52+ quote ( do: [ 0xCD , value :: 16 ] ) ,
53+ quote ( do: [ 0xCE , value :: 32 ] ) ,
54+ quote ( do: [ 0xCF , value :: 64 ] ) ,
55+ quote ( do: [ 0xD0 , value :: 8 - signed ] ) ,
56+ quote ( do: [ 0xD1 , value :: 16 - signed ] ) ,
57+ quote ( do: [ 0xD2 , value :: 32 - signed ] ) ,
58+ quote ( do: [ 0xD3 , value :: 64 - signed ] ) ] => quote ( do: value ) ,
59+ # Negative fixint
60+ [ quote ( do: [ 0b111 :: 3 , value :: 5 ] ) ] => quote ( do: value - 0b100000 ) ,
8261 }
83-
84- import Macro , only: [ pipe: 3 ]
85-
86- defp unpack ( << buffer :: bits >> , result , options , [ kind , index , size | outer ] , count , count ) do
87- unpack ( buffer , build_collection ( result , count , kind ) , options , outer , index + 1 , size )
62+ for { formats , value } <- primitives , format <- formats do
63+ defp unpack ( << unquote_splicing ( format ) , rest :: bits >> , result , options , outer , index , count ) when index < count do
64+ unpack ( rest , [ unquote ( value ) | result ] , options , outer , index + 1 , count )
65+ end
8866 end
8967
90- for { format , { :value , value } } <- formats do
91- defp unpack ( << unquote_splicing ( format ) , rest :: bits >> , result , options , outer , index , count ) do
92- unpack ( rest , [ unquote ( value ) | result ] , options , outer , index + 1 , count )
68+ lists = [
69+ quote ( do: [ 0b1001 :: 4 , length :: 4 ] ) ,
70+ quote ( do: [ 0xDC , length :: 16 ] ) ,
71+ quote ( do: [ 0xDD , length :: 32 ] ) ,
72+ ]
73+ for format <- lists do
74+ defp unpack ( << unquote_splicing ( format ) , rest :: bits >> , result , options , outer , index , count ) when index < count do
75+ unpack ( rest , result , options , [ :list , index , count | outer ] , 0 , unquote ( quote ( do: length ) ) )
9376 end
9477 end
9578
96- for { format , { :call , call } } <- formats do
97- options = Macro . var ( :options , nil )
98- defp unpack ( << unquote_splicing ( format ) , rest :: bits >> , result , options , outer , index , count ) do
99- unpack ( rest , [ unquote ( pipe ( options , call , 0 ) ) | result ] , options , outer , index + 1 , count )
79+ maps = [
80+ quote ( do: [ 0b1000 :: 4 , length :: 4 ] ) ,
81+ quote ( do: [ 0xDE , length :: 16 ] ) ,
82+ quote ( do: [ 0xDF , length :: 32 ] ) ,
83+ ]
84+ for format <- maps do
85+ defp unpack ( << unquote_splicing ( format ) , rest :: bits >> , result , options , outer , index , count ) when index < count do
86+ unpack ( rest , result , options , [ :map , index , count | outer ] , 0 , unquote ( quote ( do: length ) ) * 2 )
10087 end
10188 end
10289
103- for { format , { :collection , :list = kind } } <- formats do
104- defp unpack ( << unquote_splicing ( format ) , rest :: bits >> , result , options , outer , index , count ) do
105- unpack ( rest , result , options , [ unquote ( kind ) , index , count | outer ] , 0 , unquote ( quote ( do: len ) ) )
90+ binaries = [
91+ quote ( do: [ 0xC4 , length :: 8 , content :: size ( length ) - bytes ] ) ,
92+ quote ( do: [ 0xC5 , length :: 16 , content :: size ( length ) - bytes ] ) ,
93+ quote ( do: [ 0xC6 , length :: 32 , content :: size ( length ) - bytes ] ) ,
94+ ]
95+ for format <- binaries do
96+ defp unpack ( << unquote_splicing ( format ) , rest :: bits >> , result , options , outer , index , count ) when index < count do
97+ value = unpack_binary ( unquote ( quote ( do: content ) ) , options )
98+ unpack ( rest , [ value | result ] , options , outer , index + 1 , count )
10699 end
107100 end
108101
109- for { format , { :collection , :map = kind } } <- formats do
110- defp unpack ( << unquote_splicing ( format ) , rest :: bits >> , result , options , outer , index , count ) do
111- unpack ( rest , result , options , [ unquote ( kind ) , index , count | outer ] , 0 , unquote ( quote ( do: len ) ) * 2 )
102+ extensions = [
103+ quote ( do: [ 0xD4 , type , content :: 1 - bytes ] ) ,
104+ quote ( do: [ 0xD5 , type , content :: 2 - bytes ] ) ,
105+ quote ( do: [ 0xD6 , type , content :: 4 - bytes ] ) ,
106+ quote ( do: [ 0xD7 , type , content :: 8 - bytes ] ) ,
107+ quote ( do: [ 0xD8 , type , content :: 16 - bytes ] ) ,
108+ quote ( do: [ 0xC7 , length :: 8 , type , content :: size ( length ) - bytes ] ) ,
109+ quote ( do: [ 0xC8 , length :: 16 , type , content :: size ( length ) - bytes ] ) ,
110+ quote ( do: [ 0xC9 , length :: 32 , type , content :: size ( length ) - bytes ] ) ,
111+ ]
112+ for format <- extensions do
113+ defp unpack ( << unquote_splicing ( format ) , rest :: bits >> , result , options , outer , index , count ) when index < count do
114+ value = unpack_ext ( unquote ( quote ( do: type ) ) , unquote ( quote ( do: content ) ) , options )
115+ unpack ( rest , [ value | result ] , options , outer , index + 1 , count )
112116 end
113117 end
114118
115- defp unpack ( << byte , _ :: bits >> , [ ] , _options , _outer , _index , _count ) do
116- throw { :bad_format , byte }
119+ defp unpack ( << buffer :: bits >> , [ value ] , _options , [ :root ] , count , count ) do
120+ { value , buffer }
117121 end
118122
119- defp unpack ( << _ :: bits >> , [ ] , _options , _outer , _index , _count ) do
120- throw :incomplete
123+ defp unpack ( << byte , _ :: bits >> , _result , _options , _outer , _index , _count ) do
124+ throw { :bad_format , byte }
121125 end
122126
123- defp unpack ( buffer , [ value ] , _options , [ :root ] , count , count ) do
124- { value , buffer }
127+ defp unpack ( << _ :: bits >> , _result , _options , _outer , _index , _count ) do
128+ throw :incomplete
125129 end
126130
127- defp unpack_binary ( % { binary: true } , value ) do
128- Msgpax.Bin . new ( value )
131+ defp unpack_binary ( content , % { binary: true } ) do
132+ Msgpax.Bin . new ( content )
129133 end
130134
131- defp unpack_binary ( _options , value ) do
132- value
135+ defp unpack_binary ( content , _options ) do
136+ content
133137 end
134138
135- defp unpack_ext ( options , type , data ) do
139+ defp unpack_ext ( type , content , options ) do
136140 if type in 0 .. 127 do
137- unpack_ext_module ( type , data , options )
141+ unpack_ext_module ( type , content , options )
138142 else
139143 throw { :not_supported_ext , type }
140144 end
141145 end
142146
143147 @ compile { :inline , [ unpack_ext_module: 3 ] }
144148
145- defp unpack_ext_module ( type , data , % { ext: module } ) when is_atom ( module ) do
146- case module . unpack ( Msgpax.Ext . new ( type , data ) ) do
149+ defp unpack_ext_module ( type , content , % { ext: module } ) when is_atom ( module ) do
150+ case module . unpack ( Msgpax.Ext . new ( type , content ) ) do
147151 { :ok , result } ->
148152 result
149153 :error ->
150- throw { :ext_unpack_failure , type , module , data }
154+ throw { :ext_unpack_failure , type , module , content }
151155 end
152156 end
153157
154- defp unpack_ext_module ( type , data , _options ) do
155- Msgpax.Ext . new ( type , data )
158+ defp unpack_ext_module ( type , content , _options ) do
159+ Msgpax.Ext . new ( type , content )
156160 end
157161
158162 @ compile { :inline , [ build_collection: 3 ] }
0 commit comments