1 module hunt.gossip.Buffer;
2 
3 import hunt.util.Common;
4 import std.ascii;
5 import std.algorithm;
6 import std.array;
7 import std.exception;
8 import std.conv;
9 import std.string;
10 import std.uni;
11 import std.json;
12 import hunt.gossip.JsonObject;
13 
14 
15 class Buffer : Appendable {
16     private Appender!(byte[]) _buffer;
17 
18     private this(size_t capacity = 16) {
19         _buffer.reserve(capacity);
20     }
21 
22     private this(string data, size_t capacity = 16) {
23         _buffer.reserve(capacity);
24         this.append(data);
25     }
26 
27     static Buffer buffer()
28     {
29         return new Buffer();
30     }
31 
32     void reset() {
33         _buffer.clear();
34     }
35 
36     Buffer setCharAt(int index, char c) {
37         _buffer.data[index] = c;
38         return this;
39     }
40 
41     Buffer append(char s) {
42         _buffer.put(s);
43         return this;
44     }
45 
46     Buffer append(bool s) {
47         append(s.to!string());
48         return this;
49     }
50 
51     Buffer append(int i) {
52         _buffer.put(cast(byte[])(to!(string)(i)));
53         return this;
54     }
55 
56     Buffer append(float f) {
57         _buffer.put(cast(byte[])(to!(string)(f)));
58         return this;
59     }
60 
61     Buffer append(const(char)[] s) {
62         _buffer.put(cast(byte[]) s);
63         return this;
64     }
65 
66     Buffer append(const(char)[] s, int start, int end) {
67         _buffer.put(cast(byte[]) s[start .. end]);
68         return this;
69     }
70 
71     /// Warning: It's different from the previous one.
72     Buffer append(byte[] str, int offset, int len) {
73         _buffer.put(str[offset .. offset + len]);
74         return this;
75     }
76 
77     Buffer append(Object obj) {
78         _buffer.put(cast(byte[])(obj.toString));
79         return this;
80     }
81 
82     int length() {
83         return cast(int) _buffer.data.length;
84     }
85 
86     void setLength(int newLength) {
87         _buffer.shrinkTo(newLength);
88     }
89 
90     int lastIndexOf(string s) {
91         string source = cast(string) _buffer.data;
92         return cast(int) source.lastIndexOf(s);
93     }
94 
95     char charAt(int idx)
96     {
97         if(length() > idx)
98            return _buffer.data[idx];
99         else
100             return ' ';
101     }
102 
103     public Buffer deleteCharAt(int index) {
104         if(index < length())
105         {
106             auto data = _buffer.data.idup;
107             for(int i = index+1 ; i < data.length ; i++)
108             {
109                 _buffer.data[i-1] = data[i];
110             }
111             setLength(cast(int)(data.length-1));
112         }
113         return this;
114     }
115 
116     public Buffer insert(int index, char c) {
117         if(index <= length())
118         {
119             auto data = _buffer.data.idup;
120             for(int i = index ; i < data.length ; i++)
121             {
122                 _buffer.data[i+1] = data[i];
123             }
124             _buffer.data[index] = c;
125             setLength(cast(int)(data.length+1));
126         }
127         return this;
128     }
129 
130     public Buffer insert(int index, long data) {
131         auto bytes = cast(byte[])(to!string(data));
132         auto start = index;
133         foreach( b; bytes) {
134             insert(start , cast(char)b);
135             start++;
136         }
137         return this;
138     }
139 
140     public Buffer replace(int start, int end, string str) {
141         if( start <= end && start < length() && end < length())
142         {
143             if(str.length >= end)
144                 _buffer.data[start .. end ] = cast(byte[])(str[start .. end]);
145         }
146         return this;
147     }
148 
149     override string toString() {
150         string s = cast(string) _buffer.data.idup;
151         if (s is null)
152             return "";
153         else
154             return s;
155     }
156 
157     public byte[] data()
158     {
159         return _buffer.data.dup;
160     }
161 
162     public JsonObject toJsonObject()
163     {
164         try{
165             return new JsonObject(parseJSON(cast(string)data()));
166         }
167         catch(Exception e)
168         {
169         }
170         return null;
171     }
172 
173     public Buffer appendString(string str)
174     {
175         return append(str);
176     }
177 
178 }