试图将C ++代码转换为Javascript代码

时间:2016-07-01 00:40:06

标签: javascript

好吧,我正在尝试用C ++(自定义LZSS解压缩程序)转换此代码:

// Modified LZSS routine
// - starting position at 0 rather than 0xFEE
// - optionally, additional byte for repetition count
// - dictionary writing in two passes
static bstr custom_lzss_decompress(
const bstr &input, size_t output_size, const size_t dict_capacity)
{
std::vector<u8> dict(dict_capacity);
size_t dict_size = 0;
size_t dict_pos = 0;

bstr output(output_size);
auto output_ptr = output.get<u8>();
auto output_end = output.end<const u8>();
auto input_ptr = input.get<const u8>();
auto input_end = input.end<const u8>();

u16 control = 0;
while (output_ptr < output_end)
{
    control >>= 1;
    if (!(control & 0x100))
        control = *input_ptr++ | 0xFF00;

    if (control & 1)
    {
        dict[dict_pos++] = *output_ptr++ = *input_ptr++;
        dict_pos %= dict_capacity;
        if (dict_size < dict_capacity)
            dict_size++;
    }
    else
    {
        auto tmp = *reinterpret_cast<const u16*>(input_ptr);
        input_ptr += 2;

        auto look_behind_pos = tmp >> 4;
        auto repetitions = tmp & 0xF;
        if (repetitions == 0xF)
            repetitions += *input_ptr++;
        repetitions += 3;

        auto i = repetitions;
        while (i-- && output_ptr < output_end)
        {
            *output_ptr++ = dict[look_behind_pos++];
            look_behind_pos %= dict_size;
        }

        auto source = &output_ptr[-repetitions];
        while (source < output_ptr)
        {
            dict[dict_pos++] = *source++;
            dict_pos %= dict_capacity;
            if (dict_size < dict_capacity)
                dict_size++;
        }
    }
}

return output;
}

进入javascript版本,我实际上就是这样:

function custom_lzss_decompress(input,osize,dictcap){
var dict = new Uint8Array(dictcap);
var output = new Uint8Array(osize);
var data = str2ab(input);
var dict_size = 0;
var dict_pos = 0;
var control = 0;
var iptr = 0;
var optr = 0;

while (iptr < osize){
    control >>= 1;
    if(!(control & 0x100)){
        control = data[iptr] | 0xFF00;
        iptr++; 
    }
    if(control & 1){
        dict[dict_pos] = output[optr] = data[iptr];
        dict_pos++;
        iptr++;
        optr++;
        dict_pos %= dictcap;

        if(dict_size < dictcap)
            dict_size++;
    }
    else{
        var tmp = new Uint16Array(1);
        tmp[0] = (data[iptr] << 8) + data[iptr+1];
        iptr += 2;
        var loop_behind_pos = new Uint16Array(1);
        loop_behind_pos[0] = tmp >> 4;
        var repetitions = new Uint16Array(1);
        repetitions[0] = tmp & 0xF;
        if(repetitions[0] == 0xF){
            repetitions[0] += data[iptr];
        }
        iptr++;
        repetitions[0] += 3;
        var ai = new Uint16Array(1);
        ai[0] = repetitions[0];

        while(ai[0] && (optr < osize)){
            ai[0]--;
            output[optr] = dict[loop_behind_pos];
            optr++;
            loop_behind_pos++;
            loop_behind_pos %= dict_size;
        }
        var source = new Uint16Array(1);
        source[0] = output[-repetitions[0]];
        while(source[0] < optr){
            dict[dict_pos] = output[source];
            dict_pos++;
            source++;
            dict_pos %= dictcap;
            if(dict_size < dictcap)
                dict_size++;
        }

    }
}
return output;
}

它运行......但是不起作用......我无法弄清楚发生了什么......有人能看到一些我没见过的奇怪错误吗?

1 个答案:

答案 0 :(得分:0)

我看到一个问题,一个潜在的问题。问题始终存在于重复[0] == 0xF handler. You're incrementing iptr`中,但原始代码仅在if的正文中执行。

潜在问题在于16位字读取tmp[0] = (data[iptr] << 8) + data[iptr+1];。如果单词是big-endian,则可以正常工作,但如果源是little-endian,则不会给出正确的值。