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 | |
39 | namespace Hdfs { |
40 | namespace Internal { |
41 | |
42 | /** |
43 | * a data buffer used to read and write. |
44 | */ |
45 | class WriteBuffer { |
46 | public: |
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 | |
237 | private: |
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 | |