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.BinaryElement;
13 
14 import hunt.io.ByteBuffer;
15 import std.conv;
16 import hunt.proton.codec.impl.AtomicElement;
17 import hunt.proton.codec.impl.Element;
18 import hunt.proton.codec.impl.ArrayElement;
19 import hunt.proton.codec.impl.AbstractElement;
20 
21 import hunt.proton.amqp.Binary;
22 import hunt.proton.codec.Data;
23 
24 class BinaryElement : AtomicElement!Binary
25 {
26 
27     private Binary _value;
28 
29     this(IElement parent, IElement prev, Binary b)
30     {
31         super(parent, prev);
32         byte[] data  = new byte[b.getLength()];
33       //  System.arraycopy(b.getArray(),b.getArrayOffset(),data,0,b.getLength());
34        // data ~= b.getArray()[b.getArrayOffset() .. $];
35         data [0 .. b.getLength()] = b.getArray()[b.getArrayOffset() .. b.getArrayOffset()+b.getLength()];
36         _value = new Binary(data);
37     }
38 
39     public int size()
40     {
41         int length = _value.getLength();
42 
43         if(isElementOfArray())
44         {
45             ArrayElement parent = cast(ArrayElement) parent();
46 
47             if(parent.constructorType() == ArrayElement.SMALL)
48             {
49                 if(length > 255)
50                 {
51                     parent.setConstructorType(ArrayElement.LARGE);
52                     return 4+length;
53                 }
54                 else
55                 {
56                     return 1+length;
57                 }
58             }
59             else
60             {
61                 return 4+length;
62             }
63         }
64         else
65         {
66             if(length >255)
67             {
68                 return 5 + length;
69             }
70             else
71             {
72                 return 2 + length;
73             }
74         }
75     }
76 
77     public Object getValue()
78     {
79         return _value;
80     }
81 
82     public Data.DataType getDataType()
83     {
84         return Data.DataType.BINARY;
85     }
86 
87     public int encode(ByteBuffer b)
88     {
89         int size = size();
90         if(b.remaining()<size)
91         {
92             return 0;
93         }
94         if(isElementOfArray())
95         {
96             ArrayElement parent = cast(ArrayElement) parent();
97 
98             if(parent.constructorType() == ArrayElement.SMALL)
99             {
100                 b.put(cast(byte)_value.getLength());
101             }
102             else
103             {
104                 b.putInt(_value.getLength());
105             }
106         }
107         else if(_value.getLength()<=255)
108         {
109             b.put(cast(byte)0xa0);
110             b.put(cast(byte)_value.getLength());
111         }
112         else
113         {
114             b.put(cast(byte)0xb0);
115             b.putInt(_value.getLength());
116         }
117         b.put(_value.getArray(),_value.getArrayOffset(),_value.getLength());
118         return size;
119 
120     }
121 
122     override
123     IElement addChild(IElement element)
124     {
125             return super.addChild(element);
126     }
127 
128 
129     override
130     IElement checkChild(IElement element)
131     {
132         return super.checkChild(element);
133     }
134 
135     override
136     void setChild(IElement elt)
137     {
138         super.setChild(elt);
139     }
140 
141 }