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.security.SaslInitType;
14 
15 import hunt.collection.AbstractList;
16 import hunt.collection.List;
17 import hunt.proton.amqp.Binary;
18 import hunt.proton.amqp.Symbol;
19 import hunt.proton.amqp.UnsignedLong;
20 import hunt.proton.amqp.security.SaslInit;
21 import hunt.proton.codec.AbstractDescribedType;
22 import hunt.proton.codec.DecodeException;
23 import hunt.proton.codec.Decoder;
24 import hunt.proton.codec.DescribedTypeConstructor;
25 import hunt.proton.codec.EncoderImpl;
26 import hunt.String;
27 import hunt.Exceptions;
28 import hunt.Object;
29 
30 import hunt.Exceptions;
31 
32 import std.concurrency : initOnce;
33 import hunt.logging;
34 import std.conv : to;
35 
36 class SaslInitWrapper : AbstractList!Object
37 {
38 
39     private SaslInit _saslInit;
40 
41     this(SaslInit saslInit)
42     {
43         _saslInit = saslInit;
44     }
45 
46     override
47     public Object get(int index)
48     {
49 
50         switch(index)
51         {
52             case 0:
53             return _saslInit.getMechanism();
54             case 1:
55             return _saslInit.getInitialResponse();
56             case 2:
57             return _saslInit.getHostname();
58             default:
59             return null;
60         }
61 
62         //    throw new IllegalStateException("Unknown index " ~ to!string(index));
63 
64     }
65     override
66     public int size()
67     {
68         return _saslInit.getHostname() !is null
69         ? 3
70         : _saslInit.getInitialResponse() !is null
71         ? 2
72         : 1;
73 
74     }
75 }
76 
77 
78 class SaslInitType : AbstractDescribedType!(SaslInit,List!Object) , DescribedTypeConstructor!(SaslInit)
79 {
80     //private static Object[] DESCRIPTORS =
81     //{
82     //    UnsignedLong.valueOf(0x0000000000000041L), Symbol.valueOf("amqp:sasl-init:list"),
83     //};
84 
85     //private static UnsignedLong DESCRIPTOR = UnsignedLong.valueOf(0x0000000000000041L);
86 
87     static UnsignedLong  DESCRIPTOR() {
88         __gshared UnsignedLong  inst;
89         return initOnce!inst(UnsignedLong.valueOf(0x0000000000000041L));
90     }
91 
92     static Object[]  DESCRIPTORS() {
93         __gshared Object[]  inst;
94         return initOnce!inst([UnsignedLong.valueOf(0x0000000000000041L), Symbol.valueOf("amqp:sasl-init:list")]);
95     }
96 
97     this(EncoderImpl encoder)
98     {
99         super(encoder);
100     }
101 
102 
103     override
104     public UnsignedLong getDescriptor()
105     {
106         return DESCRIPTOR;
107     }
108 
109     override
110     protected List!Object wrap(SaslInit val)
111     {
112         return new SaslInitWrapper(val);
113     }
114 
115 
116 
117 
118     public SaslInit newInstance(Object described)
119     {
120         List!Object l = cast(List!Object) described;
121 
122         SaslInit o = new SaslInit();
123 
124         if(l.size() <= 0)
125         {
126             logError("The mechanism field cannot be omitted");
127            // throw new DecodeException("The mechanism field cannot be omitted");
128         }
129 
130         switch(3 - l.size())
131         {
132 
133             case 0:
134                 o.setHostname( cast(String) l.get( 2 ) );
135                 goto case;
136             case 1:
137                 o.setInitialResponse( cast(Binary) l.get( 1 ) );
138                 goto case;
139             case 2:
140                 o.setMechanism( cast(Symbol) l.get( 0 ) );
141                 break;
142             default:
143                 break;
144         }
145 
146 
147         return o;
148     }
149 
150     public TypeInfo getTypeClass()
151     {
152         //return typeid(SaslInitWrapper);
153         return typeid(SaslInit);
154     }
155 
156 
157 
158     public static void register(Decoder decoder, EncoderImpl encoder)
159     {
160         SaslInitType type = new SaslInitType(encoder);
161         //implementationMissing(false);
162         foreach(Object descriptor ; DESCRIPTORS)
163         {
164             decoder.registerDynamic(descriptor, type);
165         }
166         encoder.register(type);
167     }
168 }