2017-11-16 5 views
1

私はnode.jsを使って、Linux用のキーボードイベントパーサーを書いています。多少問題はありませんが、ノードが数バイトをスキップしているように見えることがあります。私はReadStreamを使用してデータを取得し、処理し、最終的に区切り文字が遭遇すると出力します(私の場合は\n)。ここでReadStreamがバイトをスキップしていますか?

は、読み出したデータを扱う私のクラスの一部です:

// This method is called through this callback: 
// this.readStream = fs.createReadStream(this.path); 
// this.readStream.on("data", function(a) { self.parse_data(self, a); }); 

EventParser.prototype.parse_data = function(self, data) 
{ 
    /* 
    * Data format : 
    * { 
    * 0x00 : struct timeval time { long sec (8), long usec (8) }  (8 bytes) 
    * 0x08 : __u16 type             (2 bytes) 
    * 0x10 : __u16 code             (2 bytes) 
    * 0x12 : __s32 value            (4 bytes) 
    * }                 = (16 bytes) 
    */ 

    var dataBuffer = new Buffer(data); 
    var slicedBuffer = dataBuffer.slice(0, 16); 
    dataBuffer = dataBuffer.slice(16, dataBuffer.length); 

    while (dataBuffer.length > 0 && slicedBuffer.length == 16) 
    { 
    var type = GetDataType(slicedBuffer), 
     code = GetDataCode(slicedBuffer), 
     value = GetDataValue(slicedBuffer); 

    if (type == CST.EV.KEY) 
    { // Key was pressed: KEY event type 
     if (code == 42 && value == 1) { self.shift_pressed = true; } 
     if (code == 42 && value == 0) { self.shift_pressed = false; } 

     console.log(type + "\t" + code + "\t" + value + "\t(" + GetKey(self.shift_pressed, code) + ")") 
     // GetKey uses a static array to get the actual character 
     // based on whether the shift key is held or not 

     if (value == 1) 
     self.handle_processed_data(GetKey(self.shift_pressed, code)); 
     // handle_processed_data adds characters together, and outputs the string when encountering a 
     // separator character (in this case, '\n') 
    } 

    // Take a new slice, and loop. 
    slicedBuffer = dataBuffer.slice(0, 16); 
    dataBuffer = dataBuffer.slice(16, dataBuffer.length); 
    } 
} 

// My system is in little endian! 
function GetDataType(dataBuffer) { return dataBuffer.readUInt16LE(8); } 
function GetDataCode(dataBuffer) { return dataBuffer.readUInt16LE(10); } 
function GetDataValue(dataBuffer) { return dataBuffer.readInt32LE(12); } 

私は基本的なデータ構造を埋めるよBufferを使用して一番上に説明しました。面白い部分は最後に近いconsole.logで、私たちのコールバックで渡された興味深いもの(KEYイベントに関連しています)が印刷されます。ここでは、ログ、期待される結果との完全な、と実際の結果の結果は次のとおりです。

EventParserConstructor: Listening to /dev/input/event19 
/* Expected result: CODE-128 */ 
/* Note that value 42 is the SHIFT key */ 
1 42 1 () 
1 46 1 (C) 
1 42 0 () 
1 46 0 (c) 
1 42 1 () 
1 24 1 (O) 
1 42 0 () 
1 24 0 (o) 
1 42 1 () 
1 32 1 (D) 
1 42 0 () 
1 32 0 (d) 
1 42 1 () 
1 18 1 (E) 
1 42 0 () 
1 18 0 (e) 
1 12 0 (-) 
1 2 0 (1) 
1 3 1 (2) 
1 3 0 (2) 
1 9 1 (8) 
1 9 0 (8) 
1 28 1 (
) 
[EventParser_Handler]/event_parser.handle_processed_data: CODE28 
/* Actual result: CODE28 */ 
/* The '-' and '1' events can be seen in the logs, but only */ 
/* as key RELEASED (value: 0), not key PRESSED */ 

我々は唯一のキーリリース(値:0)のように、通り過ぎる-1文字イベントをはっきりと見ることができ、キー押下ではありません。最も奇妙なことはほとんどの場合、イベントが正しく翻訳されていることです。しかし、時間の10%は、これが発生します。

ReadStreamは時折いくつかのバイトを食べていますか?はいの場合は、どのような代替手段を使用する必要がありますか?

ありがとうございます!

答えて

0

まあ、私のループは腐っていることが判明しました。

私は、データが16バイトのチャンクでしかないと仮定していました...明らかに常にそうであるとは限りません。時には、<のパケットが16バイト残っていて、2つの'data'イベントコールバックの間に失われました。

これは、私のクラスにexcessBufferフィールドを追加し、これを使ってデータを受け取ったときに私の最初のslicedBufferを記入することで追加しました。

関連する問題