Первый
This commit is contained in:
200
tctable/TCTable.java
Normal file
200
tctable/TCTable.java
Normal file
@ -0,0 +1,200 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user