专业打酱油javaee 2023-04-04 16:40 采纳率: 83.3%
浏览 70
已结题

C代码解压代码更换成js代码


unsafe class Decompressor
        {
            byte* _pSrc;
            uint _srcLen; 
            byte* _pDst;
            uint _dstLen;
            uint _dstLenBeforeWriteNonVertexesData;
            bool _toDoubleCoordValue;
            double _factor_toDoubleCoordValue;
            uint MerelyReadUInt32() 
            {
                if (_srcLen < sizeof(uint)) 

                    throw new ArgumentException();
                var result = *(uint*)_pSrc;
                _pSrc += sizeof(uint);
                _srcLen -= sizeof(uint);
                return result;
            }
            ushort MerelyReadUInt16()
            {
                if (_srcLen < sizeof(ushort))
                    throw new ArgumentException();
                var result = *(ushort*)_pSrc;
                _pSrc += sizeof(ushort);
                _srcLen -= sizeof(ushort);
                return result;
            }
            void ReadRaw(uint numBytes)
            {
                if (_srcLen < numBytes || _dstLen < numBytes)
                    throw new ArgumentException();
                Buffer.MemoryCopy(_pSrc, _pDst, _dstLen, numBytes);
                _pSrc += numBytes;
                _srcLen -= numBytes;
                _pDst += numBytes;
                _dstLen -= numBytes;
            }
            void ReadNonVertexesData()
            {
                var numBytes = MerelyReadUInt32();
                ReadRaw(numBytes);
            }
            void ReadVertexesData()
            {
                //读取几何头的位置
                var offset_GeomHead = MerelyReadUInt16();
                if (offset_GeomHead != 0)
                {
                    if (_dstLen + offset_GeomHead > _dstLenBeforeWriteNonVertexesData || offset_GeomHead < 8)
                        throw new ArgumentException();
                    var pCoordDim = (int*)(_pDst + (4 - offset_GeomHead));
                    if (*pCoordDim != 0x80)
                        throw new ArgumentException();
                    if (_toDoubleCoordValue)//更改坐标维度(消除“单精度”标志)
                        *pCoordDim = 0;
                }
                //读取首顶点
                if (_srcLen < sizeof(int) * 2)
                    throw new ArgumentException();
                var vLast = *(Vertex2I*)_pSrc;
                _pSrc += sizeof(int) * 2;
                _srcLen -= sizeof(int) * 2;
                if (_toDoubleCoordValue)
                {
                    if (_dstLen < sizeof(double) * 2)
                        throw new ArgumentException();
                    var pDst = (Vertex2d*)_pDst;
                    pDst->x = _factor_toDoubleCoordValue * vLast.x;
                    pDst->y = _factor_toDoubleCoordValue * vLast.y;
                    _pDst += sizeof(double) * 2;
                    _dstLen -= sizeof(double) * 2;
                }
                else
                {
                    if (_dstLen < sizeof(int) * 2)
                        throw new ArgumentException();
                    *(Vertex2I*)_pDst = vLast;
                    _pDst += sizeof(int) * 2;
                    _dstLen -= sizeof(int) * 2;
                }
                var numVeretxes = MerelyReadUInt32();
                if (numVeretxes == 0)
                    throw new ArgumentException();
                uint numVertexesRead = 1;
                while (numVertexesRead < numVeretxes)
                {
                    var cnt = MerelyReadUInt16();
                    var cnt0 = (uint)(cnt & 0x7FFF);
                    long cnt1 = numVertexesRead;
                    cnt1 += cnt0;
                    if (cnt1 == numVertexesRead || cnt1 > numVeretxes)
                        throw new ArgumentException();

                    if ((cnt & 0x8000) != 0)
                    {//
                        if (_toDoubleCoordValue)
                        {
                            var srcLenChange = (uint)sizeof(int) * 2 * cnt0;
                            var dstLenChange = (uint)sizeof(double) * 2 * cnt0;
                            if (_srcLen < srcLenChange || _dstLen < dstLenChange)
                                throw new ArgumentException();
                            for (uint i = 0; i < cnt0; ++i)
                            {
                                ((double*)_pDst)[i * 2] = _factor_toDoubleCoordValue * ((int*)_pSrc)[i * 2];
                                ((double*)_pDst)[i * 2 + 1] = _factor_toDoubleCoordValue * ((int*)_pSrc)[i * 2 + 1];
                            }
                            _pSrc += srcLenChange;
                            _srcLen -= srcLenChange;
                            _pDst += dstLenChange;
                            _dstLen -= dstLenChange;
                        }
                        else
                        {
                            ReadRaw(cnt0 * sizeof(int) * 2);
                        }
                        vLast = ((Vertex2I*)_pSrc)[-1];
                    }
                    else
                    {
                        var srcLenChange = (uint)sizeof(short) * 2 * cnt0;
                        var dstLenChange = (uint)(_toDoubleCoordValue ? sizeof(double) : sizeof(int)) * 2 * cnt0;
                        if (_srcLen < srcLenChange || _dstLen < dstLenChange)
                            throw new ArgumentException();
                        if (_toDoubleCoordValue)
                        {
                            for (uint i = 0; i < cnt0; ++i)
                            {
                                ((double*)_pDst)[i * 2] = _factor_toDoubleCoordValue * (vLast.x += ((short*)_pSrc)[i * 2]);
                                ((double*)_pDst)[i * 2 + 1] = _factor_toDoubleCoordValue * (vLast.y += ((short*)_pSrc)[i * 2 + 1]);
                            }
                        }
                        else
                        {
                            for (uint i = 0; i < cnt0; ++i)
                            {
                                ((int*)_pDst)[i * 2] = vLast.x += ((short*)_pSrc)[i * 2];
                                ((int*)_pDst)[i * 2 + 1] = vLast.y += ((short*)_pSrc)[i * 2 + 1];
                            }
                        }
                        _pSrc += srcLenChange;
                        _srcLen -= srcLenChange;
                        _pDst += dstLenChange;
                        _dstLen -= dstLenChange;
                    }
                    numVertexesRead = (uint)cnt1;
                }
            }

            public byte[] Result { get; }

            internal Decompressor(byte[] compressedData, uint offset, uint length, double? factor_toDoubleCoordValue)
            {
                _srcLen = (uint)compressedData.Length;
                if (_srcLen < offset)
                    throw new ArgumentException();
                _srcLen -= offset;
                if (_srcLen < length)
                    throw new ArgumentException();
                _srcLen = length;
                fixed (byte* pSrc0 = &compressedData[offset])  //fixed禁止垃圾回收器重定位可移动的变量。fixed语句只能出现在不安全的上下文中。
                {
                    _pSrc = pSrc0; //
                    //读取顶点数量
                    if (_srcLen < sizeof(uint))
                        throw new ArgumentException();
                    var cntVertexes = *(uint*)(_pSrc + (_srcLen - sizeof(uint)));
                    _srcLen -= sizeof(uint);
                    //准备结果缓冲区
                    _dstLen = MerelyReadUInt32();
                    var numNonVertexDataBytes = _dstLen - (long)cntVertexes * sizeof(int) * 2;
                    if (numNonVertexDataBytes <= 0)
                        throw new ArgumentException();
                    if (_toDoubleCoordValue = factor_toDoubleCoordValue.HasValue)
                        _factor_toDoubleCoordValue = factor_toDoubleCoordValue.Value;

                        
                    Result = new byte[numNonVertexDataBytes + cntVertexes * (_toDoubleCoordValue ? sizeof(double) : sizeof(int)) * 2];
                    _dstLen = (uint)Result.Length;
                    fixed (byte* pDst0 = &Result[0])
                    {
                        _pDst = pDst0;
                        //
                        while (_srcLen != 0 || _dstLen != 0)
                        {
                            _dstLenBeforeWriteNonVertexesData = _dstLen;
                            ReadNonVertexesData();
                            ReadVertexesData();
                        }
                    }
                }
            }
        }


