@@ -28,131 +28,135 @@ defmodule Msgpax.Unpacker do
28
28
unpack ( buffer , [ ] , options , [ :root ] , 0 , 1 )
29
29
end
30
30
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 ) ,
82
61
}
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
88
66
end
89
67
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 ) ) )
93
76
end
94
77
end
95
78
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 )
100
87
end
101
88
end
102
89
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 )
106
99
end
107
100
end
108
101
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 )
112
116
end
113
117
end
114
118
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 }
117
121
end
118
122
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 }
121
125
end
122
126
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
125
129
end
126
130
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 )
129
133
end
130
134
131
- defp unpack_binary ( _options , value ) do
132
- value
135
+ defp unpack_binary ( content , _options ) do
136
+ content
133
137
end
134
138
135
- defp unpack_ext ( options , type , data ) do
139
+ defp unpack_ext ( type , content , options ) do
136
140
if type in 0 .. 127 do
137
- unpack_ext_module ( type , data , options )
141
+ unpack_ext_module ( type , content , options )
138
142
else
139
143
throw { :not_supported_ext , type }
140
144
end
141
145
end
142
146
143
147
@ compile { :inline , [ unpack_ext_module: 3 ] }
144
148
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
147
151
{ :ok , result } ->
148
152
result
149
153
:error ->
150
- throw { :ext_unpack_failure , type , module , data }
154
+ throw { :ext_unpack_failure , type , module , content }
151
155
end
152
156
end
153
157
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 )
156
160
end
157
161
158
162
@ compile { :inline , [ build_collection: 3 ] }
0 commit comments