1 /*
2 * hunt-proton: AMQP Protocol library for D programming language.
3 *
4 * Copyright (C) 2018-2019 HuntLabs
5 *
6 * Website: https://www.huntlabs.net/
7 *
8 * Licensed under the Apache-2.0 License.
9 *
10 */
11
12
13 module hunt.proton.codec.transport.FlowType;
14
15 import hunt.collection.AbstractList;
16 import hunt.collection.List;
17 import hunt.collection.Map;
18 import hunt.proton.amqp.Symbol;
19 import hunt.proton.amqp.UnsignedInteger;
20 import hunt.proton.amqp.UnsignedLong;
21 import hunt.proton.amqp.transport.Flow;
22 import hunt.proton.codec.AbstractDescribedType;
23 import hunt.proton.codec.DecodeException;
24 import hunt.proton.codec.Decoder;
25 import hunt.proton.codec.DescribedTypeConstructor;
26 import hunt.proton.codec.EncoderImpl;
27 import std.concurrency : initOnce;
28 import hunt.logging;
29 import hunt.Object;
30 import hunt.Boolean;
31
32 class FlowWrapper : AbstractList!Object
33 {
34
35
36 private Flow _flow;
37
38 this(Flow flow)
39 {
40 _flow = flow;
41 }
42
43 override
44 public Object get(int index)
45 {
46
47 switch(index)
48 {
49 case 0:
50 return _flow.getNextIncomingId();
51 case 1:
52 return _flow.getIncomingWindow();
53 case 2:
54 return _flow.getNextOutgoingId();
55 case 3:
56 return _flow.getOutgoingWindow();
57 case 4:
58 return _flow.getHandle();
59 case 5:
60 return _flow.getDeliveryCount();
61 case 6:
62 return _flow.getLinkCredit();
63 case 7:
64 return _flow.getAvailable();
65 case 8:
66 return _flow.getDrain();
67 case 9:
68 return _flow.getEcho();
69 case 10:
70 return cast(Object) _flow.getProperties();
71 default:
72 return null;
73 }
74
75 // throw new IllegalStateException("Unknown index " ~ index);
76
77 }
78
79 override
80 public int size()
81 {
82 return _flow.getProperties() !is null
83 ? 11
84 : _flow.getEcho().booleanValue
85 ? 10
86 : _flow.getDrain().booleanValue
87 ? 9
88 : _flow.getAvailable() !is null
89 ? 8
90 : _flow.getLinkCredit() !is null
91 ? 7
92 : _flow.getDeliveryCount() !is null
93 ? 6
94 : _flow.getHandle() !is null
95 ? 5
96 : 4;
97
98 }
99 }
100
101 class FlowType : AbstractDescribedType!(Flow,List!Object) , DescribedTypeConstructor!(Flow)
102 {
103 //private static Object[] DESCRIPTORS =
104 //{
105 // UnsignedLong.valueOf(0x0000000000000013L), Symbol.valueOf("amqp:flow:list"),
106 //};
107 //
108 //private static UnsignedLong DESCRIPTOR = UnsignedLong.valueOf(0x0000000000000013L);
109
110 static Object[] DESCRIPTORS() {
111 __gshared Object[] inst;
112 return initOnce!inst([UnsignedLong.valueOf(0x0000000000000013L), Symbol.valueOf("amqp:flow:list")]);
113 }
114
115 static UnsignedLong DESCRIPTOR() {
116 __gshared UnsignedLong inst;
117 return initOnce!inst(UnsignedLong.valueOf(0x0000000000000013L));
118 }
119
120
121 this(EncoderImpl encoder)
122 {
123 super(encoder);
124 }
125
126 override
127 public UnsignedLong getDescriptor()
128 {
129 return DESCRIPTOR;
130 }
131
132 override
133 protected List!Object wrap(Flow val)
134 {
135 return new FlowWrapper(val);
136 }
137
138
139
140 public Flow newInstance(Object described)
141 {
142 List!Object l = cast(List!Object) described;
143
144 Flow o = new Flow();
145
146 if(l.size() <= 3)
147 {
148 logError("The outgoing-window field cannot be omitted");
149 // throw new DecodeException("The outgoing-window field cannot be omitted");
150 }
151
152 switch(11 - l.size())
153 {
154
155 case 0:
156 o.setProperties( cast(IObject) l.get( 10 ) );
157 goto case;
158 case 1:
159 Boolean echo = cast(Boolean) l.get(9);
160 o.setEcho(echo is null ? null : echo);
161 goto case;
162 case 2:
163 Boolean drain = cast(Boolean) l.get(8);
164 o.setDrain(drain is null ? null : drain );
165 goto case;
166 case 3:
167 o.setAvailable( cast(UnsignedInteger) l.get( 7 ) );
168 goto case;
169 case 4:
170 o.setLinkCredit( cast(UnsignedInteger) l.get( 6 ) );
171 goto case;
172 case 5:
173 o.setDeliveryCount( cast(UnsignedInteger) l.get( 5 ) );
174 goto case;
175 case 6:
176 o.setHandle( cast(UnsignedInteger) l.get( 4 ) );
177 goto case;
178 case 7:
179 o.setOutgoingWindow( cast(UnsignedInteger) l.get( 3 ) );
180 goto case;
181 case 8:
182 o.setNextOutgoingId( cast(UnsignedInteger) l.get( 2 ) );
183 goto case;
184 case 9:
185 o.setIncomingWindow( cast(UnsignedInteger) l.get( 1 ) );
186 goto case;
187 case 10:
188 o.setNextIncomingId( cast(UnsignedInteger) l.get( 0 ) );
189 break;
190 default:
191 break;
192 }
193
194
195 return o;
196 }
197
198 public TypeInfo getTypeClass()
199 {
200 return typeid(Flow);
201 }
202
203 public static void register(Decoder decoder, EncoderImpl encoder)
204 {
205 FlowType type = new FlowType(encoder);
206 foreach(Object descriptor ; DESCRIPTORS)
207 {
208 decoder.registerDynamic(descriptor, type);
209 }
210 encoder.register(type);
211 }
212 }