将数组缓冲区转换为字符串

时间:2014-08-27 21:54:20

标签: javascript google-chrome-app

将数组缓冲区转换为字符串然后在div中显示输出时,我得到了一些奇怪的结果。

我在Chrome打包的应用程序中从USB端口获取一些GPS数据。它将从端口接收的数组缓冲区转换为字符串并输出。功能是:

var onReceiveCallback = function(info) {    
    if (info.connectionId == connectionId && info.data) {
        $(".output").append(ab2str(info.data));
    }   
};

/* Interprets an ArrayBuffer as UTF-8 encoded string data. */
var ab2str = function(buf) {
    var bufView = new Uint8Array(buf);
    var encodedString = String.fromCharCode.apply(null, bufView);
    return decodeURIComponent(escape(encodedString));
};

我有一个启动和停止按钮,显然可以启动和停止从gps设备读取数据。当我第一次启动它并按预期输出时,就像:

  

$ GPGGA,214948.209 ,,,,, 0,0 ,,, M ,, M ,, * 41 $ GPGSA,A,1 ,,,,,,,,,,,,,,, * 1E   $ GPGSV,1,1,01,07 ,,, 33 * 7F   $ GPRMC,214948.209,V ,,,,, 0.00,0.00,270814 ,,, N * 4C   $ GPGGA,214949.209 ,,,,, 0,0 ,,, M ,, M ,, * 40 $ GPGSA,A,1 ,,,,,,,,,,,,,,, * 1E   $ GPGSV,1,1,01,07 ,,, 34 * 78   $ GPRMC,214949.209,V ,,,,, 0.00,0.00,270814 ,,, N * 4D

但是当我停止它并重新启动它时,虽然我清除了输出div,但输出数据似乎与之前的结果混合在一起。像:

  

$$ GPGPGGGGAA ,, 221155115544..202099 ,,,,,,,,, 0,0,0,0 ,,,,,, MM ,,,, MM ,,,, ** 4455   $$ GGPPGGSSAA ,, AA ,, 11 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ** 11EE   $$ GGPGPGSSVV ,, 11日,11日,0022,,0077 ,,,,,, 3344,1,177 ,,,,,, 3311 ** 77FF   $$ GGPPRRMMCC ,, 212155115544..220099,VV ,,,,,,,,,, 00..0000,00..0000,227700881144 ,,,,,, NN * 4 * 488   $$ GPGGPGGGAA ,, 221155115555..220099 ,,,,,,,,,, 00,00 ,,,,,, MM ,,,, MM ,,,, ** 4444   $$ GGPPGGSSAA ,, AA ,, 11 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ** 11EE   $ G $ GPPGGSSVV ,, 11日,11日,0022,,0077 ,,,,,, 331,1,1177 ,,,,,, 2255 ** 77FF   $$ GGPPRRMMCC,2,21155115555..220099,VV ,,,,,,,,,, 00..0000,00..0000,227700881144 ,,,,,, N * N * 4499

它就像一个缓冲区或变量没有被清空,或者其他疯狂的东西,我无法弄清楚。任何指针都赞赏。

编辑:

这是'start'函数,它清除输出div并重新连接:

// when the start button is clicked
$( "#start" ).click(function() {
    if ( deviceId == 0 ) {
        console.log("Please select a device");
        return;
    }
    else {
        $(".output").empty();
        serial.connect(deviceId, {bitrate: 9600}, onConnect);
    }
});

1 个答案:

答案 0 :(得分:1)

我发现这种技术在我自己的代码中不可靠,但我不记得问题是否与您报告的问题类似:

var ab2str = function(buf) { // not reliable
    var bufView = new Uint8Array(buf);
    var encodedString = String.fromCharCode.apply(null, bufView);
    return decodeURIComponent(escape(encodedString));
};

所以,我这样做了,代码来自一个谷歌Chrome应用程序示例(tcpserver):

function ab2str(buf, callback) {
    var bb = new Blob([new Uint8Array(buf)]);
    var f = new FileReader();
    f.onload = function(e) {
        callback(e.target.result);
    };
    f.readAsText(bb);
}

请注意,此版本不是一个确切的替代品,因为它是异步的。

现在,从Chrome版本38(现在处于测试阶段)开始,您可以这样做:

function ab2str(buf) {
    var dataView = new DataView(buf);
    var decoder = new TextDecoder('utf-8');
    return decoder.decode(dataView);
}

由于我总是运行测试版并且正在为即将出版的书准备示例,我现在正在以最新的方式进行测试。尝试一下,看看你的问题是否消失了。如果没有,我认为检查info.data的建议仍然很好。

更新:我刚刚查看了这个反向功能,您可能会在某些方面找到方便之处:

function str2ab(buf) {
    var encoder = new TextEncoder('utf-8');
    return encoder.encode(buf).buffer;
}
相关问题