201 lines
5.2 KiB
Java
201 lines
5.2 KiB
Java
package tctable;
|
|
|
|
import java.io.DataInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
|
|
public class TCTable
|
|
{
|
|
public int id=0; //Идентификатор таблицы
|
|
public String name=""; //Название таблицы
|
|
public List<TCField> fields=new ArrayList<TCField>(); //Список полей
|
|
|
|
private int nc=0; //Байтов под NULL значения
|
|
private byte[] m_NULL=null; //NULL значения
|
|
private InputStream m_file;
|
|
|
|
/**
|
|
* Конструктор
|
|
* @param Строка name Название таблицы
|
|
* @param Целое id Идентификатор таблицы (обычно уникальный)
|
|
*/
|
|
public TCTable(String name, int id)
|
|
{ this.name=name;
|
|
this.id=id;
|
|
}
|
|
|
|
//Открыть таблицу по названию файла
|
|
/*function OpenTableF(file)
|
|
{
|
|
if(file_exists(file))
|
|
{
|
|
this.OpenTableH(fopen(file,'r'));
|
|
}
|
|
}*/
|
|
|
|
//Открыть таблицу из потока HANDLE
|
|
public boolean OpenTableH(InputStream handle) throws IOException
|
|
{
|
|
this.m_file=handle;
|
|
DataInputStream dis = new DataInputStream(handle);
|
|
|
|
if(Tools.readUShort(dis)!=65500) return false; //id файла
|
|
if(Tools.readUShort(dis)!=1) return false; //Версия файла
|
|
this.id= Tools.readInt(dis); //ID таблицы или запроса (4 байта можно сделать 2)
|
|
if(dis.readByte()!=0) return false; //Только плотные таблицы
|
|
//Считываем название таблицы
|
|
this.name = Tools.readUTF8_1(dis);
|
|
|
|
//Считываем столбцы
|
|
int count=dis.readUnsignedByte(); //Количество столбцов
|
|
for(int i=0;i<count;i++)
|
|
{
|
|
TCField field=new TCField(Tools.readUTF8_1(dis), dis.readUnsignedByte());
|
|
this.addField(field);
|
|
}
|
|
return true;
|
|
}
|
|
//Открыть таблицу из потока
|
|
//OpenTable
|
|
|
|
//Прочитать следующую запись из потока
|
|
public boolean ReadNextRecord()
|
|
{
|
|
Boolean result=true;
|
|
try
|
|
{
|
|
DataInputStream dis = new DataInputStream(m_file);
|
|
//if(m_file.available()) return false; //Неработает
|
|
|
|
if(dis.available()==0)
|
|
return false;
|
|
|
|
//Считываем NULL значения
|
|
if(m_NULL==null) m_NULL = new byte[nc];
|
|
for(int i=0;i<nc;i++)
|
|
{
|
|
m_NULL[i]=(byte)dis.readUnsignedByte();
|
|
}
|
|
|
|
clearRows();
|
|
for(int i=0;i<fields.size();i++)
|
|
{
|
|
if(Tools.getBit(m_NULL,i))
|
|
{
|
|
fields.get(i).ReadValue(m_file);
|
|
}
|
|
}
|
|
}catch(Exception e)
|
|
{
|
|
result=false;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//Добавить поле к таблице
|
|
public void addField(TCField field)
|
|
{ if(field!=null)
|
|
{ fields.add(field);
|
|
this.nc=(int) Math.ceil(fields.size()/8.0); //Байтов под NULL
|
|
m_NULL=new byte[nc];
|
|
}
|
|
}
|
|
|
|
//Получить заголовок плотной таблицы в виде двоичной строки
|
|
public boolean getHeader(OutputStream os)
|
|
{
|
|
boolean result=true;
|
|
try {
|
|
//File ID: 2 bytes.
|
|
os.write((65500 & 0x000000ff));
|
|
os.write((65500 & 0x0000ff00) >> 8);
|
|
//File version: 2 bytes.
|
|
os.write((1 & 0x000000ff));
|
|
os.write((1 & 0x0000ff00) >> 8);
|
|
//Table ID (or Request ID): 4 bytes.
|
|
os.write((this.id & 0x000000ff));
|
|
os.write((this.id & 0x0000ff00) >> 8);
|
|
os.write((this.id & 0x00ff0000) >> 16);
|
|
os.write((this.id & 0xff000000) >> 24);
|
|
//Table type: 1 byte (0- "Dense" 1- "Loose")
|
|
os.write(0);
|
|
//UTF8_1 String
|
|
byte[] ba = this.name.getBytes("UTF-8");
|
|
os.write(ba.length);
|
|
os.write(ba);
|
|
//Count of fields: 1 byte.
|
|
os.write(this.fields.size());
|
|
//Write name and type id
|
|
for(int i=0;i<this.fields.size();i++)
|
|
{
|
|
ba = this.fields.get(i).name.getBytes("UTF-8");
|
|
os.write(ba.length);
|
|
os.write(ba);
|
|
os.write(this.fields.get(i).type);
|
|
}
|
|
} catch (IOException e) {
|
|
result=false;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//Получить данные 1 записи в виде строки
|
|
public boolean getCol(OutputStream os)
|
|
{
|
|
boolean result=true;
|
|
//Запишем NULL значения побайтно (1-есть данные 0-нету данных)
|
|
int nc=(int) Math.ceil(fields.size()/8.0); //Байтов под NULL
|
|
byte[] fNULL=new byte[nc];
|
|
for(int i=0;i<nc*8;i++)
|
|
{
|
|
if(i<this.fields.size() && this.fields.get(i).value!=null)
|
|
{
|
|
Tools.setBit(fNULL,i);
|
|
}
|
|
}
|
|
//Write NULL fields
|
|
try {
|
|
os.write(fNULL);
|
|
} catch (IOException e1) {
|
|
result=false;
|
|
}
|
|
//Запишем сами данные в строку
|
|
for(int i=0;i<fields.size();i++)
|
|
{
|
|
try {
|
|
if(fields.get(i).value!=null)
|
|
os.write(fields.get(i).value);
|
|
} catch (IOException e) {
|
|
result=false;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//Row очистить запись
|
|
void clearRows()
|
|
{ for(int i=0;i<fields.size();i++)
|
|
{
|
|
fields.get(i).value=null;
|
|
}
|
|
}
|
|
|
|
//Получить обьект столбца по имени
|
|
public TCField getRowByName(String name)
|
|
{ for(int i=0;i<fields.size();i++)
|
|
{ if(fields.get(i).name.toUpperCase().equals(name.toUpperCase())) return fields.get(i);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
//Получить объект столбца по номеру
|
|
TCField getRowByNum(int num)
|
|
{ return fields.get(num);
|
|
}
|
|
|
|
}
|