(State s, byte[] data, int offset, int length)
| 231 | } |
| 232 | |
| 233 | static int copyRawBytes(State s, byte[] data, int offset, int length) { |
| 234 | int pos = offset; |
| 235 | int len = length; |
| 236 | if ((s.bitOffset & 7) != 0) { |
| 237 | return Utils.makeError(s, BROTLI_PANIC_UNALIGNED_COPY_BYTES); |
| 238 | } |
| 239 | |
| 240 | // Drain accumulator. |
| 241 | while ((s.bitOffset != BITNESS) && (len != 0)) { |
| 242 | data[pos++] = (byte) peekBits(s); |
| 243 | s.bitOffset += 8; |
| 244 | len--; |
| 245 | } |
| 246 | if (len == 0) { |
| 247 | return BROTLI_OK; |
| 248 | } |
| 249 | |
| 250 | // Get data from shadow buffer with "sizeof(int)" granularity. |
| 251 | final int copyNibbles = Utils.min(halfAvailable(s), len >> LOG_HALF_SIZE); |
| 252 | if (copyNibbles > 0) { |
| 253 | final int readOffset = s.halfOffset << LOG_HALF_SIZE; |
| 254 | final int delta = copyNibbles << LOG_HALF_SIZE; |
| 255 | Utils.copyBytes(data, pos, s.byteBuffer, readOffset, readOffset + delta); |
| 256 | pos += delta; |
| 257 | len -= delta; |
| 258 | s.halfOffset += copyNibbles; |
| 259 | } |
| 260 | if (len == 0) { |
| 261 | return BROTLI_OK; |
| 262 | } |
| 263 | |
| 264 | // Read tail bytes. |
| 265 | if (halfAvailable(s) > 0) { |
| 266 | // length = 1..3 |
| 267 | fillBitWindow(s); |
| 268 | while (len != 0) { |
| 269 | data[pos++] = (byte) peekBits(s); |
| 270 | s.bitOffset += 8; |
| 271 | len--; |
| 272 | } |
| 273 | return checkHealth(s, 0); |
| 274 | } |
| 275 | |
| 276 | // Now it is possible to copy bytes directly. |
| 277 | while (len > 0) { |
| 278 | final int chunkLen = Utils.readInput(s, data, pos, len); |
| 279 | if (chunkLen < BROTLI_ERROR) { |
| 280 | return chunkLen; |
| 281 | } |
| 282 | // EOF is -1 in Java, but 0 in C#. |
| 283 | if (chunkLen <= 0) { |
| 284 | return Utils.makeError(s, BROTLI_ERROR_TRUNCATED_INPUT); |
| 285 | } |
| 286 | pos += chunkLen; |
| 287 | len -= chunkLen; |
| 288 | } |
| 289 | return BROTLI_OK; |
| 290 | } |
no test coverage detected