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.FlowType; 14 15 import hunt.collection.AbstractList; 16 import hunt.collection.List; 17 import hunt.collection.Map; 18 import hunt.proton.amqp.Symbol; 19 import hunt.proton.amqp.UnsignedInteger; 20 import hunt.proton.amqp.UnsignedLong; 21 import hunt.proton.amqp.transport.Flow; 22 import hunt.proton.codec.AbstractDescribedType; 23 import hunt.proton.codec.DecodeException; 24 import hunt.proton.codec.Decoder; 25 import hunt.proton.codec.DescribedTypeConstructor; 26 import hunt.proton.codec.EncoderImpl; 27 import std.concurrency : initOnce; 28 import hunt.logging; 29 import hunt.Object; 30 import hunt.Boolean; 31 32 class FlowWrapper : AbstractList!Object 33 { 34 35 36 private Flow _flow; 37 38 this(Flow flow) 39 { 40 _flow = flow; 41 } 42 43 override 44 public Object get(int index) 45 { 46 47 switch(index) 48 { 49 case 0: 50 return _flow.getNextIncomingId(); 51 case 1: 52 return _flow.getIncomingWindow(); 53 case 2: 54 return _flow.getNextOutgoingId(); 55 case 3: 56 return _flow.getOutgoingWindow(); 57 case 4: 58 return _flow.getHandle(); 59 case 5: 60 return _flow.getDeliveryCount(); 61 case 6: 62 return _flow.getLinkCredit(); 63 case 7: 64 return _flow.getAvailable(); 65 case 8: 66 return _flow.getDrain(); 67 case 9: 68 return _flow.getEcho(); 69 case 10: 70 return cast(Object) _flow.getProperties(); 71 default: 72 return null; 73 } 74 75 // throw new IllegalStateException("Unknown index " ~ index); 76 77 } 78 79 override 80 public int size() 81 { 82 return _flow.getProperties() !is null 83 ? 11 84 : _flow.getEcho().booleanValue 85 ? 10 86 : _flow.getDrain().booleanValue 87 ? 9 88 : _flow.getAvailable() !is null 89 ? 8 90 : _flow.getLinkCredit() !is null 91 ? 7 92 : _flow.getDeliveryCount() !is null 93 ? 6 94 : _flow.getHandle() !is null 95 ? 5 96 : 4; 97 98 } 99 } 100 101 class FlowType : AbstractDescribedType!(Flow,List!Object) , DescribedTypeConstructor!(Flow) 102 { 103 //private static Object[] DESCRIPTORS = 104 //{ 105 // UnsignedLong.valueOf(0x0000000000000013L), Symbol.valueOf("amqp:flow:list"), 106 //}; 107 // 108 //private static UnsignedLong DESCRIPTOR = UnsignedLong.valueOf(0x0000000000000013L); 109 110 static Object[] DESCRIPTORS() { 111 __gshared Object[] inst; 112 return initOnce!inst([UnsignedLong.valueOf(0x0000000000000013L), Symbol.valueOf("amqp:flow:list")]); 113 } 114 115 static UnsignedLong DESCRIPTOR() { 116 __gshared UnsignedLong inst; 117 return initOnce!inst(UnsignedLong.valueOf(0x0000000000000013L)); 118 } 119 120 121 this(EncoderImpl encoder) 122 { 123 super(encoder); 124 } 125 126 override 127 public UnsignedLong getDescriptor() 128 { 129 return DESCRIPTOR; 130 } 131 132 override 133 protected List!Object wrap(Flow val) 134 { 135 return new FlowWrapper(val); 136 } 137 138 139 140 public Flow newInstance(Object described) 141 { 142 List!Object l = cast(List!Object) described; 143 144 Flow o = new Flow(); 145 146 if(l.size() <= 3) 147 { 148 logError("The outgoing-window field cannot be omitted"); 149 // throw new DecodeException("The outgoing-window field cannot be omitted"); 150 } 151 152 switch(11 - l.size()) 153 { 154 155 case 0: 156 o.setProperties( cast(IObject) l.get( 10 ) ); 157 goto case; 158 case 1: 159 Boolean echo = cast(Boolean) l.get(9); 160 o.setEcho(echo is null ? null : echo); 161 goto case; 162 case 2: 163 Boolean drain = cast(Boolean) l.get(8); 164 o.setDrain(drain is null ? null : drain ); 165 goto case; 166 case 3: 167 o.setAvailable( cast(UnsignedInteger) l.get( 7 ) ); 168 goto case; 169 case 4: 170 o.setLinkCredit( cast(UnsignedInteger) l.get( 6 ) ); 171 goto case; 172 case 5: 173 o.setDeliveryCount( cast(UnsignedInteger) l.get( 5 ) ); 174 goto case; 175 case 6: 176 o.setHandle( cast(UnsignedInteger) l.get( 4 ) ); 177 goto case; 178 case 7: 179 o.setOutgoingWindow( cast(UnsignedInteger) l.get( 3 ) ); 180 goto case; 181 case 8: 182 o.setNextOutgoingId( cast(UnsignedInteger) l.get( 2 ) ); 183 goto case; 184 case 9: 185 o.setIncomingWindow( cast(UnsignedInteger) l.get( 1 ) ); 186 goto case; 187 case 10: 188 o.setNextIncomingId( cast(UnsignedInteger) l.get( 0 ) ); 189 break; 190 default: 191 break; 192 } 193 194 195 return o; 196 } 197 198 public TypeInfo getTypeClass() 199 { 200 return typeid(Flow); 201 } 202 203 public static void register(Decoder decoder, EncoderImpl encoder) 204 { 205 FlowType type = new FlowType(encoder); 206 foreach(Object descriptor ; DESCRIPTORS) 207 { 208 decoder.registerDynamic(descriptor, type); 209 } 210 encoder.register(type); 211 } 212 }