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 module hunt.proton.codec.SymbolType; 13 14 import hunt.proton.codec.SmallFloatingSizePrimitiveTypeEncoding; 15 import hunt.proton.codec.LargeFloatingSizePrimitiveTypeEncoding; 16 import hunt.proton.codec.EncodingCodes; 17 import hunt.proton.codec.EncoderImpl; 18 import hunt.proton.codec.PrimitiveTypeEncoding; 19 import hunt.proton.codec.DecoderImpl; 20 import hunt.proton.codec.ReadableBuffer; 21 import hunt.proton.codec.AbstractPrimitiveType; 22 import hunt.collection.Collection; 23 import hunt.collection.HashMap; 24 import hunt.collection.Map; 25 import hunt.collection.ArrayList; 26 import hunt.proton.codec.TypeEncoding; 27 28 import hunt.proton.amqp.Symbol; 29 import hunt.String; 30 import hunt.collection.List; 31 32 class SymbolType : AbstractPrimitiveType!(Symbol) 33 { 34 //private static Charset ASCII_CHARSET = Charset.forName("US-ASCII"); 35 private SymbolEncoding _symbolEncoding; 36 private SymbolEncoding _shortSymbolEncoding; 37 38 private Map!(ReadableBuffer, Symbol) _symbolCache; 39 private DecoderImpl.TypeDecoder!(Symbol) _symbolCreator ; 40 41 interface SymbolEncoding : PrimitiveTypeEncoding!(Symbol) 42 { 43 44 } 45 46 this(EncoderImpl encoder, DecoderImpl decoder) 47 { 48 _symbolCreator = new class DecoderImpl.TypeDecoder!(Symbol) 49 { 50 override 51 public Symbol decode(DecoderImpl decoder, ReadableBuffer buffer) 52 { 53 Symbol symbol = _symbolCache.get(buffer); 54 if (symbol is null) 55 { 56 byte[] bytes = new byte[buffer.limit()]; 57 buffer.get(bytes); 58 59 // String str = new String(cast(string)bytes); 60 symbol = Symbol.getSymbol(cast(string)bytes); 61 62 _symbolCache.put(ByteBufferReader.wrap(bytes), symbol); 63 } 64 return symbol; 65 } 66 }; 67 _symbolCache = new HashMap!(ReadableBuffer, Symbol); 68 _symbolEncoding = new LongSymbolEncoding(encoder, decoder); 69 _shortSymbolEncoding = new ShortSymbolEncoding(encoder, decoder); 70 encoder.register(typeid(Symbol), this); 71 decoder.register(this); 72 } 73 74 public TypeInfo getTypeClass() 75 { 76 return typeid(Symbol); 77 } 78 79 public void fastWrite(EncoderImpl encoder, Symbol symbol) 80 { 81 if (symbol.length() <= 255) 82 { 83 // Reserve size of body + type encoding and single byte size 84 encoder.getBuffer().ensureRemaining(2 + symbol.length()); 85 encoder.writeRaw(EncodingCodes.SYM8); 86 encoder.writeRaw(cast(byte) symbol.length()); 87 symbol.writeTo(encoder.getBuffer()); 88 } 89 else 90 { 91 // Reserve size of body + type encoding and four byte size 92 encoder.getBuffer().ensureRemaining(5 + symbol.length()); 93 encoder.writeRaw(EncodingCodes.SYM32); 94 encoder.writeRaw(symbol.length()); 95 symbol.writeTo(encoder.getBuffer()); 96 } 97 } 98 99 public ITypeEncoding getEncoding(Object val) 100 { 101 return (cast(Symbol)val).length() <= 255 ? _shortSymbolEncoding : _symbolEncoding; 102 } 103 104 public SymbolEncoding getCanonicalEncoding() 105 { 106 return _symbolEncoding; 107 } 108 109 public Collection!(TypeEncoding!(Symbol)) getAllEncodings() 110 { 111 List!(TypeEncoding!(Symbol)) lst = new ArrayList!(TypeEncoding!(Symbol)); 112 lst.add(_shortSymbolEncoding); 113 lst.add(_symbolEncoding); 114 return lst; 115 //return Arrays.asList(_shortSymbolEncoding, _symbolEncoding); 116 } 117 118 119 //Collection!(PrimitiveTypeEncoding!(Symbol)) getAllEncodings() 120 //{ 121 // return super.getAllEncodings(); 122 //} 123 124 class LongSymbolEncoding 125 : LargeFloatingSizePrimitiveTypeEncoding!(Symbol) 126 , SymbolEncoding 127 { 128 129 this(EncoderImpl encoder, DecoderImpl decoder) 130 { 131 super(encoder, decoder); 132 } 133 134 override 135 protected void writeEncodedValue(Symbol val) 136 { 137 getEncoder().getBuffer().ensureRemaining(getEncodedValueSize(val)); 138 val.writeTo(getEncoder().getBuffer()); 139 } 140 141 override 142 protected int getEncodedValueSize(Symbol val) 143 { 144 return val.length(); 145 } 146 147 override 148 public byte getEncodingCode() 149 { 150 return EncodingCodes.SYM32; 151 } 152 153 override 154 public SymbolType getType() 155 { 156 return this.outer; 157 } 158 159 override 160 public bool encodesSuperset(TypeEncoding!(Symbol) encoding) 161 { 162 return (getType() == encoding.getType()); 163 } 164 165 override 166 public Object readValue() 167 { 168 DecoderImpl decoder = getDecoder(); 169 int size = decoder.readRawInt(); 170 return decoder.readRaw(_symbolCreator, size); 171 } 172 173 override 174 public void skipValue() 175 { 176 DecoderImpl decoder = getDecoder(); 177 ReadableBuffer buffer = decoder.getBuffer(); 178 int size = decoder.readRawInt(); 179 buffer.position(buffer.position() + size); 180 } 181 182 override bool encodesJavaPrimitive() 183 { 184 return super.encodesJavaPrimitive(); 185 } 186 187 override TypeInfo getTypeClass() 188 { 189 return super.getTypeClass(); 190 } 191 192 override void writeConstructor() 193 { 194 return super.writeConstructor(); 195 } 196 197 override int getConstructorSize() 198 { 199 return super.getConstructorSize(); 200 } 201 } 202 203 class ShortSymbolEncoding 204 : SmallFloatingSizePrimitiveTypeEncoding!(Symbol) 205 , SymbolEncoding 206 { 207 208 this(EncoderImpl encoder, DecoderImpl decoder) 209 { 210 super(encoder, decoder); 211 } 212 213 override 214 protected void writeEncodedValue(Symbol val) 215 { 216 getEncoder().getBuffer().ensureRemaining(getEncodedValueSize(val)); 217 val.writeTo(getEncoder().getBuffer()); 218 } 219 220 override 221 protected int getEncodedValueSize(Symbol val) 222 { 223 return val.length(); 224 } 225 226 override 227 public byte getEncodingCode() 228 { 229 return EncodingCodes.SYM8; 230 } 231 232 override 233 public SymbolType getType() 234 { 235 return this.outer; 236 } 237 238 override 239 public bool encodesSuperset(TypeEncoding!(Symbol) encoder) 240 { 241 return encoder == this; 242 } 243 244 override 245 public Symbol readValue() 246 { 247 DecoderImpl decoder = getDecoder(); 248 int size = (cast(int)decoder.readRawByte()) & 0xff; 249 return decoder.readRaw(_symbolCreator, size); 250 } 251 252 override 253 public void skipValue() 254 { 255 DecoderImpl decoder = getDecoder(); 256 ReadableBuffer buffer = decoder.getBuffer(); 257 int size = (cast(int)decoder.readRawByte()) & 0xff; 258 buffer.position(buffer.position() + size); 259 } 260 261 override bool encodesJavaPrimitive() 262 { 263 return super.encodesJavaPrimitive(); 264 } 265 266 override TypeInfo getTypeClass() 267 { 268 return super.getTypeClass(); 269 } 270 271 override void writeConstructor() 272 { 273 return super.writeConstructor(); 274 } 275 276 override int getConstructorSize() 277 { 278 return super.getConstructorSize(); 279 } 280 } 281 }