private int getBytes(int offset, int index, int bufferDataOffset, byte[] data, int dataOffset,
			int length) throws IndexOutOfBoundsException, IOException {
		int availableData = dataSpace - bufferDataOffset;
		int len = availableData < length ? availableData : length;
		int id = dataBufferIdTable[index];
		if (id < 0) {
			if (uninitializedDataSource != null) {
				uninitializedDataSource.get(uninitializedDataSourceOffset + offset, data,
					dataOffset, len);
			}
			else {
				Arrays.fill(data, dataOffset, dataOffset + len, (byte) 0);
			}
		}
		else {
			DataBuffer buffer = bufferMgr.getBuffer(id);
			buffer.get(dataBaseOffset + bufferDataOffset, data, dataOffset, len);
			bufferMgr.releaseBuffer(buffer);
			if (useXORMask) {
				int dataIndex = dataOffset;
				for (int i = 0; i < len; i++, dataIndex++) {
					data[dataIndex] = xorMaskByte(bufferDataOffset++, data[dataIndex]);
				}
			}
		}
		return len;
	}
Get byte data from the specified chained buffer.
@param offset ChainedBuffer offset (needed for uninitialized buffer pass-through)
@param index buffer index within chain
@param bufferDataOffset data offset within specified buffer
@param data destination byte array
@param dataOffset destination array offset within data
@param length number of bytes to read
@return int actual number of byte read.
This could be smaller than length if the end of buffer is 
encountered while reading data.
@throws IndexOutOfBoundsException if an invalid offset, dataOffset, or length is specified.
@throws IOException thrown if IO error occurs
Ghidra/Framework/DB/src/main/java/db/ChainedBuffer.java