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 module hunt.proton.codec.messaging.FastPathAcceptedType;
12 
13 import hunt.collection.Collection;
14 import hunt.proton.codec.messaging.AcceptedType;
15 import hunt.proton.amqp.Symbol;
16 import hunt.proton.amqp.UnsignedLong;
17 import hunt.proton.amqp.messaging.Accepted;
18 import hunt.proton.codec.AMQPType;
19 import hunt.proton.codec.DecodeException;
20 import hunt.proton.codec.Decoder;
21 import hunt.proton.codec.DecoderImpl;
22 import hunt.proton.codec.EncoderImpl;
23 import hunt.proton.codec.EncodingCodes;
24 import hunt.proton.codec.FastPathDescribedTypeConstructor;
25 import hunt.proton.codec.TypeEncoding;
26 import hunt.proton.codec.WritableBuffer;
27 import hunt.logging;
28 import hunt.Exceptions;
29 import std.concurrency : initOnce;
30 
31 class FastPathAcceptedType : AMQPType!(Accepted), FastPathDescribedTypeConstructor!(Accepted) {
32 
33     private static byte DESCRIPTOR_CODE = 0x24;
34 
35     //private static Object[] DESCRIPTORS =
36     //{
37     //    UnsignedLong.valueOf(DESCRIPTOR_CODE), Symbol.valueOf("amqp:accepted:list"),
38     //};
39 
40     static Object[]  DESCRIPTORS() {
41         __gshared Object[]  inst;
42         return initOnce!inst([UnsignedLong.valueOf(DESCRIPTOR_CODE), Symbol.valueOf("amqp:accepted:list")]);
43     }
44 
45     static byte[] ACCEPTED_ENCODED_BYTES()
46     {
47         __gshared byte[]  inst;
48         return initOnce!inst(
49             [ EncodingCodes.DESCRIBED_TYPE_INDICATOR,
50             EncodingCodes.SMALLULONG,
51             DESCRIPTOR_CODE,
52             EncodingCodes.LIST0 ]
53         );
54 
55     }
56 
57     //private static byte[] ACCEPTED_ENCODED_BYTES = [
58     //    EncodingCodes.DESCRIBED_TYPE_INDICATOR,
59     //    EncodingCodes.SMALLULONG,
60     //    DESCRIPTOR_CODE,
61     //    EncodingCodes.LIST0
62     //];
63 
64     private AcceptedType acceptedType;
65 
66     this(EncoderImpl encoder) {
67         this.acceptedType = new AcceptedType(encoder);
68     }
69 
70     public EncoderImpl getEncoder() {
71         return acceptedType.getEncoder();
72     }
73 
74     public DecoderImpl getDecoder() {
75         return acceptedType.getDecoder();
76     }
77 
78     override
79     public bool encodesJavaPrimitive() {
80         return false;
81     }
82 
83     override
84     public TypeInfo getTypeClass() {
85         return typeid(Accepted);
86     }
87 
88     override
89     public ITypeEncoding getEncoding(Object accepted) {
90         return acceptedType.getEncoding(cast(Accepted)accepted);
91     }
92 
93     override
94     public TypeEncoding!(Accepted) getCanonicalEncoding() {
95         return acceptedType.getCanonicalEncoding();
96     }
97 
98     override
99     public  Collection!(TypeEncoding!(Accepted)) getAllEncodings() {
100         return acceptedType.getAllEncodings();
101     }
102 
103     override
104     public Accepted readValue() {
105         DecoderImpl decoder = getDecoder();
106         byte typeCode = decoder.getBuffer().get();
107 
108         switch (typeCode) {
109             case EncodingCodes.LIST0:
110                 break;
111             case EncodingCodes.LIST8:
112                 decoder.getBuffer().get();
113                 decoder.getBuffer().get();
114                 break;
115             case EncodingCodes.LIST32:
116                 decoder.getBuffer().getInt();
117                 decoder.getBuffer().getInt();
118                 break;
119             default:
120             {
121                 logError("Incorrect type found in Accepted type encoding %d",typeCode);
122                 break;
123             }
124                // throw new DecodeException("Incorrect type found in Accepted type encoding: " ~ typeCode);
125 
126         }
127 
128         return Accepted.getInstance();
129     }
130 
131     public void skipValue() {
132         //implementationMissing(false);
133         getDecoder().readConstructor().skipValue();
134     }
135 
136     override
137     public void write(Object v) {
138         Accepted accepted = cast(Accepted)v;
139         WritableBuffer buffer = getEncoder().getBuffer();
140         buffer.put(ACCEPTED_ENCODED_BYTES, 0, cast(int)ACCEPTED_ENCODED_BYTES.length);
141     }
142 
143     public static void register(Decoder decoder, EncoderImpl encoder) {
144         FastPathAcceptedType type = new FastPathAcceptedType(encoder);
145        // implementationMissing(false);
146         foreach(Object descriptor ; DESCRIPTORS) {
147             decoder.registerFastPath(descriptor,  type);
148         }
149         encoder.register(type);
150     }
151 }