1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
/**
* \class document::ByteBuffer
* \ingroup util
*
* \brief Java like bytebuffer class
*
* This class wraps a char* buffer with a length and position.
* It can be used to hide from the user whether the buffer was
* allocated or not, and can hold a position in the buffer which
* can be used for streaming-like behaviour.
*
* @author Thomas F. Gundersen, �ystein Fledsberg, Einar Rosenvinge
*/
#pragma once
#include <vespa/vespalib/util/alloc.h>
namespace document {
class ByteBuffer
{
public:
using UP = std::unique_ptr<ByteBuffer>;
ByteBuffer(const ByteBuffer &);
ByteBuffer& operator=(const ByteBuffer &) = delete;
ByteBuffer(ByteBuffer &&) = default;
ByteBuffer& operator=(ByteBuffer &&) = default;
ByteBuffer() : ByteBuffer(nullptr, 0) { }
~ByteBuffer() = default;
/**
* Create a buffer with the given content.
*
* @param buffer The buffer to represent.
* @param len The length of the buffer
*/
ByteBuffer(const char* buffer, uint32_t len)
: _buffer(const_cast<char *>(buffer)),
_len(len),
_pos(0),
_ownedBuffer()
{ }
/**
* Create a buffer with the given content.
*
* @param buffer The buffer to represent.
* @param len The length of the buffer
*/
ByteBuffer(vespalib::alloc::Alloc buffer, uint32_t len);
ByteBuffer(std::unique_ptr<vespalib::alloc::Alloc> buffer, uint32_t len);
/**
* Creates a ByteBuffer object from another buffer. allocates
* a new buffer of same size and copies the content.
*
* @param buffer The buffer to copy.
* @param len The length of the buffer.
*
* @return Returns a newly created bytebuffer object, or nullptr
* if buffer was nullptr, or len was <=0.
*/
static ByteBuffer copyBuffer(const char* buffer, uint32_t len);
/** @return Returns the buffer pointed to by this object (at position 0) */
const char* getBuffer() const { return _buffer; }
/** @return Returns the length of the buffer pointed to by this object. */
uint32_t getLength() const { return _len; }
/** @return Returns a pointer to the current position in the buffer. */
const char* getBufferAtPos() const { return _buffer + _pos; }
/** @return Returns the index of the current position in the buffer. */
uint32_t getPos() const { return _pos; }
/**
* @return Returns the number of bytes remaining in the buffer - that is,
* getLength()-getPos().
*/
uint32_t getRemaining() const { return _len -_pos; }
/**
* Moves the position in the buffer.
*
* @param pos The number of bytes to move the position. The new position
* will be oldPos + pos. This is the same as doing
* setPos(getPos()+pos)
* @throws BufferOutOfBoundsException;
*/
void incPos(uint32_t pos);
void getNumeric(uint8_t & v);
void getNumericNetwork(int16_t & v);
void getNumericNetwork(int32_t & v);
void getNumericNetwork(int64_t & v);
void getNumeric(int64_t& v);
void getNumericNetwork(double & v);
void getChar(char & val) { unsigned char t;getByte(t); val=t; }
void getByte(uint8_t & v) { getNumeric(v); }
void getShortNetwork(int16_t & v) { getNumericNetwork(v); }
void getIntNetwork(int32_t & v) { getNumericNetwork(v); }
void getLongNetwork(int64_t & v) { getNumericNetwork(v); }
void getLong(int64_t& v) { getNumeric(v); }
void getDoubleNetwork(double & v) { getNumericNetwork(v); }
void getBytes(void *buffer, uint32_t count);
private:
template<typename T>
void getDoubleLongNetwork(T &val);
void incPosNoCheck(uint32_t pos) { _pos += pos; }
const char * _buffer;
uint32_t _len;
uint32_t _pos;
std::unique_ptr<vespalib::alloc::Alloc> _ownedBuffer;
};
} // document
|