package me.xcoding.opencdc.mysql.protocol.column;
import java.util.Arrays;
/**
* A serial Column.
* @author Teny Zh(zh.Teny.1@gmail.com)
*
*/
public class ColumnList {
private static final int[] bitmask = new int[] {
1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7
};
private int curColumn = -1;
private final Column[] columns; // before
private final int numberOfColumns;
// 不能为空,或可以为空。
// private final byte[] nullBitmask;
private final byte[] columnTypeDef;
private final byte[] columnMetaDef;
private boolean[] _null;
private final boolean nullable[];
private static final int FF = 0x000000FF;
private final ColumnDef columnDef = new ColumnDef(0, 0);
public ColumnList(byte[] columnTypeDef, byte[] columnMetaDef, byte[] nullBitmask) {
// this.nullBitmask = nullBitmask;
this.columnTypeDef = columnTypeDef;
this.columnMetaDef = columnMetaDef;
this.numberOfColumns = columnTypeDef.length;
this.columns = new Column[numberOfColumns];
this.nullable = new boolean[numberOfColumns];
// int c = 0; // FIXME : 是不是可以直接取到字段的Nullable呢?
// for(byte b : nullBitmask) {
// for(int pos=0; pos<8; pos++, c++) {
// nullable[c] = ((b & bitmask[pos]) == bitmask[pos]);
// }
// }
}
// FIXME 如此之挫,求改。
public ColumnList init(byte[] columnsPresent, byte[] nullBitmap) {
_null = new boolean[columnsPresent.length << 3];
int c = 0;
for(byte b : nullBitmap) {
for(int pos=0; pos<8; pos++, c++) {
_null[c] = ((b & bitmask[pos]) == bitmask[pos]);
}
}
return this;
}
public boolean isNullable() {
return nullable[curColumn];
}
public boolean isNull() {
// check border?
return _null[curColumn];
}
public boolean isNull(int cIndex) {
// check border?
return _null[cIndex];
}
public boolean hasNext() {
return ++curColumn < numberOfColumns;
}
public ColumnDef next() {
return columnDef.valueOf(
(columnTypeDef[curColumn] & 0x1F),
parser()
);
}
public void add(Column column) {
columns[curColumn] = column;
}
public void add(int type, Object value) {
add(new Column(type, value));
}
public Column[] toArray() {
return columns;
}
private int offset = 0;
private int parser() {
int v = MetaDataParser.lengthOf[columnTypeDef[curColumn] & 0x1F];
if(v == 0) {
return 0;
}
return v==1?(columnMetaDef[offset++] & FF) :
((columnMetaDef[offset++] & FF) | ((columnMetaDef[offset++] & FF) << 8));
}
@Override
public String toString() {
return Arrays.toString(columns);
}
}