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 }