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.transport.DispositionType; 14 15 import hunt.collection.AbstractList; 16 import hunt.collection.List; 17 import hunt.proton.amqp.Symbol; 18 import hunt.proton.amqp.UnsignedInteger; 19 import hunt.proton.amqp.UnsignedLong; 20 import hunt.proton.amqp.transport.DeliveryState; 21 import hunt.proton.amqp.transport.Disposition; 22 import hunt.proton.amqp.transport.Role; 23 import hunt.proton.codec.AbstractDescribedType; 24 import hunt.proton.codec.DecodeException; 25 import hunt.proton.codec.Decoder; 26 import hunt.proton.codec.DescribedTypeConstructor; 27 import hunt.proton.codec.EncoderImpl; 28 import std.concurrency : initOnce; 29 import hunt.Boolean; 30 import hunt.logging; 31 32 class DispositionWrapper : AbstractList!Object 33 { 34 35 private Disposition _disposition; 36 37 this(Disposition disposition) 38 { 39 _disposition = disposition; 40 } 41 42 override 43 public Object get(int index) 44 { 45 46 switch(index) 47 { 48 case 0: 49 return new Boolean( _disposition.getRole().getValue()); 50 case 1: 51 return _disposition.getFirst(); 52 case 2: 53 return _disposition.getLast(); 54 case 3: 55 return _disposition.getSettled(); 56 case 4: 57 return cast(Object)(_disposition.getState()); 58 case 5: 59 return _disposition.getBatchable(); 60 default: 61 return null; 62 } 63 64 // throw new IllegalStateException("Unknown index " ~ index); 65 66 } 67 68 override 69 public int size() 70 { 71 return _disposition.getBatchable().booleanValue() 72 ? 6 73 : _disposition.getState() !is null 74 ? 5 75 : _disposition.getSettled().booleanValue() 76 ? 4 77 : _disposition.getLast() !is null 78 ? 3 79 : 2; 80 81 } 82 } 83 84 class DispositionType : AbstractDescribedType!(Disposition,List!Object) , DescribedTypeConstructor!(Disposition) 85 { 86 //private static Object[] DESCRIPTORS = 87 //{ 88 // UnsignedLong.valueOf(0x0000000000000015L), Symbol.valueOf("amqp:disposition:list"), 89 //}; 90 // 91 //private static UnsignedLong DESCRIPTOR = UnsignedLong.valueOf(0x0000000000000015L); 92 93 static Object[] DESCRIPTORS() { 94 __gshared Object[] inst; 95 return initOnce!inst([UnsignedLong.valueOf(0x0000000000000015L), Symbol.valueOf("amqp:disposition:list")]); 96 } 97 98 static UnsignedLong DESCRIPTOR() { 99 __gshared UnsignedLong inst; 100 return initOnce!inst(UnsignedLong.valueOf(0x0000000000000015L)); 101 } 102 103 this(EncoderImpl encoder) 104 { 105 super(encoder); 106 } 107 108 override 109 public UnsignedLong getDescriptor() 110 { 111 return DESCRIPTOR; 112 } 113 114 override 115 protected List!Object wrap(Disposition val) 116 { 117 return new DispositionWrapper(val); 118 } 119 120 121 122 123 public Disposition newInstance(Object described) 124 { 125 List!Object l = cast(List!Object) described; 126 127 Disposition o = new Disposition(); 128 129 if(l.isEmpty()) 130 { 131 // throw new DecodeException("The first field cannot be omitted"); 132 logError("The first field cannot be omitted"); 133 return null; 134 } 135 136 switch(6 - l.size()) 137 { 138 139 case 0: 140 Boolean batchable = cast(Boolean) l.get(5); 141 o.setBatchable(batchable is null ? null : batchable); 142 goto case; 143 case 1: 144 o.setState( cast(DeliveryState) l.get( 4 ) ); 145 goto case; 146 case 2: 147 Boolean settled = cast(Boolean) l.get(3); 148 o.setSettled(settled is null ? null : settled); 149 goto case; 150 case 3: 151 o.setLast( cast(UnsignedInteger) l.get( 2 ) ); 152 goto case; 153 case 4: 154 o.setFirst( cast(UnsignedInteger) l.get( 1 ) ); 155 goto case; 156 case 5: 157 Boolean tmp = cast(Boolean) l.get( 0 ); 158 o.setRole( tmp.booleanValue() ? Role.RECEIVER : Role.SENDER ); 159 break; 160 default: 161 break; 162 } 163 164 165 return o; 166 } 167 168 public TypeInfo getTypeClass() 169 { 170 return typeid(Disposition); 171 } 172 173 174 175 176 public static void register(Decoder decoder, EncoderImpl encoder) 177 { 178 DispositionType type = new DispositionType(encoder); 179 foreach(Object descriptor ; DESCRIPTORS) 180 { 181 decoder.registerDynamic(descriptor, type); 182 } 183 encoder.register(type); 184 } 185 186 187 }