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 }