/*
* myLib - https://github.com/taktod/myLib
* Copyright (c) 2014 ttProject. All rights reserved.
*
* Licensed under The MIT license.
*/
package com.ttProject.util;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.List;
import com.ttProject.nio.channels.IReadChannel;
/**
* util for byteBuffer
* @author taktod
*/
public class BufferUtil {
public static ByteBuffer safeRead(ReadableByteChannel ch, int length) throws Exception {
return safeRead(ch, length, -1);
}
public static ByteBuffer safeRead(ReadableByteChannel ch, int length, int timeout) throws Exception {
return safeRead(ch, length, timeout, -1);
}
public static ByteBuffer safeRead(ReadableByteChannel ch, int length, int timeout, int tryCount) throws Exception {
ByteBuffer buffer = ByteBuffer.allocate(length);
int count = 0;
while(true) {
ch.read(buffer);
if(buffer.limit() == length) {
buffer.flip();
return buffer;
}
if(tryCount != -1 && tryCount < count) {
throw new Exception("exceed the count of retry.");
}
if(timeout != -1 && timeout < count * 10) {
throw new InterruptedException("buffer read time out.");
}
Thread.sleep(10);
count ++;
}
}
public static ByteBuffer safeRead(IReadChannel ch, int length) throws Exception {
return safeRead(ch, length, -1);
}
public static ByteBuffer safeRead(IReadChannel ch, int length, int timeout) throws Exception {
return safeRead(ch, length, timeout, -1);
}
public static ByteBuffer safeRead(IReadChannel ch, int length, int timeout, int tryCount) throws Exception {
if(ch.size() - ch.position() < length) {
throw new Exception("try to read larger data.");
}
ByteBuffer buffer = ByteBuffer.allocate(length);
int count = 0;
while(true) {
ch.read(buffer);
if(buffer.position() == length) {
buffer.flip();
return buffer;
}
if(tryCount != -1 && tryCount < count) {
throw new Exception("exceed the count of retry.");
}
if(timeout != -1 && timeout < count * 10) {
throw new InterruptedException("buffer read time out.");
}
Thread.sleep(10);
count ++;
}
}
/**
* copy from source to target with the size.
* @param source
* @param target
* @param size
* @throws Exception
*/
public static void quickCopy(IReadChannel source, WritableByteChannel target, int size) throws Exception {
ByteBuffer buffer = null;
int targetSize = size;
while(targetSize > 0) {
int bufSize = (16777216 > targetSize) ? targetSize : 16777216;
buffer = ByteBuffer.allocate(bufSize);
source.read(buffer);
buffer.flip();
if(buffer.remaining() == 0) {
// TODO this could be exception, because the reading is on the middle.
break;
}
Thread.sleep(10);
targetSize -= buffer.remaining();
target.write(buffer);
}
}
/**
* dispose the size of bytes
* @param source
* @param size
* @throws Exception
*/
public static void quickDispose(IReadChannel source, int size) throws Exception {
ByteBuffer buffer = null;
int targetSize = size;
while(targetSize > 0) {
int bufSize = (16777216 > targetSize) ? targetSize : 16777216;
buffer = ByteBuffer.allocate(bufSize);
source.read(buffer);
buffer.flip();
if(buffer.remaining() == 0) {
// TODO this could be exception, because the reading is on the middle.
break;
}
Thread.sleep(10);
targetSize -= buffer.remaining();
}
}
/**
* get tag string from 4bytes buffer.(with lower case)
* for mp4 reading
* @param buffer
* @return
*/
public static String getDwordText(ByteBuffer buffer) {
byte[] data = new byte[4];
buffer.get(data);
return new String(data).toLowerCase();
}
/**
* get tag string from 4bytes buffer.
* for mp4 reading
* @param buffer
* @return
*/
public static String getDwordTextNormal(ByteBuffer buffer) {
byte[] data = new byte[4];
buffer.get(data);
return new String(data);
}
/**
* write int
* @param target
* @param data
* @throws IOException
*/
public static void writeInt(WritableByteChannel target, int data) throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.putInt(data);
buffer.flip();
target.write(buffer);
}
/**
* check if the buffer is same.
* (maybe hashCode compalision is enough, this func is no needed)
* @param src
* @param dst
* @return true:same false:different
*/
public static boolean isSame(ByteBuffer src, ByteBuffer dst) {
if(src.remaining() != dst.remaining()) {
return false;
}
while(src.remaining() > 0 && src.get() == dst.get()) {
;
}
return src.remaining() == 0;
}
/**
* make byte array from byteBuffer.
* @param src
* @return
*/
public static byte[] toByteArray(ByteBuffer src) {
int size = src.remaining();
byte[] data = new byte[size];
src.get(data);
return data;
}
/**
* connect byteBuffers.
* @param buffers
* @return
*/
public static ByteBuffer connect(ByteBuffer ... buffers) {
int length = 0;
for(ByteBuffer buf : buffers) {
if(buf != null) {
length += buf.remaining();
}
}
ByteBuffer result = ByteBuffer.allocate(length);
for(ByteBuffer buf : buffers) {
if(buf != null) {
result.put(buf);
}
}
result.flip();
return result;
}
/**
* connect byteBuffers.
* @param buffers
* @return
*/
public static ByteBuffer connect(List<ByteBuffer> buffers) {
int length = 0;
for(ByteBuffer buf : buffers) {
if(buf != null) {
length += buf.remaining();
}
}
ByteBuffer result = ByteBuffer.allocate(length);
for(ByteBuffer buf : buffers) {
if(buf != null) {
result.put(buf);
}
}
result.flip();
return result;
}
}