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.impl.DescribedTypeElement; 13 14 import hunt.proton.codec.impl.DescribedTypeImpl; 15 import hunt.proton.codec.impl.AbstractElement; 16 import hunt.proton.codec.impl.Element; 17 import hunt.proton.codec.impl.ArrayElement; 18 import hunt.proton.codec.Data; 19 import hunt.collection.Map; 20 import hunt.io.ByteBuffer; 21 import hunt.proton.amqp.DescribedType; 22 import hunt.proton.codec.Data; 23 import hunt.Exceptions; 24 25 class DescribedTypeElement : AbstractElement!(DescribedType) 26 { 27 private IElement _first; 28 29 this(IElement parent, IElement prev) 30 { 31 super(parent, prev); 32 } 33 34 35 36 37 public int size() 38 { 39 int count = 0; 40 int size = 0; 41 IElement elt = _first; 42 while(elt !is null) 43 { 44 count++; 45 size += elt.size(); 46 elt = elt.next(); 47 } 48 49 if(isElementOfArray()) 50 { 51 throw new IllegalArgumentException("Cannot add described type members to an array"); 52 } 53 else if(count > 2) 54 { 55 throw new IllegalArgumentException("Too many elements in described type"); 56 } 57 else if(count == 0) 58 { 59 size = 3; 60 } 61 else if(count == 1) 62 { 63 size += 2; 64 } 65 else 66 { 67 size+=1; 68 } 69 70 return size; 71 } 72 73 public Object getValue() 74 { 75 Object descriptor = _first is null ? null :_first.getValue(); 76 IElement second = _first is null ? null : _first.next(); 77 Object described = second is null ? null : second.getValue(); 78 return new DescribedTypeImpl(descriptor,described); 79 } 80 81 public Data.DataType getDataType() 82 { 83 return Data.DataType.DESCRIBED; 84 } 85 86 public int encode(ByteBuffer b) 87 { 88 int encodedSize = size(); 89 90 if(encodedSize > b.remaining()) 91 { 92 return 0; 93 } 94 else 95 { 96 b.put(cast(byte) 0); 97 if(_first is null) 98 { 99 b.put(cast(byte)0x40); 100 b.put(cast(byte)0x40); 101 } 102 else 103 { 104 _first.encode(b); 105 if(_first.next() is null) 106 { 107 b.put(cast(byte)0x40); 108 } 109 else 110 { 111 _first.next().encode(b); 112 } 113 } 114 } 115 return encodedSize; 116 } 117 118 public bool canEnter() 119 { 120 return true; 121 } 122 123 public IElement child() 124 { 125 return _first; 126 } 127 128 public void setChild(IElement elt) 129 { 130 _first = elt; 131 } 132 133 public IElement checkChild(IElement element) 134 { 135 if(element.prev() != _first) 136 { 137 throw new IllegalArgumentException("Described Type may only have two elements"); 138 } 139 return element; 140 141 } 142 143 public IElement addChild(IElement element) 144 { 145 _first = element; 146 return element; 147 } 148 149 override 150 string startSymbol() { 151 return "("; 152 } 153 154 override 155 string stopSymbol() { 156 return ")"; 157 } 158 159 }