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.StringElement;
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.Symbol;
22 import hunt.proton.codec.Data;
23 import hunt.text.Charset;
24 import hunt.String;
25 
26 class StringElement : AtomicElement!String
27 {
28 
29   //  private static Charset UTF_8 = StandardCharsets.UTF-8;
30     private string _value;
31 
32     this(IElement parent, IElement prev, string s)
33     {
34         super(parent, prev);
35         _value = s;
36     }
37 
38     public int size()
39     {
40         int length = cast(int)_value.length;
41 
42         return size(length);
43     }
44 
45     private int size(int length)
46     {
47         if(isElementOfArray())
48         {
49             ArrayElement parent = cast(ArrayElement) parent();
50 
51             if(parent.constructorType() == ArrayElement.SMALL)
52             {
53                 if(length > 255)
54                 {
55                     parent.setConstructorType(ArrayElement.LARGE);
56                     return 4+length;
57                 }
58                 else
59                 {
60                     return 1+length;
61                 }
62             }
63             else
64             {
65                 return 4+length;
66             }
67         }
68         else
69         {
70             if(length >255)
71             {
72                 return 5 + length;
73             }
74             else
75             {
76                 return 2 + length;
77             }
78         }
79     }
80 
81     public Object getValue()
82     {
83         return new String( _value);
84     }
85 
86     public Data.DataType getDataType()
87     {
88         return Data.DataType.STRING;
89     }
90 
91     public int encode(ByteBuffer b)
92     {
93         byte[] bytes = cast(byte[])_value.dup;
94         int length = cast(int)bytes.length;
95 
96         int size = size(length);
97         if(b.remaining()<size)
98         {
99             return 0;
100         }
101         if(isElementOfArray())
102         {
103             ArrayElement parent = cast(ArrayElement) parent();
104 
105             if(parent.constructorType() == ArrayElement.SMALL)
106             {
107                 b.put(cast(byte)length);
108             }
109             else
110             {
111                 b.putInt(length);
112             }
113         }
114         else if(length<=255)
115         {
116             b.put(cast(byte)0xa1);
117             b.put(cast(byte)length);
118         }
119         else
120         {
121             b.put(cast(byte)0xb1);
122             b.putInt(length);
123         }
124         b.put(bytes);
125         return size;
126 
127     }
128 }