|
1 /*------------------------------------------------------------------------------ |
|
2 * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team |
|
3 * |
|
4 * Distributable under the terms of either the Apache License (Version 2.0) or |
|
5 * the GNU Lesser General Public License, as specified in the COPYING file. |
|
6 ------------------------------------------------------------------------------*/ |
|
7 #include "clucene/stdheader.h" |
|
8 #include "IndexOutput.h" |
|
9 |
|
10 CL_NS_USE(util) |
|
11 CL_NS_DEF(store) |
|
12 |
|
13 |
|
14 IndexOutput::IndexOutput() |
|
15 { |
|
16 } |
|
17 |
|
18 IndexOutput::~IndexOutput(){ |
|
19 } |
|
20 |
|
21 BufferedIndexOutput::BufferedIndexOutput() |
|
22 { |
|
23 buffer = _CL_NEWARRAY(uint8_t, BUFFER_SIZE ); |
|
24 bufferStart = 0; |
|
25 bufferPosition = 0; |
|
26 } |
|
27 |
|
28 BufferedIndexOutput::~BufferedIndexOutput(){ |
|
29 if ( buffer != NULL ) |
|
30 close(); |
|
31 } |
|
32 |
|
33 void BufferedIndexOutput::close(){ |
|
34 flush(); |
|
35 _CLDELETE_ARRAY( buffer ); |
|
36 |
|
37 bufferStart = 0; |
|
38 bufferPosition = 0; |
|
39 } |
|
40 |
|
41 void BufferedIndexOutput::writeByte(const uint8_t b) { |
|
42 CND_PRECONDITION(buffer!=NULL,"IndexOutput is closed") |
|
43 if (bufferPosition >= BUFFER_SIZE) |
|
44 flush(); |
|
45 buffer[bufferPosition++] = b; |
|
46 } |
|
47 |
|
48 void BufferedIndexOutput::writeBytes(const uint8_t* b, const int32_t length) { |
|
49 if ( length < 0 ) |
|
50 _CLTHROWA(CL_ERR_IllegalArgument, "IO Argument Error. Value must be a positive value."); |
|
51 int32_t bytesLeft = BUFFER_SIZE - bufferPosition; |
|
52 // is there enough space in the buffer? |
|
53 if (bytesLeft >= length) { |
|
54 // we add the data to the end of the buffer |
|
55 memcpy(buffer + bufferPosition, b, length); |
|
56 bufferPosition += length; |
|
57 // if the buffer is full, flush it |
|
58 if (BUFFER_SIZE - bufferPosition == 0) |
|
59 flush(); |
|
60 } else { |
|
61 // is data larger then buffer? |
|
62 if (length > BUFFER_SIZE) { |
|
63 // we flush the buffer |
|
64 if (bufferPosition > 0) |
|
65 flush(); |
|
66 // and write data at once |
|
67 flushBuffer(b, length); |
|
68 bufferStart += length; |
|
69 } else { |
|
70 // we fill/flush the buffer (until the input is written) |
|
71 int64_t pos = 0; // position in the input data |
|
72 int32_t pieceLength; |
|
73 while (pos < length) { |
|
74 if ( length - pos < bytesLeft ) |
|
75 pieceLength = length - pos; |
|
76 else |
|
77 pieceLength = bytesLeft; |
|
78 memcpy(buffer + bufferPosition, b + pos, pieceLength); |
|
79 pos += pieceLength; |
|
80 bufferPosition += pieceLength; |
|
81 // if the buffer is full, flush it |
|
82 bytesLeft = BUFFER_SIZE - bufferPosition; |
|
83 if (bytesLeft == 0) { |
|
84 flush(); |
|
85 bytesLeft = BUFFER_SIZE; |
|
86 } |
|
87 } |
|
88 } |
|
89 } |
|
90 } |
|
91 |
|
92 void IndexOutput::writeInt(const int32_t i) { |
|
93 writeByte((uint8_t)(i >> 24)); |
|
94 writeByte((uint8_t)(i >> 16)); |
|
95 writeByte((uint8_t)(i >> 8)); |
|
96 writeByte((uint8_t) i); |
|
97 } |
|
98 |
|
99 void IndexOutput::writeVInt(const int32_t vi) { |
|
100 uint32_t i = vi; |
|
101 while ((i & ~0x7F) != 0) { |
|
102 writeByte((uint8_t)((i & 0x7f) | 0x80)); |
|
103 i >>= 7; //doing unsigned shift |
|
104 } |
|
105 writeByte( (uint8_t)i ); |
|
106 } |
|
107 |
|
108 void IndexOutput::writeLong(const int64_t i) { |
|
109 writeInt((int32_t) (i >> 32)); |
|
110 writeInt((int32_t) i); |
|
111 } |
|
112 |
|
113 void IndexOutput::writeVLong(const int64_t vi) { |
|
114 uint64_t i = vi; |
|
115 while ((i & ~0x7F) != 0) { |
|
116 writeByte((uint8_t)((i & 0x7f) | 0x80)); |
|
117 i >>= 7; //doing unsigned shift |
|
118 } |
|
119 writeByte((uint8_t)i); |
|
120 } |
|
121 |
|
122 void IndexOutput::writeString(const TCHAR* s, const int32_t length ) { |
|
123 writeVInt(length); |
|
124 writeChars(s, 0, length); |
|
125 } |
|
126 |
|
127 void IndexOutput::writeChars(const TCHAR* s, const int32_t start, const int32_t length){ |
|
128 if ( length < 0 || start < 0 ) |
|
129 _CLTHROWA(CL_ERR_IllegalArgument, "IO Argument Error. Value must be a positive value."); |
|
130 |
|
131 const int32_t end = start + length; |
|
132 for (int32_t i = start; i < end; ++i) { |
|
133 const int32_t code = (int32_t)s[i]; |
|
134 if (code >= 0x01 && code <= 0x7F) |
|
135 writeByte((uint8_t)code); |
|
136 else if (((code >= 0x80) && (code <= 0x7FF)) || code == 0) { |
|
137 writeByte((uint8_t)(0xC0 | (code >> 6))); |
|
138 writeByte((uint8_t)(0x80 | (code & 0x3F))); |
|
139 } else { |
|
140 writeByte((uint8_t)(0xE0 | (((uint32_t)code) >> 12))); //unsigned shift |
|
141 writeByte((uint8_t)(0x80 | ((code >> 6) & 0x3F))); |
|
142 writeByte((uint8_t)(0x80 | (code & 0x3F))); |
|
143 } |
|
144 } |
|
145 } |
|
146 |
|
147 |
|
148 int64_t BufferedIndexOutput::getFilePointer() const{ |
|
149 return bufferStart + bufferPosition; |
|
150 } |
|
151 |
|
152 void BufferedIndexOutput::seek(const int64_t pos) { |
|
153 flush(); |
|
154 bufferStart = pos; |
|
155 } |
|
156 |
|
157 void BufferedIndexOutput::flush() { |
|
158 flushBuffer(buffer, bufferPosition); |
|
159 bufferStart += bufferPosition; |
|
160 bufferPosition = 0; |
|
161 } |
|
162 |
|
163 CL_NS_END |