1/********************************************************************
2 * Copyright (c) 2013 - 2014, Pivotal Inc.
3 * All rights reserved.
4 *
5 * Author: Zhanwei Wang
6 ********************************************************************/
7/********************************************************************
8 * 2014 -
9 * open source under Apache License Version 2.0
10 ********************************************************************/
11/**
12 * Licensed to the Apache Software Foundation (ASF) under one
13 * or more contributor license agreements. See the NOTICE file
14 * distributed with this work for additional information
15 * regarding copyright ownership. The ASF licenses this file
16 * to you under the Apache License, Version 2.0 (the
17 * "License"); you may not use this file except in compliance
18 * with the License. You may obtain a copy of the License at
19 *
20 * http://www.apache.org/licenses/LICENSE-2.0
21 *
22 * Unless required by applicable law or agreed to in writing, software
23 * distributed under the License is distributed on an "AS IS" BASIS,
24 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 * See the License for the specific language governing permissions and
26 * limitations under the License.
27 */
28#ifndef _HDFS_LIBHDFS3_COMMON_WRITEBUFFER_H_
29#define _HDFS_LIBHDFS3_COMMON_WRITEBUFFER_H_
30
31#include <cassert>
32#include <cstddef>
33#include <cstring>
34#include <stdint.h>
35#include <vector>
36
37#include <arpa/inet.h>
38
39namespace Hdfs {
40namespace Internal {
41
42/**
43 * a data buffer used to read and write.
44 */
45class WriteBuffer {
46public:
47 /**
48 * Construct a empty buffer.
49 * @throw nothrow
50 */
51 WriteBuffer();
52
53 /**
54 * Destroy a buffer.
55 * @throw nothrow
56 */
57 ~WriteBuffer();
58
59 /**
60 * Write string into buffer.
61 * Terminated '\0' will also be written into buffer.
62 * @param str The string to be written.
63 * @throw nothrow
64 */
65 void writeString(const char * str) {
66 writeString(str, size);
67 }
68
69 /**
70 * Write string into buffer with given position.
71 * Terminated '\0' will also be written into buffer and the data after given position will be overwritten.
72 * @param str The string to be written.
73 * @param pos The given start position in buffer.
74 * @throw nothrow
75 */
76 void writeString(const char * str, size_t pos) {
77 write(str, strlen(str) + 1, pos);
78 }
79
80 /**
81 * Write a vector into buffer.
82 * @param bytes The data be written.
83 * @param s The size of data.
84 */
85 void write(const void * bytes, size_t s) {
86 write(bytes, s, size);
87 }
88
89 /**
90 * Write a vector into buffer with given position.
91 * The data after given position will be overwritten.
92 * @param bytes The data be written.
93 * @param s The size of data.
94 * @param pos The given start position in buffer.
95 */
96 void write(const void * bytes, size_t s, size_t pos);
97
98 /**
99 * Write char into buffer.
100 * @param value The char to be written.
101 * @throw nothrow
102 */
103 void write(char value) {
104 write(value, size);
105 }
106
107 /**
108 * Write char into buffer with given position.
109 * The data after given position will be overwritten.
110 * @param value The char to be written.
111 * @param pos The given start position in buffer.
112 * @throw nothrow
113 */
114 void write(char value, size_t pos) {
115 write(&value, sizeof(value));
116 }
117
118 /**
119 * Convert the 16 bit integer into big endian and write into buffer.
120 * @param value The integer to be written.
121 * @throw nothrow
122 */
123 void writeBigEndian(int16_t value) {
124 writeBigEndian(value, size);
125 }
126
127 /**
128 * Convert the 16 bit integer into big endian and write into buffer with given position.
129 * The data after given position will be overwritten.
130 * @param value The integer to be written.
131 * @param pos The given start position in buffer.
132 * @throw nothrow
133 */
134 void writeBigEndian(int16_t value, size_t pos) {
135 int16_t v = htons(value);
136 write((const char *) &v, sizeof(v));
137 }
138
139 /**
140 * Convert the 32 bit integer into big endian and write into buffer.
141 * @param value The integer to be written.
142 * @throw nothrow
143 */
144 void writeBigEndian(int32_t value) {
145 writeBigEndian(value, size);
146 }
147
148 /**
149 * Convert the 32 bit integer into big endian and write into buffer with given position.
150 * The data after given position will be overwritten.
151 * @param value The integer to be written.
152 * @param pos The given start position in buffer.
153 * @throw nothrow
154 */
155 void writeBigEndian(int32_t value, size_t pos) {
156 int32_t v = htonl(value);
157 write((const char *) &v, sizeof(v), pos);
158 }
159
160 /**
161 * Convert the 32 bit integer into varint and write into buffer.
162 * @param value The integer to be written.
163 * @throw nothrow
164 */
165 void writeVarint32(int32_t value) {
166 writeVarint32(value, size);
167 }
168
169 /**
170 * Convert the 32 bit integer into varint and write into buffer with given position.
171 * The data after given position will be overwritten.
172 * @param value The integer to be written.
173 * @param pos The given start position in buffer.
174 * @throw nothrow
175 */
176 void writeVarint32(int32_t value, size_t pos);
177
178 /**
179 * Get the buffered data from given offset.
180 * @param offset The size of bytes to be ignored from begin of buffer.
181 * @return The buffered data, or NULL if offset is over the end of data.
182 * @throw nothrow
183 */
184 const char * getBuffer(size_t offset) const {
185 assert(offset <= size && offset < buffer.size());
186
187 if (offset >= size) {
188 return NULL;
189 }
190
191 return &buffer[offset];
192 }
193
194 /**
195 * Get the total bytes in the buffer from offset.
196 * @param offset The size of bytes to be ignored from begin of buffer.
197 * @return The total bytes in the buffer from offset.
198 * @throw nothrow
199 */
200 size_t getDataSize(size_t offset) const {
201 assert(offset <= size);
202 return size - offset;
203 }
204
205 /**
206 * Allocate a region of buffer to caller.
207 * Caller should copy the data into this region manually instead of calling Buffer's method.
208 * This method will set the current data size to offset + s, caller may need to reset it to correct value.
209 * @param offset Expected offset in the buffer, the data after given offset will be overwritten.
210 * @param s Allocate the size of byte.
211 * @return The start address in the buffer from offset, or NULL if offset is over the end of data.
212 * @throw nothrow
213 */
214 char * alloc(size_t offset, size_t s);
215
216 /**
217 * Allocate a region of buffer to caller from the end of current buffer.
218 * Caller should copy the data into this region manually instead of calling Buffer's method.
219 * This method will set the current data size to size + s, caller may need to reset it to correct value.
220 * @param s Allocate the size of byte.
221 * @return The start address in the buffer from offset.
222 * @throw nothrow
223 */
224 char * alloc(size_t s) {
225 return alloc(size, s);
226 }
227
228 /**
229 * Set the available data size.
230 * @param s The size to be set.
231 * throw nothrow
232 */
233 void setBufferDataSize(size_t s) {
234 size = s;
235 }
236
237private:
238 size_t size; //current write position.
239 std::vector<char> buffer;
240
241};
242
243}
244}
245#endif /* _HDFS_LIBHDFS3_COMMON_WRITEBUFFER_H_ */
246