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.DetachType;
14 
15 import hunt.collection.AbstractList;
16 import hunt.collection.List;
17 import hunt.proton.amqp.Symbol;
18 import hunt.proton.amqp.UnsignedInteger;
19 import hunt.proton.amqp.UnsignedLong;
20 import hunt.proton.amqp.transport.Detach;
21 import hunt.proton.amqp.transport.ErrorCondition;
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.Boolean;
30 
31 class DetachWrapper : AbstractList!Object
32 {
33 
34     private Detach _detach;
35 
36     this(Detach detach)
37     {
38         _detach = detach;
39     }
40 
41     override
42     Object get(int index)
43     {
44 
45         switch(index)
46         {
47             case 0:
48             return _detach.getHandle();
49             case 1:
50             return _detach.getClosed();
51             case 2:
52             return _detach.getError();
53             default:
54             return null;
55         }
56 
57         //     throw new IllegalStateException("Unknown index " ~ index);
58 
59     }
60 
61     override
62     int size()
63     {
64         return _detach.getError() !is null
65         ? 3
66         : _detach.getClosed().booleanValue()
67         ? 2
68         : 1;
69 
70     }
71 }
72 
73 class DetachType : AbstractDescribedType!(Detach,List!Object) , DescribedTypeConstructor!(Detach)
74 {
75     //private static Object[] DESCRIPTORS =
76     //{
77     //    UnsignedLong.valueOf(0x0000000000000016L), Symbol.valueOf("amqp:detach:list"),
78     //};
79     //
80     //private static UnsignedLong DESCRIPTOR = UnsignedLong.valueOf(0x0000000000000016L);
81 
82 
83      static Object[]  DESCRIPTORS() {
84          __gshared Object[]  inst;
85          return initOnce!inst([UnsignedLong.valueOf(0x0000000000000016L), Symbol.valueOf("amqp:detach:list")]);
86      }
87 
88          static UnsignedLong  DESCRIPTOR() {
89              __gshared UnsignedLong  inst;
90              return initOnce!inst(UnsignedLong.valueOf(0x0000000000000016L));
91          }
92 
93     this(EncoderImpl encoder)
94     {
95         super(encoder);
96     }
97 
98     override
99     protected UnsignedLong getDescriptor()
100     {
101         return DESCRIPTOR;
102     }
103 
104     override
105     protected List!Object wrap(Detach val)
106     {
107         return new DetachWrapper(val);
108     }
109 
110 
111 
112     Detach newInstance(Object described)
113     {
114         List!Object l = cast(List!Object) described;
115         
116         version(HUNT_AMQP_DEBUG) {
117             size_t index = 0;
118             foreach (Object obj; l) {
119                 if(obj is null) {
120                     tracef("Object[%d] is null", index);
121                 } else {
122                     tracef("Object[%d]: %s ,%s", index, typeid(obj), obj.toString());
123                 }
124                 index++;
125             }
126         }
127 
128         Detach o = new Detach();
129 
130         if(l.isEmpty())
131         {
132             logError("The handle field cannot be omitted");
133             //throw new DecodeException("The handle field cannot be omitted");
134         }
135 
136         switch(3 - l.size())
137         {
138 
139             case 0:
140                 o.setError( cast(ErrorCondition) l.get( 2 ) );
141                 goto case;
142             case 1:
143                 Boolean closed = cast(Boolean) l.get(1);
144                 o.setClosed(closed is null ? Boolean.FALSE : closed);
145                 // o.setClosed(Boolean.TRUE);
146                 goto case;
147             case 2:
148                 o.setHandle( cast(UnsignedInteger) l.get( 0 ) );
149                 break;
150             default:
151                 break;
152         }
153 
154 
155         return o;
156     }
157 
158     TypeInfo getTypeClass()
159     {
160         return typeid(Detach);
161     }
162 
163 
164     static void register(Decoder decoder, EncoderImpl encoder)
165     {
166         DetachType type = new DetachType(encoder);
167         foreach(Object descriptor ; DESCRIPTORS)
168         {
169             decoder.registerDynamic(descriptor, type);
170         }
171         encoder.register(type);
172     }
173 
174 }
175