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 }