能否更新成js书写

  • 写回答

7条回答 默认 最新

  • 百晓生2023 2023-04-05 08:56
    关注
    该回答引用ChatGPT
    将C#代码转化成JavaScript代码需要注意的几个点:

    1. 在JavaScript中是没有指针的,需要使用数组模拟指针的操作;

    2. JavaScript中没有fixed关键字,需要通过创建ArrayBuffer类型的数据进行操作;

    3. 在JavaScript中ByteBuffer中没有Buffer.MemoryCopy方法,需要使用ArrayBuffer的slice方法来实现;

    4. 在JavaScript中使用typed数组能够更好地模拟C中的数据类型,例如Int32Array、Uint16Array等。

    下面是JavaScript代码:


    class Decompressor {
    constructor(compressedData, offset, length, factor_toDoubleCoordValue) {
    var buffer = new ArrayBuffer(compressedData.length);
    var uint8Array = new Uint8Array(buffer);
    for (var i = 0; i < compressedData.length; i++) {
    uint8Array[i] = compressedData[i];
    }
    var pSrc0 = uint8Array.slice(offset);
    this.result = new ArrayBuffer(0);
    this.pDst = new Uint8Array(this.result);
    this.pSrc = new Uint8Array(pSrc0);
    this._srcLen = compressedData.length - offset;
    this._srcLen -= offset;
    if (this._srcLen < length) {
    throw new Error("decoded data too large");
    }
    this._srcLen = length;
    this._dstLen = this.merelyReadUInt32();
    var cntVertexes = this.merelyReadUInt32();
    var numNonVertexDataBytes = this._dstLen - cntVertexes * 2 * 4;
    if (numNonVertexDataBytes <= 0) {
    throw new Error("decoded data has invalid format");
    }
    if (factor_toDoubleCoordValue !== undefined) {
    this._toDoubleCoordValue = true;
    this._factor_toDoubleCoordValue = factor_toDoubleCoordValue;
    }
    this.result = new ArrayBuffer(numNonVertexDataBytes + cntVertexes * (this._toDoubleCoordValue ? 2 * 8 : 2 * 4));
    this.pDst = new Uint8Array(this.result);
    this._dstLen = this.result.byteLength;
    var numVertexesRead = 1;
    while (this._srcLen != 0 || this._dstLen != 0) {
    var dstLenBeforeWriteNonVertexesData = this._dstLen;
    this.readNonVertexesData();
    this.readVertexesData(numVertexesRead);
    numVertexesRead = this.merelyReadUInt32();
    if (numVertexesRead == 0) {
    break;
    }
    }
    }
    readDouble(pVal) {
    if (this._srcLen < 8) {
    throw new Error("data underflow");
    }
    this._srcLen -= 8;
    pVal[0] = new Float64Array(this.pSrc.slice(0, 8).buffer)[0];
    for (var i = 0; i < 8; i++) {
    this.pSrc = this.pSrc.slice(1);
    }
    }
    readInt(pVal) {
    if (this._srcLen < 4) {
    throw new Error("data underflow");
    }
    this._srcLen -= 4;
    pVal[0] = new Int32Array(this.pSrc.slice(0, 4).buffer)[0];
    for (var i = 0; i < 4; i++) {
    this.pSrc = this.pSrc.slice(1);
    }
    }
    merelyReadUInt32() {
    if (this._srcLen < 4) {
    throw new Error("data underflow");
    }
    this._srcLen -= 4;
    var uint32Array = new Uint32Array(this.pSrc.slice(0, 4).buffer);
    var result = uint32Array[0];
    for (var i = 0; i < 4; i++) {
    this.pSrc = this.pSrc.slice(1);
    }
    return result;
    }
    merelyReadUInt16() {
    if (this._srcLen < 2) {
    throw new Error("data underflow");
    }
    this._srcLen -= 2;
    var uint16Array = new Uint16Array
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月7日
  • 已采纳回答 4月7日
  • 创建了问题 4月4日

悬赏问题

  • ¥15 关于vue2中methods使用call修改this指向的问题
  • ¥15 idea自动补全键位冲突
  • ¥15 请教一下写代码,代码好难
  • ¥15 iis10中如何阻止别人网站重定向到我的网站
  • ¥15 滑块验证码移动速度不一致问题
  • ¥15 定制ai直播实时换脸软件
  • ¥100 栈回溯相关,模块加载后KiExceptionDispatch无法正常回溯了
  • ¥15 Utunbu中vscode下cern root工作台中写的程序root的头文件无法包含
  • ¥15 麒麟V10桌面版SP1如何配置bonding
  • ¥15 Marscode IDE 如何预览新建的 HTML 文件