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.FastPathDeliveryAnnotationsType;
12
13 import hunt.collection.Collection;
14 import hunt.collection.LinkedHashMap;
15 import hunt.collection.Map;
16
17 import hunt.proton.amqp.Symbol;
18 import hunt.proton.amqp.UnsignedLong;
19 import hunt.proton.amqp.messaging.DeliveryAnnotations;
20 import hunt.proton.codec.AMQPType;
21 import hunt.proton.codec.ArrayType;
22 import hunt.proton.codec.DecodeException;
23 import hunt.proton.codec.Decoder;
24 import hunt.proton.codec.DecoderImpl;
25 import hunt.proton.codec.EncoderImpl;
26 import hunt.proton.codec.EncodingCodes;
27 import hunt.proton.codec.FastPathDescribedTypeConstructor;
28 import hunt.proton.codec.MapType;
29 import hunt.proton.codec.PrimitiveTypeEncoding;
30 import hunt.proton.codec.ReadableBuffer;
31 import hunt.proton.codec.SymbolType;
32 import hunt.proton.codec.TypeConstructor;
33 import hunt.proton.codec.TypeEncoding;
34 import hunt.proton.codec.WritableBuffer;
35 import hunt.proton.codec.messaging.DeliveryAnnotationsType;
36 import std.concurrency : initOnce;
37 import hunt.Exceptions;
38
39
40 class FastPathDeliveryAnnotationsType : AMQPType!(DeliveryAnnotations), FastPathDescribedTypeConstructor!(DeliveryAnnotations) {
41
42 private static byte DESCRIPTOR_CODE = 0x71;
43
44 //private static Object[] DESCRIPTORS = {
45 // UnsignedLong.valueOf(DESCRIPTOR_CODE), Symbol.valueOf("amqp:delivery-annotations:map"),
46 //};
47
48
49 static Object[] DESCRIPTORS() {
50 __gshared Object[] inst;
51 return initOnce!inst([UnsignedLong.valueOf(DESCRIPTOR_CODE), Symbol.valueOf("amqp:delivery-annotations:map")]);
52 }
53
54 private DeliveryAnnotationsType annotationsType;
55 private SymbolType symbolType;
56
57 this(EncoderImpl encoder) {
58 this.annotationsType = new DeliveryAnnotationsType(encoder);
59 this.symbolType = cast(SymbolType) encoder.getTypeFromClass(typeid(Symbol));
60 }
61
62 public EncoderImpl getEncoder() {
63 return annotationsType.getEncoder();
64 }
65
66 public DecoderImpl getDecoder() {
67 return annotationsType.getDecoder();
68 }
69
70 override
71 public bool encodesJavaPrimitive() {
72 return false;
73 }
74
75 override
76 public TypeInfo getTypeClass() {
77 return typeid(DeliveryAnnotations);
78 }
79
80 override
81 public ITypeEncoding getEncoding(Object val) {
82 return annotationsType.getEncoding(cast(DeliveryAnnotations)val);
83 }
84
85 override
86 public TypeEncoding!(DeliveryAnnotations) getCanonicalEncoding() {
87 return annotationsType.getCanonicalEncoding();
88 }
89
90 override
91 public Collection!(TypeEncoding!(DeliveryAnnotations)) getAllEncodings() {
92 return annotationsType.getAllEncodings();
93 }
94
95 override
96 public DeliveryAnnotations readValue() {
97 implementationMissing(false);
98 return null;
99 //DecoderImpl decoder = getDecoder();
100 //ReadableBuffer buffer = decoder.getBuffer();
101 //
102 //int size;
103 //int count;
104 //
105 //byte encodingCode = buffer.get();
106 //
107 //switch (encodingCode) {
108 // case EncodingCodes.MAP8:
109 // size = buffer.get() & 0xFF;
110 // count = buffer.get() & 0xFF;
111 // break;
112 // case EncodingCodes.MAP32:
113 // size = buffer.getInt();
114 // count = buffer.getInt();
115 // break;
116 // case EncodingCodes.NULL:
117 // return new DeliveryAnnotations(null);
118 // default:
119 // throw new ProtonException("Expected Map type but found encoding: " ~ encodingCode);
120 //}
121 //
122 //if (count > buffer.remaining()) {
123 // throw new IllegalArgumentException("Map element count " ~ count ~ " is specified to be greater than the " ~
124 // "amount of data available (" ~ buffer.remaining() ~ ")");
125 //}
126 //
127 //TypeConstructor<?> valueConstructor = null;
128 //
129 //Map!(Symbol, Object) map = new LinkedHashMap<>(count);
130 //for(int i = 0; i < count / 2; i++) {
131 // Symbol key = decoder.readSymbol(null);
132 // if (key is null) {
133 // throw new DecodeException("String key in DeliveryAnnotations cannot be null");
134 // }
135 //
136 // bool arrayType = false;
137 // byte code = buffer.get(buffer.position());
138 // switch (code)
139 // {
140 // case EncodingCodes.ARRAY8:
141 // case EncodingCodes.ARRAY32:
142 // arrayType = true;
143 // }
144 //
145 // valueConstructor = findNextDecoder(decoder, buffer, valueConstructor);
146 //
147 // Object value;
148 //
149 // if (arrayType) {
150 // value = ((ArrayType.ArrayEncoding) valueConstructor).readValueArray();
151 // } else {
152 // value = valueConstructor.readValue();
153 // }
154 //
155 // map.put(key, value);
156 //}
157 //
158 //return new DeliveryAnnotations(map);
159 }
160
161 override
162 public void skipValue() {
163 implementationMissing(false);
164 // getDecoder().readConstructor().skipValue();
165 }
166
167 override
168 public void write(Object v) {
169 DeliveryAnnotations val = cast(DeliveryAnnotations)v;
170 implementationMissing(false);
171 //WritableBuffer buffer = getEncoder().getBuffer();
172 //
173 //buffer.put(EncodingCodes.DESCRIBED_TYPE_INDICATOR);
174 //buffer.put(EncodingCodes.SMALLULONG);
175 //buffer.put(DESCRIPTOR_CODE);
176 //
177 //MapType mapType = (MapType) getEncoder().getType(val.getValue());
178 //
179 //mapType.setKeyEncoding(symbolType);
180 //try {
181 // mapType.write(val.getValue());
182 //} finally {
183 // mapType.setKeyEncoding(null);
184 //}
185 }
186
187 public static void register(Decoder decoder, EncoderImpl encoder) {
188 FastPathDeliveryAnnotationsType type = new FastPathDeliveryAnnotationsType(encoder);
189 //implementationMissing(false);
190 foreach(Object descriptor ; DESCRIPTORS) {
191 decoder.registerFastPath(descriptor, type);
192 }
193 encoder.register(type);
194 }
195
196 //private static TypeConstructor<?> findNextDecoder(DecoderImpl decoder, ReadableBuffer buffer, TypeConstructor<?> previousConstructor) {
197 // if (previousConstructor is null) {
198 // return decoder.readConstructor();
199 // } else {
200 // byte encodingCode = buffer.get(buffer.position());
201 // if (encodingCode == EncodingCodes.DESCRIBED_TYPE_INDICATOR || !(previousConstructor instanceof PrimitiveTypeEncoding<?>)) {
202 // previousConstructor = decoder.readConstructor();
203 // } else {
204 // PrimitiveTypeEncoding<?> primitiveConstructor = (PrimitiveTypeEncoding<?>) previousConstructor;
205 // if (encodingCode != primitiveConstructor.getEncodingCode()) {
206 // previousConstructor = decoder.readConstructor();
207 // } else {
208 // // consume the encoding code byte for real
209 // encodingCode = buffer.get();
210 // }
211 // }
212 // }
213 //
214 // if (previousConstructor is null) {
215 // throw new DecodeException("Unknown constructor found in Map encoding: ");
216 // }
217 //
218 // return previousConstructor;
219 //}
220 }