package com.wistron.StreamHelper;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.util.Log;
/**
* 数据类型处理帮助类
* @author WH1107028 Cocoonshu
* @date 2012-02-01 11:42:22
* @commit 使用RandomAccessFile作为文件流读取类
*/
public class BaselineUtls {
/**
* 无序Byte数组转Long型
* @param src 无序Byte数组,长度0~4
* @param endian 字节序
* @return
*/
static public long Byte2Long(byte[] src, int endian){
long res = 0;
long ones = 0xff;
switch (endian) {
case MPOHexTAG.LITTLE_ENDIAN:
for(int i = 0; i < src.length; i++){
res = res | (((long)src[i]) << 8*i);
}
break;
case MPOHexTAG.BIG_ENDIAN:
for(int i = 0; i < src.length; i++){
res = res | (((long)src[src.length - i - 1]) << (8*i));
}
break;
default:
res = res & ones;
break;
}
return res;
}
/**
* 无序Byte数组转Int型
* @param src 无序Byte数组,长度0~2
* @param endian 字节序
* @return
*/
static public int Byte2Int(byte[] src, int endian){
int res = 0x00;
int ones = 0xff;
switch (endian) {
case MPOHexTAG.LITTLE_ENDIAN:
for(int i = 0; i < src.length; i++){
res = res | (((int)src[i]) << 8*i);
}
break;
case MPOHexTAG.BIG_ENDIAN:
for(int i = 0; i < src.length; i++){
res = res | (((int)src[src.length - i - 1]) << (8*i));
}
break;
default:
res = res & ones;
break;
}
return res;
}
/**
* 无序Byte数组转UInt型
* @param src 无序Byte数组,长度0~2
* @param endian 字节序
* @return
*/
static public int Byte2UInt(byte[] src, int endian){
int tmp = 0x00;
int res = 0x00;
int ones = 0xff;
switch (endian) {
case MPOHexTAG.LITTLE_ENDIAN:
for(int i = 0; i < src.length; i++){
tmp = (int)src[i];
if(tmp < 0){
tmp &= ones;
}
res = res | (tmp << 8*i);
}
break;
case MPOHexTAG.BIG_ENDIAN:
for(int i = 0; i < src.length; i++){
tmp = (int)src[src.length - i - 1];
if(tmp < 0){
tmp &= ones;
}
res = res | (tmp << (8*i));
}
break;
default:
res = res & ones;
break;
}
if(res < 0){
res &= ones;
}
return res;
}
/**
* 无序Byte数组转Long型
* @param src 无序Byte数组,长度0~4
* @param endian 字节序
* @return
*/
static public long Byte2ULong(byte[] src, int endian){
long tmp = 0;
long res = 0;
long ones = 0xff;
switch (endian) {
case MPOHexTAG.LITTLE_ENDIAN:
for(int i = 0; i < src.length; i++){
tmp = src[i];
if(tmp < 0){
tmp &= ones;
}
res = res | (tmp << 8*i);
}
break;
case MPOHexTAG.BIG_ENDIAN:
for(int i = 0; i < src.length; i++){
tmp = src[src.length - i - 1];
if(tmp < 0){
tmp &= ones;
}
res = res | (tmp << (8*i));
}
break;
default:
res = res & ones;
break;
}
if(res < 0){
res &= ones;
}
return res;
}
/**
* Byte数组转换为String型
* @param buffer
* @return
*/
static public String Byte2String(byte[] buffer){
String res = null;
res = new String(buffer);
return res;
}
/**
* 整型转Big Endian Byte数组
* @param value 要转换的值
* @param length 整型数组长度
* @return
*/
static public byte[] Int2Byte(int value, int length){
if(length < 0 || length > Integer.MAX_VALUE){
length = 0;
}
byte[] res = new byte[length];
for(int i = 0; i < length; i++){
res[length - i - 1] = (byte)((value >> (8 * i)) & 0xFF);
}
return res;
}
/**
* 实数字符串转double型,因为这里的double是无符号的,故返回值小于0表示出错
* @param rational
* @return
*/
static public double Rational2UDouble(String rational){
String[] tmp = null;
double res = -1;
if(rational == null){
return -1;
}
tmp = rational.split("/");
if(tmp.length == 2){
res = Double.parseDouble(tmp[0])/Double.parseDouble(tmp[1]);
}else if(tmp.length == 1){
res = Double.parseDouble(tmp[0]);
}else{
res = -1;
}
return res;
}
/**
* 在Byte数组中查找arg0 arg1组合值,如0xFF 0xD8
* @param src
* @param arg0
* @param arg1
* @return 返回第index个组合值在Byte数组中的位置,若返回-1,则没有找到
*/
static public List<Integer> getMarkerOffset(byte[] src, int arg0, int arg1){
List<Integer> pos = new ArrayList<Integer>();
for(int j = 0; j < src.length - 1; j++){
if(src[j] == arg0 && src[j+1] == arg1){
pos.add(j);
}
}
return pos;
}
/**
* 在文件流中查找标志位
* @param fin
* @param arg0
* @param arg1
* @return
*/
static public List<Integer> getMarkerOffset(RandomAccessFile fin, byte arg0, byte arg1){
List<Integer> pos = new ArrayList<Integer>();
try{
if(fin == null){
return null;
}
byte[] buffer = new byte[1024];
int loopCount = (int) (fin.length()/1024f);
int loopMod = (int) (fin.length()%1024f);
for(int i = 0; i < loopCount; i++){
//1024倍数文件块
fin.read(buffer, 0, 1024);
for(int j = 0; j < buffer.length - 1; j++){
if(buffer[j] == arg0 && buffer[j+1] == arg1){
pos.add(i*buffer.length + j);
}
}
}
if(loopMod > 0){
//1024余数文件块
fin.read(buffer, 0, loopMod);
for(int j = 0; j < 1024 - 1; j++){
if(buffer[j] == arg0 && buffer[j+1] == arg1){
pos.add(loopCount*buffer.length + j);
}
}
}
fin.seek(0);
}catch(IOException exp){
exp.printStackTrace();
}
return pos;
}
/**
* 在文件流中查找标志位
* @param fin
* @param arg0
* @param arg1
* @param start
* @param end
* @return
*/
static public List<Integer> getMarkerOffset(RandomAccessFile fin, byte arg0, byte arg1, int start, int end){
List<Integer> pos = new ArrayList<Integer>(),
ans = new ArrayList<Integer>();
int size = 0,
curr = 0;
pos = getMarkerOffset(fin, arg0, arg1);
size = pos.size();
for(int i = 0; i < size; i++){
curr = pos.get(i);
if(curr >= start && curr <= end){
ans.add(curr);
}
}
return ans;
}
/**
* 在线性表中查询
* @param KeyValue
* @param list
* @return -1为未找到
*/
public static int BinarySearch(int KeyValue, int[] list)
{
int counter = 1; // 计数器
int Max = list.length;
int left = 0, // 左边界变量
right = 0, // 右边界变量
middle = 0; // 中位数变量
left = 0;
right = Max - 1;
while (left <= right)
{
middle = (left + right) / 2;
if (KeyValue < list[middle]) // 欲查找值较小
right = middle - 1; // 查找前半段
// 欲查找值较大
else if (KeyValue > list[middle])
left = middle + 1; // 查找后半段
// 查找到数据
else if (KeyValue == list[middle])
{
return list[middle];
}
counter++;
}
return -1;
}
/**
* 把原始比特流写入文件
* @param filePath
* @param data
*/
public static void writeByteToFile(String filePath, byte[] data){
File picture = new File(filePath);
// 如果父目录不存在,就创建目录
if (!picture.getParentFile().exists()) {
picture.getParentFile().mkdirs();
picture = new File(filePath);
}
// 获得文件输出流
FileOutputStream fos = null;
try {
fos = new FileOutputStream(picture);
if(data != null){
fos.write(data);
}
// 关闭文件流
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 把Bitmap写入图片文件
* @param filePath
* @param bmp
* @param compressFormat
* @param quality
*/
public static void writeBitemapToFile(String filePath, Bitmap bmp, CompressFormat compressFormat, int quality){
File picture = new File(filePath);
// 如果父目录不存在,就创建目录
if (!picture.getParentFile().exists()) {
picture.getParentFile().mkdirs();
picture = new File(filePath);
}
// 获得文件输出流
FileOutputStream fos = null;
try {
fos = new FileOutputStream(picture);
if(bmp != null){
bmp.compress(compressFormat, quality, fos);
}
// 关闭文件流
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取标签名称,byte数组以BIG_ENDIAN传入
* @param b
* @param c
* @return
*/
public static int getTag(byte b, byte c) {
return Byte2UInt(new byte[]{b, c}, MPOHexTAG.BIG_ENDIAN);
}
/**
* 获取标签的数据类型,byte数组以BIG_ENDIAN传入
* @param b
* @param c
* @return
*/
public static int getType(byte b, byte c) {
return Byte2Int(new byte[]{b, c}, MPOHexTAG.BIG_ENDIAN);
}
/**
* 获取标签的数据个数,byte数组以BIG_ENDIAN传入
* @param b
* @param c
* @param d
* @param e
* @return
*/
public static int getCount(byte b, byte c, byte d, byte e) {
return Byte2Int(new byte[]{b, c, d, e}, MPOHexTAG.BIG_ENDIAN);
}
/**
* 获取标签的数据偏移量,byte数组以BIG_ENDIAN传入
* @param b
* @param c
* @param d
* @param e
* @return
*/
public static int getOffset(byte b, byte c, byte d, byte e) {
return Byte2UInt(new byte[]{b, c, d, e}, MPOHexTAG.BIG_ENDIAN);
}
/**
* 获取标签的值,byte数组以BIG_ENDIAN传入
* @param bs
* @param mType
* @return
*/
public static Object getValue(byte[] bs, int type) {
Object res = null;
switch (type) {
case MPOHexTAG.TAG_BYTE:
res = bs[bs.length - 1];
if(bs[bs.length - 1] < 0){
res = bs[bs.length - 1] & 0xff;
}
break;
case MPOHexTAG.TAG_ASCII:
res = new String(bs).trim();
break;
case MPOHexTAG.TAG_SHORT:
res = Byte2UInt(new byte[]{bs[2], bs[3]}, MPOHexTAG.BIG_ENDIAN);
break;
case MPOHexTAG.TAG_LONG:
res = Byte2ULong(new byte[]{bs[0], bs[1], bs[2], bs[3]}, MPOHexTAG.BIG_ENDIAN);
break;
case MPOHexTAG.TAG_RATIONAL://会以"12/13"的String返回
res = "" + Byte2ULong(new byte[]{bs[0], bs[1], bs[2], bs[3]}, MPOHexTAG.BIG_ENDIAN);
res = (String)res + "/";
res = (String)res + Byte2ULong(new byte[]{bs[4], bs[5], bs[6], bs[7]}, MPOHexTAG.BIG_ENDIAN);
break;
case MPOHexTAG.TAG_SBYTE:
res = bs[bs.length - 1];
break;
case MPOHexTAG.TAG_UNDEFINED:
res = bs;
break;
case MPOHexTAG.TAG_SSHORT:
res = Byte2Int(new byte[]{bs[2], bs[3]}, MPOHexTAG.BIG_ENDIAN);
break;
case MPOHexTAG.TAG_SLONG:
res = Byte2Long(new byte[]{bs[0], bs[1], bs[2], bs[3]}, MPOHexTAG.BIG_ENDIAN);
break;
case MPOHexTAG.TAG_SRATIONAL:
res = "" + Byte2Long(new byte[]{bs[0], bs[1], bs[2], bs[3]}, MPOHexTAG.BIG_ENDIAN);
res = (String)res + "/";
res = (String)res + Byte2Long(new byte[]{bs[4], bs[5], bs[6], bs[7]}, MPOHexTAG.BIG_ENDIAN);
break;
case MPOHexTAG.TAG_FLOAT:
case MPOHexTAG.TAG_DOUBLE:
res = Byte2Long(bs, MPOHexTAG.BIG_ENDIAN);
break;
}
return res;
}
/**
* 获取标签的值,byte数组以BIG_ENDIAN传入
* @param bs
* @param mType
* @return
*/
public static Object getValue(byte[] bs, int type, int codeOrder) {
Object res = null;
switch (type) {
case MPOHexTAG.TAG_BYTE:
res = bs[bs.length - 1];
if(bs[bs.length - 1] < 0){
res = bs[bs.length - 1] & 0xff;
}
break;
case MPOHexTAG.TAG_ASCII:
res = new String(bs).trim();
break;
case MPOHexTAG.TAG_SHORT:
res = Byte2UInt(new byte[]{bs[0], bs[1]}, codeOrder);
break;
case MPOHexTAG.TAG_LONG:
res = Byte2ULong(new byte[]{bs[0], bs[1], bs[2], bs[3]}, codeOrder);
break;
case MPOHexTAG.TAG_RATIONAL://会以"12/13"的String返回
res = "" + Byte2ULong(new byte[]{bs[0], bs[1], bs[2], bs[3]}, codeOrder);
res = (String)res + "/";
res = (String)res + Byte2ULong(new byte[]{bs[4], bs[5], bs[6], bs[7]}, codeOrder);
break;
case MPOHexTAG.TAG_SBYTE:
res = bs[bs.length - 1];
break;
case MPOHexTAG.TAG_UNDEFINED:
res = bs;
break;
case MPOHexTAG.TAG_SSHORT:
res = Byte2Int(new byte[]{bs[0], bs[1]}, codeOrder);
break;
case MPOHexTAG.TAG_SLONG:
res = Byte2Long(new byte[]{bs[0], bs[1], bs[2], bs[3]}, codeOrder);
break;
case MPOHexTAG.TAG_SRATIONAL:
res = "" + Byte2Long(new byte[]{bs[0], bs[1], bs[2], bs[3]}, codeOrder);
res = (String)res + "/";
res = (String)res + Byte2Long(new byte[]{bs[4], bs[5], bs[6], bs[7]}, codeOrder);
break;
case MPOHexTAG.TAG_FLOAT:
case MPOHexTAG.TAG_DOUBLE:
res = Byte2Long(bs, MPOHexTAG.BIG_ENDIAN);
break;
}
return res;
}
/**
* 获取数据类型的大小,單位Byte
* @param mType
* @return
*/
public static int sizeof(int mType) {
switch (mType) {
case MPOHexTAG.TAG_BYTE:
return 1;
case MPOHexTAG.TAG_ASCII:
return 1;
case MPOHexTAG.TAG_SHORT:
return 2;
case MPOHexTAG.TAG_LONG:
return 4;
case MPOHexTAG.TAG_RATIONAL:
return 8;
case MPOHexTAG.TAG_SBYTE:
return 2;
case MPOHexTAG.TAG_UNDEFINED:
return 1;
case MPOHexTAG.TAG_SSHORT:
return 4;
case MPOHexTAG.TAG_SLONG:
return 4;
case MPOHexTAG.TAG_SRATIONAL:
return 8;
case MPOHexTAG.TAG_FLOAT:
return 4;
case MPOHexTAG.TAG_DOUBLE:
return 8;
}
return 0;
}
/**
* 把字节大小转换成方便阅读的UI大小字符串
* 如10256348 B将被转换成9.781215667724609375 MB
* @param byteLength 字节大小
* @param decimal 保留小数位数
* @return
*/
public static String getUISizeString(double byteLength, int decimal){
String res = "";
String unit = "";
String[] decPart = null;
int pointPos = -1;
//换算
if(byteLength/1024f >= 1f){
if(byteLength/1024f/1024f >= 1f){
if(byteLength/1024f/1024f/1024f >= 1f){
//超过1G
res = "" + byteLength/1024f/1024f/1024f;
unit = " GB";
}else{
//不足1G
res = "" + byteLength/1024f/1024f;
unit = " MB";
}
}else{
//不足1M
res = "" + byteLength/1024f;
unit = " KB";
}
}else{
//不足1K
res = "" + byteLength;
unit = " B";
}
//保留小数点
pointPos = res.indexOf(".");
if(pointPos >= 0){
res = res.substring(0, pointPos + decimal + 1);
//小数为全0,则去掉小数部分
decPart = res.split(".");
if(decPart.length > 1 && Double.valueOf(decPart[decPart.length - 1]) == 0 ){
res = decPart[decPart.length - 2];
}
}
return res + unit;
}
}