/*
 * SDK Pullenti Unitext, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software. 
 * This class is generated using the converter Unisharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

package com.pullenti.util;

// Поддержка работы с таблицами DBF
public class DbfTable implements AutoCloseable {

    public DbfTable(String fileName) throws Exception, java.io.FileNotFoundException, java.io.IOException {
        m_Stream = new com.pullenti.unisharp.FileStream(fileName, "r", "");
        byte[] buf = new byte[1024];
        if (m_Stream.read(buf, 0, 0x20) != 0x20 || buf[0] != ((byte)3)) 
            throw new Exception("Bad DBF format");
        int headLen = ((Byte.toUnsignedInt(buf[9])) << 8) | (Byte.toUnsignedInt(buf[8]));
        int recLen = ((Byte.toUnsignedInt(buf[11])) << 8) | (Byte.toUnsignedInt(buf[10]));
        for (; (m_Stream.getPosition() + (0x20L)) <= headLen; ) {
            if (m_Stream.read(buf, 0, 0x20) != 0x20) 
                throw new Exception("Bad DBF format");
            int i = 0;
            for (; i < 11; i++) {
                if (buf[i] == ((byte)0)) 
                    break;
            }
            String nam = MiscHelper.decodeStringAscii(buf, 0, i).trim();
            columnnNames.add(nam);
            columnLengths.add((int)(Byte.toUnsignedInt(buf[0x10])));
            values.add(null);
        }
        m_Stream.setPosition((long)(headLen - 1));
        int b = m_Stream.read();
        if (b != 13) 
            throw new Exception("Bad DBF format (end of head not 13)");
        java.util.ArrayList<String> vals = new java.util.ArrayList<String>();
        int le = 0;
        for (int v : columnLengths) {
            le += v;
            vals.add(null);
        }
        if ((le + 1) != recLen) 
            throw new Exception(("Total columns length " + (le + 1) + " != length of record " + recLen));
        m_Enc = new EncodingWrapper(EncodingStandard.CP1251, null, 0);
        bufRec = new byte[recLen];
        m_FirstRecPos = m_Stream.getPosition();
        rowsCount = (int)((((m_Stream.length() - m_FirstRecPos)) / ((long)recLen)));
    }

    public int rowsCount;

    @Override
    public void close() {
        try {
            if (m_Stream != null) 
                m_Stream.close();
            m_Stream = null;
        } catch (Exception ex123) {
        }
    }

    private com.pullenti.unisharp.FileStream m_Stream;

    private long m_FirstRecPos;

    public java.util.ArrayList<String> columnnNames = new java.util.ArrayList<String>();

    public java.util.ArrayList<Integer> columnLengths = new java.util.ArrayList<Integer>();

    private byte[] bufRec;

    private EncodingWrapper m_Enc;

    public java.util.ArrayList<String> values = new java.util.ArrayList<String>();

    public int percent = 0;

    public String getString(String columnName) {
        int i = columnnNames.indexOf(columnName);
        if (i < 0) 
            return null;
        if (com.pullenti.unisharp.Utils.isNullOrEmpty(values.get(i))) 
            return null;
        return values.get(i);
    }

    public java.util.UUID getGuid(String columnName) {
        String val = this.getString(columnName);
        if (com.pullenti.unisharp.Utils.isNullOrEmpty(val)) 
            return null;
        try {
            return java.util.UUID.fromString(val);
        } catch (Exception ex) {
            return null;
        }
    }

    public boolean readNext(int onlyColumnIndex) throws java.io.IOException {
        if (m_Stream == null) 
            return false;
        if (m_Stream.read(bufRec, 0, bufRec.length) != bufRec.length) 
            return false;
        if (bufRec[0] != ((byte)0x20)) 
            return false;
        int d = 1;
        int i;
        for (i = 0; i < bufRec.length; i++) {
            int j = Byte.toUnsignedInt(bufRec[i]);
            if (j >= 0xE0 && j <= 0xEF) 
                j -= 0x30;
            if (j >= 0x80 && j <= 0xDF) 
                bufRec[i] = (byte)((j + 0x40));
            if (j == 0xF1) 
                bufRec[i] = (byte)0xB8;
            if (j == 0xF0) 
                bufRec[i] = (byte)0xA8;
        }
        for (i = 0; i < columnnNames.size(); i++) {
            if ((onlyColumnIndex < 0) || onlyColumnIndex == i) {
                String val = m_Enc.getString(bufRec, d, columnLengths.get(i)).trim();
                com.pullenti.unisharp.Utils.putArrayValue(values, i, val);
            }
            d += columnLengths.get(i);
        }
        if (m_Stream.length() < (100000L)) 
            percent = (int)(((m_Stream.getPosition() * (100L)) / m_Stream.length()));
        else 
            percent = (int)((m_Stream.getPosition() / ((m_Stream.length() / (100L)))));
        return true;
    }

    public void reread() throws java.io.IOException {
        if (m_Stream != null) 
            m_Stream.setPosition(m_FirstRecPos);
    }
    public DbfTable() {
    }
}
