forked from kbinani/libvsq
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathByteArrayOutputStream.hpp
More file actions
158 lines (140 loc) · 3.72 KB
/
Copy pathByteArrayOutputStream.hpp
File metadata and controls
158 lines (140 loc) · 3.72 KB
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#ifndef __ByteArrayOutputStream_h__
#define __ByteArrayOutputStream_h__
#include <string>
#include <cmath>
#include <vector>
#include "vsqglobal.hpp"
#include "OutputStream.hpp"
VSQ_BEGIN_NAMESPACE
/**
* データがバイト配列に書き込まれるストリームの実装
* @class table
* @name ByteArrayOutputStream
*/
class ByteArrayOutputStream : public VSQ_NS::OutputStream
{
protected:
/**
* @brief 確保するバッファー・ブロックのサイズ(バイト単位)
*/
static const int UNIT_BUFFER_LENGTH = 512;
private:
/**
* 現在のファイルポインタ
*/
int64_t _pointer;
/**
* @brief 書き込み先のバイト列
*/
char *_array;
/**
* @brief 確保されたバイト列の現在の長さ
*/
int64_t _arrayLength;
/**
* @brief 書き込み済みバイト数
*/
int64_t _length;
public:
/**
* @brief 初期化を行う
*/
ByteArrayOutputStream()
{
_pointer = 0;
_arrayLength = UNIT_BUFFER_LENGTH;
_array = (char *)::calloc( _arrayLength, sizeof( char ) );
_length = 0;
}
~ByteArrayOutputStream()
{
close();
}
/**
* 指定されたバイト値をストリームに書きこむ
* @param byte (int) 書きこむバイト値
* @name write<! *1 *>
*/
void write( int byte )
{
ensureBufferLength( _pointer + 1 );
_array[_pointer] = (char)byte;
_pointer++;
_length = std::max( _length, _pointer );
}
/**
* @brief 指定された配列の、指定した範囲のバイト値をストリームに書きこむ
* @param array (table) 書きこむバイト列が格納された配列
* @param startIndex (int) 書き込み開始位置
* @param length (int) 書き込むバイト値の個数
* @name write<! *2 *>
*/
void write( const char *array, int64_t startIndex, int64_t length )
{
ensureBufferLength( _pointer + length );
for( int i = 0; i < length; i++ ){
_array[_pointer + i] = array[startIndex + i];
}
_pointer += length;
_length = std::max( _length, _pointer );
}
/**
* @brief バイト列を文字列に変換する
* @return (string) 変換された文字列
*/
const std::string toString()
{
std::string result( _array, _length );
return result;
}
/**
* @brief 現在のファイルポインタを取得する
* @return (int) 現在のファイルポインタ
*/
int64_t getPointer()
{
return _pointer;
}
/**
* @brief ファイルポインタを指定した位置に変更する
* @param position (int) 新しいポインタ値
*/
void seek( int64_t position ){
_pointer = (position < 0) ? 0 : position;
}
/**
* @brief ストリームを閉じる
*/
void close()
{
if( _array ){
free( _array );
_array = NULL;
}
_length = 0;
_arrayLength = 0;
}
private:
/**
* @brief バッファーを指定した長さまで確保する
* @param length 確保するバッファーの長さ
*/
void ensureBufferLength( int length )
{
int amount = length - _arrayLength;
if( 0 < amount ){
char *temporary = (char *)realloc( _array, length * sizeof( char ) );
if( !temporary ){
close();
return;
}
_array = temporary;
for( int i = _arrayLength; i < _arrayLength + amount; i++ ){
_array[i] = 0;
}
_arrayLength = length;
}
}
};
VSQ_END_NAMESPACE
#endif