Первый

This commit is contained in:
2024-11-18 22:17:38 +05:00
commit 6cd3bb5e65
12 changed files with 4118 additions and 0 deletions

200
tctable/TCTable.java Normal file
View 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);
}
}