/*
文件名:MemoryClass.nut
路径:Dps_A/BaseClass/MemoryClass/MemoryClass.nut
创建日期:2024-09-17	08:23
文件用途:内存类
*/
class Memory {

    function alloc(Size) {
        return NativePointer(Size);
    }

    function allocUtf8String(Str) {
        local P = NativePointer(Str_Ptr(Str));
        P.Size = Str.len();
        return P;
    }

    function copy(P1, P2, Size) {
        local WriteArr = Sq_ReadByteArr(P2.C_Object, Size);
        P1.writeByteArray(WriteArr);
    }

    function reset(P1, Size) {
        local WriteArr = array(Size, 0);
        P1.writeByteArray(WriteArr);
    }
}

class NativePointer extends Base_C_Object {
    //大小
    Size = -1;

    function _tyoeof()
    {
        return "Sq_Pointer";
    }

    constructor(T) {
        if (typeof T == "integer") {
            base.constructor(Sq_New_Point(T));
            Size = T;
            //注册销毁伪析构
            Register_Destruction(C_Object, this);
        } else if (typeof T == "userdata") {
            base.constructor(T);
        } else if (typeof T == "string") {
            base.constructor(S_Ptr(T));
        }
    }

    function Output(Size) {
        local Buf = Sq_Point2Blob(this.C_Object, Size);
        local Str = "[";
        foreach(Value in Buf) {
            Str = format("%s%02X", Str, Value);
            Str += ",";
        }
        Str += "]";
        print(Str);
    }

    function add(intoffset) {
        return NativePointer(Sq_PointerOperation(this.C_Object, intoffset, "+"));
    }

    function sub(intoffset) {
        return NativePointer(Sq_PointerOperation(this.C_Object, intoffset, "-"));
    }

    function writeByteArray(arr) {
        Sq_Memory_WriteByteArr(this.C_Object, arr);
    }

    function readByteArray(size) {
        local PointB = Sq_Point2Blob(this.C_Object, size);
        local arr = [];
        foreach(value in PointB) {
            arr.append(value);
        }
        return arr;
    }


    function write(value, type) {
        local Buf = blob(0);
        Buf.writen(value, type);
        Sq_Memory_WriteBlob(this.C_Object, Buf);
    }

    function writeS8(value) {
        write(value, 'c');
    }

    function writeU8(value) {
        write(value, 'b');
    }

    function writeS16(value) {
        write(value, 's');
    }

    function writeU16(value) {
        write(value, 'w');
    }

    function writeS32(value) {
        write(value, 'i');
    }

    function writeU32(value) {
        write(value, 'i');
    }

    function writeShort(value) {
        write(value, 's');
    }

    function writeUShort(value) {
        write(value, 'w');
    }

    function writeInt(value) {
        write(value, 'i');
    }

    function writeUInt(value) {
        write(value, 'i');
    }

    function writeFloat(value) {
        write(value, 'f');
    }

    function writeDouble(value) {
        write(value, 'd');
    }


    function read(type) {
        local Buf = Sq_Point2Blob(this.C_Object, 4);
        return Buf.readn(type);
    }

    function readS8() {
        return read('c');
    }

    function readU8() {
        return read('b');
    }

    function readS16() {
        return read('s');
    }

    function readU16() {
        return read('w');
    }

    function readS32() {
        return read('i');
    }

    function readU32() {
        return read('i');
    }

    function readShort() {
        return read('s');
    }

    function readUShort() {
        return read('w');
    }

    function readInt() {
        return read('i');
    }

    function readUInt() {
        return read('i');
    }

    function readFloat() {
        return read('f');
    }

    function readDouble() {
        return read('d');
    }

    function readUtf8String(...) {
        if (vargv.len() > 0) {
            return Sq_Memory_ReadString(this.C_Object, vargv[0]);
        } else {
            return Sq_Memory_ReadString(this.C_Object);
        }
    }

    function readPointer() {
        return Sq_ReadPoint(this.C_Object);
    }

    function readBinary(Size) {
        return Sq_Point2Blob(this.C_Object, Size);
    }

    function tostring() {
        return this.C_Object.tostring();
    }
}