![JAR search and dependency download from the Maven repository](/logo.png)
com.aliyun.odps.tunnel.io.ArrowHttpInputStream Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.aliyun.odps.tunnel.io;
import com.google.protobuf.CodedInputStream;
import net.jpountz.lz4.LZ4FrameInputStream;
import org.xerial.snappy.PureJavaCrc32C;
import org.xerial.snappy.SnappyFramedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.util.zip.InflaterInputStream;
public class ArrowHttpInputStream implements ReadableByteChannel {
private InputStream in;
private CompressOption compress;
private byte buf[] = new byte[0];
private PureJavaCrc32C chunkCrc = new PureJavaCrc32C();
private PureJavaCrc32C globalCrc = new PureJavaCrc32C();
private int crcChunkSize;
private int readPos; //can read pos
private int bufSize; //buf size
private int bufCapacity;
private boolean isOpen;
private boolean isLastChunk;
private static int bytesToInt(byte[] bytes) {
return ((bytes[0] & 255) << 24) + ((bytes[1] & 255) << 16) + ((bytes[2] & 255) << 8) + (bytes[3] & 255);
}
private static int bytesToInt(byte[] bytes, int offset) {
return ((bytes[offset] & 255) << 24) + ((bytes[1 + offset] & 255) << 16) + ((bytes[2 + offset] & 255) << 8) + (bytes[3 + offset] & 255);
}
public ArrowHttpInputStream(InputStream inputStream, CompressOption compress) throws IOException {
this.in = inputStream;
this.bufSize = 0;
this.readPos = 0;
this.isOpen = true;
this.isLastChunk = false;
this.compress = compress;
if (compress != null && !compress.algorithm.equals(CompressOption.CompressAlgorithm.ODPS_RAW)) {
if (compress.algorithm.equals(CompressOption.CompressAlgorithm.ODPS_ZLIB)) {
this.in = new InflaterInputStream(inputStream);
} else if (compress.algorithm.equals(CompressOption.CompressAlgorithm.ODPS_SNAPPY)) {
this.in = new SnappyFramedInputStream(inputStream);
} else if (compress.algorithm.equals(CompressOption.CompressAlgorithm.ODPS_ARROW_LZ4_FRAME)) {
this.in = new LZ4FrameInputStream(inputStream);
} else {
throw new IOException("invalid compression option.");
}
}
}
private boolean readChunk() throws IOException {
if (bufSize > readPos) {
return true;
}
if (buf.length == 0) {
byte[] temp = new byte[4];
if (in.read(temp) != -1) {
crcChunkSize = bytesToInt(temp);
bufCapacity = crcChunkSize + 4;
buf = new byte[bufCapacity];
}
}
bufSize = 0;
int byteRead = -1;
while ((bufSize < bufCapacity) && (byteRead = in.read(buf, bufSize, bufCapacity - bufSize)) != -1) {
bufSize += byteRead;
}
if (bufSize == 0) {
return false;
}
if (bufSize < 4) {
throw new IOException("InputStream Read() for crc32 failed.");
}
int dataSize = bufSize - 4;
int readCheckSum = bytesToInt(buf, dataSize);
int checkSum = 0;
globalCrc.update(buf, 0, dataSize);
if (bufSize < crcChunkSize + 4) {
isLastChunk = true;
checkSum = (int) globalCrc.getValue();
} else {
chunkCrc.reset();
chunkCrc.update(buf, 0, dataSize);
checkSum = (int) chunkCrc.getValue();
}
if (checkSum != readCheckSum) {
throw new IOException("CRC Check failed.");
}
bufSize = dataSize;
readPos = 0;
return true;
}
@Override
public int read(ByteBuffer dst) throws IOException {
if (!isOpen)
throw new IOException("Operation forbidden on closed BufferReader");
int len = dst.remaining();
int totalRead;
int readBytes;
for(totalRead = 0; totalRead < len && this.readChunk(); totalRead += readBytes) {
readBytes = Math.min(this.bufSize - this.readPos, len - totalRead);
dst.put(this.buf, this.readPos, readBytes);
this.readPos += readBytes;
}
return totalRead;
}
@Override
public boolean isOpen() {
return this.isOpen;
}
@Override
public void close() throws IOException {
if (isOpen) {
this.isOpen = false;
this.in.close();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy