blob: dffb6ff817097b80a44960c6c3f6d338bb81db84 [file] [log] [blame]
package org.mariadb.jdbc.client.result.rowdecoder;
import static org.mariadb.jdbc.client.result.Result.NULL_LENGTH;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import org.mariadb.jdbc.Configuration;
import org.mariadb.jdbc.client.ColumnDecoder;
import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
import org.mariadb.jdbc.client.util.MutableInt;
import org.mariadb.jdbc.plugin.Codec;
/** BINARY rows decoder */
public class BinaryRowDecoder implements RowDecoder {
/**
* Binary decode data according to data type.
*
* @param codec current codec
* @param cal calendar
* @param rowBuf row buffer
* @param fieldLength field length
* @param metadataList metadatas
* @param fieldIndex field index
* @return default object according to metadata
* @param <T> Codec default return type
* @throws SQLException if any decoding error occurs
*/
public <T> T decode(
Codec<T> codec,
Calendar cal,
StandardReadableByteBuf rowBuf,
int fieldLength,
ColumnDecoder[] metadataList,
final MutableInt fieldIndex)
throws SQLException {
return codec.decodeBinary(rowBuf, fieldLength, metadataList[fieldIndex.get()], cal);
}
@Override
public Object defaultDecode(
Configuration conf,
ColumnDecoder[] metadataList,
final MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength)
throws SQLException {
return metadataList[fieldIndex.get()].getDefaultBinary(conf, rowBuf, fieldLength);
}
public String decodeString(
ColumnDecoder[] metadataList,
final MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength)
throws SQLException {
return metadataList[fieldIndex.get()].decodeStringBinary(rowBuf, fieldLength, null);
}
public byte decodeByte(
ColumnDecoder[] metadataList,
final MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength)
throws SQLException {
return metadataList[fieldIndex.get()].decodeByteBinary(rowBuf, fieldLength);
}
public boolean decodeBoolean(
ColumnDecoder[] metadataList,
final MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength)
throws SQLException {
return metadataList[fieldIndex.get()].decodeBooleanBinary(rowBuf, fieldLength);
}
public Date decodeDate(
ColumnDecoder[] metadataList,
MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength,
Calendar cal)
throws SQLException {
return metadataList[fieldIndex.get()].decodeDateBinary(rowBuf, fieldLength, cal);
}
public Time decodeTime(
ColumnDecoder[] metadataList,
MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength,
Calendar cal)
throws SQLException {
return metadataList[fieldIndex.get()].decodeTimeBinary(rowBuf, fieldLength, cal);
}
public Timestamp decodeTimestamp(
ColumnDecoder[] metadataList,
MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength,
Calendar cal)
throws SQLException {
return metadataList[fieldIndex.get()].decodeTimestampBinary(rowBuf, fieldLength, cal);
}
public short decodeShort(
ColumnDecoder[] metadataList,
final MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength)
throws SQLException {
return metadataList[fieldIndex.get()].decodeShortBinary(rowBuf, fieldLength);
}
public int decodeInt(
ColumnDecoder[] metadataList,
final MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength)
throws SQLException {
return metadataList[fieldIndex.get()].decodeIntBinary(rowBuf, fieldLength);
}
public long decodeLong(
ColumnDecoder[] metadataList,
final MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength)
throws SQLException {
return metadataList[fieldIndex.get()].decodeLongBinary(rowBuf, fieldLength);
}
public float decodeFloat(
ColumnDecoder[] metadataList,
final MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength)
throws SQLException {
return metadataList[fieldIndex.get()].decodeFloatBinary(rowBuf, fieldLength);
}
public double decodeDouble(
ColumnDecoder[] metadataList,
final MutableInt fieldIndex,
StandardReadableByteBuf rowBuf,
int fieldLength)
throws SQLException {
return metadataList[fieldIndex.get()].decodeDoubleBinary(rowBuf, fieldLength);
}
public boolean wasNull(byte[] nullBitmap, final MutableInt fieldIndex, int fieldLength) {
return (nullBitmap[(fieldIndex.get() + 2) / 8] & (1 << ((fieldIndex.get() + 2) % 8))) > 0;
}
/**
* Set length and pos indicator to asked index.
*
* @param newIndex index (0 is first).
*/
@Override
public int setPosition(
int newIndex,
final MutableInt fieldIndex,
int maxIndex,
StandardReadableByteBuf rowBuf,
byte[] nullBitmap,
ColumnDecoder[] metadataList) {
if (fieldIndex.get() >= newIndex) {
fieldIndex.set(0);
rowBuf.pos(1);
rowBuf.readBytes(nullBitmap);
} else {
fieldIndex.incrementAndGet();
if (fieldIndex.get() == 0) {
// skip header + null-bitmap
rowBuf.pos(1);
rowBuf.readBytes(nullBitmap);
}
}
while (fieldIndex.get() < newIndex) {
if ((nullBitmap[(fieldIndex.get() + 2) / 8] & (1 << ((fieldIndex.get() + 2) % 8))) == 0) {
// skip bytes
switch (metadataList[fieldIndex.get()].getType()) {
case BIGINT:
case DOUBLE:
rowBuf.skip(8);
break;
case INTEGER:
case MEDIUMINT:
case FLOAT:
rowBuf.skip(4);
break;
case SMALLINT:
case YEAR:
rowBuf.skip(2);
break;
case TINYINT:
rowBuf.skip(1);
break;
default:
rowBuf.skipLengthEncoded();
break;
}
}
fieldIndex.incrementAndGet();
}
if (wasNull(nullBitmap, fieldIndex, 0)) {
return NULL_LENGTH;
}
// read asked field position and length
switch (metadataList[fieldIndex.get()].getType()) {
case BIGINT:
case DOUBLE:
return 8;
case INTEGER:
case MEDIUMINT:
case FLOAT:
return 4;
case SMALLINT:
case YEAR:
return 2;
case TINYINT:
return 1;
default:
// field with variable length
byte len = rowBuf.readByte();
switch (len) {
case (byte) 252:
// length is encoded on 3 bytes (0xfc header + 2 bytes indicating length)
return rowBuf.readUnsignedShort();
case (byte) 253:
// length is encoded on 4 bytes (0xfd header + 3 bytes indicating length)
return rowBuf.readUnsignedMedium();
case (byte) 254:
// length is encoded on 9 bytes (0xfe header + 8 bytes indicating length)
return (int) rowBuf.readLong();
default:
return len & 0xff;
}
}
}
}