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.AttachType;
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.UnsignedByte;
20 import hunt.proton.amqp.UnsignedInteger;
21 import hunt.proton.amqp.UnsignedLong;
22 import hunt.proton.amqp.transport.Attach;
23 import hunt.proton.amqp.transport.ReceiverSettleMode;
24 import hunt.proton.amqp.transport.Role;
25 import hunt.proton.amqp.transport.SenderSettleMode;
26 import hunt.proton.amqp.transport.Source;
27 import hunt.proton.amqp.transport.Target;
28 import hunt.proton.codec.AbstractDescribedType;
29 import hunt.proton.codec.DecodeException;
30 import hunt.proton.codec.Decoder;
31 import hunt.proton.codec.DescribedTypeConstructor;
32 import hunt.proton.codec.EncoderImpl;
33 import hunt.logging;
34 import hunt.Boolean;
35 import hunt.String;
36 import std.concurrency : initOnce;
37 class AttachWrapper : AbstractList!Object
38 {
39 
40     private Attach _attach;
41 
42     this(Attach attach)
43     {
44         _attach = attach;
45     }
46 
47     override
48     public Object get(int index)
49     {
50 
51         switch(index)
52         {
53             case 0:
54             return _attach.getName();
55             case 1:
56             return _attach.getHandle();
57             case 2:
58             return _attach.getRole().getValue();
59             case 3:
60             return _attach.getSndSettleMode().getValue();
61             case 4:
62             return _attach.getRcvSettleMode().getValue();
63             case 5:
64             return  cast(Object)(_attach.getSource());
65             case 6:
66             return cast(Object)(_attach.getTarget());
67             case 7:
68             return cast(Object)(_attach.getUnsettled());
69             case 8:
70             return _attach.getIncompleteUnsettled();
71             case 9:
72             return _attach.getInitialDeliveryCount();
73             case 10:
74             return _attach.getMaxMessageSize();
75             case 11:
76             return cast(Object)(_attach.getOfferedCapabilities());
77             case 12:
78             return cast(Object)(_attach.getDesiredCapabilities());
79             case 13:
80             return cast(Object)(_attach.getProperties());
81             default:
82             return null;
83         }
84 
85         // throw new IllegalStateException("Unknown index " ~ index);
86 
87     }
88 
89     override
90     public int size()
91     {
92         return _attach.getProperties() !is null
93         ? 14
94         : _attach.getDesiredCapabilities() !is null
95         ? 13
96         : _attach.getOfferedCapabilities() !is null
97         ? 12
98         : _attach.getMaxMessageSize() !is null
99         ? 11
100         : _attach.getInitialDeliveryCount() !is null
101         ? 10
102         : _attach.getIncompleteUnsettled().booleanValue
103         ? 9
104         : _attach.getUnsettled() !is null
105         ? 8
106         : _attach.getTarget() !is null
107         ? 7
108         : _attach.getSource() !is null
109         ? 6
110         : (_attach.getRcvSettleMode() !is null && _attach.getRcvSettleMode()!= (ReceiverSettleMode.FIRST))
111         ? 5
112         : (_attach.getSndSettleMode() !is null && _attach.getSndSettleMode()!= (SenderSettleMode.MIXED))
113         ? 4
114         : 3;
115 
116     }
117 
118 }
119 
120 
121 class AttachType : AbstractDescribedType!(Attach,List!Object) , DescribedTypeConstructor!(Attach)
122 {
123     //private static Object[] DESCRIPTORS =
124     //{
125     //    UnsignedLong.valueOf(0x0000000000000012L), Symbol.valueOf("amqp:attach:list"),
126     //};
127     //
128     //private static UnsignedLong DESCRIPTOR = UnsignedLong.valueOf(0x0000000000000012L);
129 
130       static Object[]  DESCRIPTORS() {
131           __gshared Object[]  inst;
132           return initOnce!inst([UnsignedLong.valueOf(0x0000000000000012L), Symbol.valueOf("amqp:attach:list")]);
133       }
134 
135          static UnsignedLong  DESCRIPTOR() {
136              __gshared UnsignedLong  inst;
137              return initOnce!inst(UnsignedLong.valueOf(0x0000000000000012L));
138          }
139 
140     this(EncoderImpl encoder)
141     {
142         super(encoder);
143     }
144 
145     override
146     public UnsignedLong getDescriptor()
147     {
148         return DESCRIPTOR;
149     }
150 
151     override
152     protected List!Object wrap(Attach val)
153     {
154         return new AttachWrapper(val);
155     }
156 
157 
158 
159     public Attach newInstance(Object described)
160     {
161         List!Object l = cast(List!Object) described;
162 
163         Attach o = new Attach();
164 
165         if(l.size() <= 2)
166         {
167             logError("The role field cannot be omitted");
168             return null;
169             //throw new DecodeException("The role field cannot be omitted");
170         }
171 
172         switch(14 - l.size())
173         {
174 
175             case 0:
176                 o.setProperties( cast(Map!(Symbol,Object)) l.get( 13 ) );
177                 goto case;
178             case 1:
179                 o.setDesiredCapabilities( cast(List!Symbol)  l.get( 12 ) );
180                 goto case;
181             case 2:
182                 o.setOfferedCapabilities( cast(List!Symbol) l.get( 11 ) );
183                 goto case;
184             case 3:
185                 o.setMaxMessageSize( cast(UnsignedLong) l.get( 10 ) );
186                 goto case;
187             case 4:
188                 o.setInitialDeliveryCount( cast(UnsignedInteger) l.get( 9 ) );
189                 goto case;
190             case 5:
191                 Boolean incompleteUnsettled = cast(Boolean) l.get(8);
192                 o.setIncompleteUnsettled(incompleteUnsettled is null ? null : incompleteUnsettled);
193                 goto case;
194             case 6:
195                 o.setUnsettled( cast(Map!(Symbol,Object)) l.get( 7 ) );
196                 goto case;
197             case 7:
198                 o.setTarget( cast(Target) l.get( 6 ) );
199                 goto case;
200             case 8:
201                 o.setSource( cast(Source) l.get( 5 ) );
202                 goto case;
203             case 9:
204                 UnsignedByte rcvSettleMode = cast(UnsignedByte) l.get(4);
205                 o.setRcvSettleMode(rcvSettleMode is null ? ReceiverSettleMode.FIRST : ReceiverSettleMode.valueOf(rcvSettleMode));
206                 goto case;
207             case 10:
208                 UnsignedByte sndSettleMode = cast(UnsignedByte) l.get(3);
209                 o.setSndSettleMode(sndSettleMode is null ? SenderSettleMode.MIXED : SenderSettleMode.valueOf(sndSettleMode));
210                 goto case;
211             case 11:
212                 Boolean tmp = cast(Boolean) l.get( 2 );
213                 o.setRole(tmp.booleanValue() ? Role.RECEIVER : Role.SENDER);
214                 goto case;
215             case 12:
216                 o.setHandle( cast(UnsignedInteger) l.get( 1 ) );
217                 goto case;
218             case 13:
219                 o.setName( cast(String) l.get( 0 ) );
220                  break;
221             default:
222                 break;
223         }
224 
225 
226         return o;
227     }
228 
229     public TypeInfo getTypeClass()
230     {
231         return typeid(Attach);
232     }
233 
234 
235     public static void register(Decoder decoder, EncoderImpl encoder)
236     {
237         AttachType type = new AttachType(encoder);
238         foreach(Object descriptor ; DESCRIPTORS)
239         {
240             decoder.registerDynamic(descriptor, type);
241         }
242         encoder.register(type);
243     }
244 }