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.BeginType;
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.UnsignedShort;
22 import hunt.proton.amqp.transport.Begin;
23 import hunt.proton.codec.AbstractDescribedType;
24 import hunt.proton.codec.DecodeException;
25 import hunt.proton.codec.Decoder;
26 import hunt.proton.codec.DescribedTypeConstructor;
27 import hunt.proton.codec.EncoderImpl;
28 import hunt.logging;
29 import std.concurrency : initOnce;
30 
31 class BeginWrapper : AbstractList!Object
32 {
33 
34     private Begin _begin;
35 
36     this(Begin begin)
37     {
38         _begin = begin;
39     }
40 
41     override
42     public Object get(int index)
43     {
44 
45         switch(index)
46         {
47             case 0:
48             return _begin.getRemoteChannel();
49             case 1:
50             return _begin.getNextOutgoingId();
51             case 2:
52             return _begin.getIncomingWindow();
53             case 3:
54             return _begin.getOutgoingWindow();
55             case 4:
56             return _begin.getHandleMax();
57             case 5:
58             return cast(Object)(_begin.getOfferedCapabilities());
59             case 6:
60             return cast(Object)(_begin.getDesiredCapabilities());
61             case 7:
62             return cast(Object)(_begin.getProperties());
63             default:
64             return null;
65         }
66 
67         //throw new IllegalStateException("Unknown index " ~ index);
68 
69     }
70 
71     override
72     public int size()
73     {
74         return _begin.getProperties() !is null
75         ? 8
76         : _begin.getDesiredCapabilities() !is null
77         ? 7
78         : _begin.getOfferedCapabilities() !is null
79         ? 6
80         : (_begin.getHandleMax() !is null && _begin.getHandleMax() != (UnsignedInteger.MAX_VALUE))
81         ? 5
82         : 4;
83 
84     }
85 }
86 
87 class BeginType : AbstractDescribedType!(Begin,List!Object) , DescribedTypeConstructor!(Begin)
88 {
89     //private static Object[] DESCRIPTORS =
90     //{
91     //    UnsignedLong.valueOf(0x0000000000000011L), Symbol.valueOf("amqp:begin:list"),
92     //};
93     //
94     //private static UnsignedLong DESCRIPTOR = UnsignedLong.valueOf(0x0000000000000011L);
95 
96       static Object[]  DESCRIPTORS() {
97           __gshared Object[]  inst;
98           return initOnce!inst([UnsignedLong.valueOf(0x0000000000000011L), Symbol.valueOf("amqp:begin:list")]);
99       }
100 
101          static UnsignedLong  DESCRIPTOR() {
102              __gshared UnsignedLong  inst;
103              return initOnce!inst(UnsignedLong.valueOf(0x0000000000000011L));
104          }
105 
106     this(EncoderImpl encoder)
107     {
108         super(encoder);
109     }
110 
111     override
112     protected UnsignedLong getDescriptor()
113     {
114         return DESCRIPTOR;
115     }
116 
117     override
118     protected List!Object wrap(Begin val)
119     {
120         return new BeginWrapper(val);
121     }
122 
123 
124 
125     public Begin newInstance(Object described)
126     {
127         List!Object l = cast(List!Object) described;
128 
129         Begin o = new Begin();
130 
131         if(l.size() <= 3)
132         {
133             logError("The outgoing-window field cannot be omitted");
134             return null;
135            // throw new DecodeException("The outgoing-window field cannot be omitted");
136         }
137 
138         switch(8 - l.size())
139         {
140 
141             case 0:
142                 o.setProperties( cast(Map!(Symbol,Object)) l.get( 7 ) );
143                 goto case;
144             case 1:
145                 o.setDesiredCapabilities( cast(List!Symbol) l.get( 6 ) );
146                 goto case;
147             case 2:
148                 o.setOfferedCapabilities( cast(List!Symbol) l.get( 5 ) );
149                 goto case;
150             case 3:
151                 UnsignedInteger handleMax = cast(UnsignedInteger) l.get(4);
152                 o.setHandleMax(handleMax is null ? UnsignedInteger.MAX_VALUE : handleMax);
153                 goto case;
154             case 4:
155                 o.setOutgoingWindow( cast(UnsignedInteger) l.get( 3 ) );
156                 goto case;
157             case 5:
158                 o.setIncomingWindow( cast(UnsignedInteger) l.get( 2 ) );
159                 goto case;
160             case 6:
161                 o.setNextOutgoingId( cast(UnsignedInteger) l.get( 1 ) );
162                 goto case;
163             case 7:
164                 o.setRemoteChannel( cast(UnsignedShort) l.get( 0 ) );
165                 break;
166             default:
167                 break;
168         }
169 
170 
171         return o;
172     }
173 
174     public TypeInfo getTypeClass()
175     {
176         return typeid(Begin);
177     }
178 
179 
180     public static void register(Decoder decoder, EncoderImpl encoder)
181     {
182         BeginType type = new BeginType(encoder);
183         foreach(Object descriptor ; DESCRIPTORS)
184         {
185             decoder.registerDynamic(descriptor, type);
186         }
187         encoder.register(type);
188     }
189 
190 }
191