/*
 * 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
 */

const Stream = require("./../../../unisharp/Stream");
const FileStream = require("./../../../unisharp/FileStream");
const MemoryStream = require("./../../../unisharp/MemoryStream");

const MiscHelper = require("./../../../util/MiscHelper");
const MyZipEntry = require("./MyZipEntry");

class MyZipFile {
    
    constructor(fileName, content) {
        this.entries = new Array();
        this.m_Stream = null;
        this.m_Buf = null;
        if (content !== null) 
            this.m_Stream = new MemoryStream(content);
        else 
            this.m_Stream = new FileStream(fileName, "r", false);
        this.m_Buf = new Uint8Array(4);
        while (true) {
            let i = this.m_Stream.read(this.m_Buf, 0, 4);
            if ((i !== 4 || this.m_Buf[0] !== (0x50) || this.m_Buf[1] !== (0x4B)) || this.m_Buf[2] !== (3) || this.m_Buf[3] !== (4)) 
                break;
            let e = new MyZipEntry(this);
            this._readShort();
            let flags = this._readShort();
            if (((flags & 1)) !== 0) 
                e.encrypted = true;
            e.method = this._readShort();
            this._readShort();
            this._readShort();
            let crc = this._readInt();
            e.compressDataSize = this._readInt();
            e.uncompressDataSize = this._readInt();
            let flen = this._readShort();
            let extr = this._readShort();
            let fnam = new Uint8Array(flen);
            this.m_Stream.read(fnam, 0, flen);
            try {
                if (((flags & 0x800)) !== 0) 
                    e.name = MiscHelper.decodeStringUtf8(fnam, 0, -1);
                else {
                    for (i = 0; i < fnam.length; i++) {
                        let j = fnam[i];
                        if (j >= 0xE0 && j <= 0xEF) 
                            j -= 0x30;
                        if (j >= 0x80 && j <= 0xDF) 
                            fnam[i] = (j + 0x40);
                        if (j === 0xF1) 
                            fnam[i] = 0xB8;
                        if (j === 0xF0) 
                            fnam[i] = 0xA8;
                    }
                    e.name = MiscHelper.decodeString1251(fnam, 0, -1);
                }
            } catch (ex) {
                e.name = MiscHelper.decodeString1251(fnam, 0, -1);
            }
            e.pos = (this.m_Stream.position) + extr;
            if (extr > 10 && (e.compressDataSize < 0)) {
                let ii = this._readShort();
                if (ii === 1) {
                    this._readShort();
                    e.uncompressDataSize = this._readInt();
                    this._readInt();
                    e.compressDataSize = this._readInt();
                    this._readInt();
                }
            }
            this.m_Stream.position = e.pos;
            if (e.compressDataSize > 0) 
                this.m_Stream.position = this.m_Stream.position + (e.compressDataSize);
            if (((flags & 8)) !== 0 && e.compressDataSize === 0) {
                let buf = new Uint8Array(10000);
                while (this.m_Stream.position < this.m_Stream.length) {
                    let p0 = this.m_Stream.position;
                    i = this.m_Stream.read(buf, 0, buf.length);
                    if (i < 6) 
                        break;
                    for (let j = 0; j < (i - 4); j++) {
                        if (buf[j] === (0x50) && buf[j + 1] === (0x4B)) {
                            if (((buf[j + 2] === (3) && buf[j + 3] === (4))) || ((buf[j + 2] === (1) && buf[j + 3] === (2))) || ((buf[j + 2] === (5) && buf[j + 3] === (6)))) {
                                p0 += j;
                                e.compressDataSize = p0 - 12 - e.pos;
                                this.m_Stream.position = p0 - 4;
                                e.uncompressDataSize = this._readInt();
                                break;
                            }
                        }
                    }
                    if (e.compressDataSize > 0) 
                        break;
                    this.m_Stream.position = this.m_Stream.position - (4);
                }
            }
            this.entries.push(e);
        }
    }
    
    _readShort() {
        let i = this.m_Stream.read(this.m_Buf, 0, 2);
        if (i !== 2) 
            return -1;
        i = this.m_Buf[1];
        i <<= 8;
        i |= (this.m_Buf[0]);
        return i;
    }
    
    _readInt() {
        let i = this.m_Stream.read(this.m_Buf, 0, 4);
        if (i !== 4) 
            return -1;
        i = this.m_Buf[3];
        i <<= 8;
        i |= (this.m_Buf[2]);
        i <<= 8;
        i |= (this.m_Buf[1]);
        i <<= 8;
        i |= (this.m_Buf[0]);
        return i;
    }
    
    close() {
        if (this.m_Stream !== null) 
            this.m_Stream.close();
    }
    
    unzip(e) {
        const ArchiveHelper = require("./../../../util/ArchiveHelper");
        if (e.compressDataSize === 0) 
            return null;
        if (e.method === 8 || e.method === 0) {
        }
        else 
            return null;
        let buf = new Uint8Array(e.compressDataSize);
        this.m_Stream.position = e.pos;
        this.m_Stream.read(buf, 0, buf.length);
        if (e.method === 0) 
            return buf;
        return ArchiveHelper.decompressDeflate(buf);
    }
}


module.exports = MyZipFile