<commit_before>var serialport = require("serialport"),
    rfxcom = require("./index"),
    EventEmitter = require("events").EventEmitter,
    util = require("util");

function RfxCom(device, options) {
    var self = this;

    self.options = options || {};
    self.handlers = {
        0x01: "statusHandler",
        0x02: "messageHandler",
        0x10: "lighting1Handler",
        0x11: "lighting2Handler",
        0x13: "lighting4Handler",
        0x14: "lighting5Handler",
        0x15: "lighting6Handler",
        0x16: "chime1Handler",
        0x20: "security1Handler",
        0x4f: "temprain1handler",
        0x50: "temp19Handler",
        0x51: "humidity1Handler",
        0x52: "temphumidity19Handler",
        0x54: "temphumbaro12Handler",
        0x55: "rain16Handler",
        0x56: "wind16Handler",
        0x57: "uv13Handler",
        0x59: "elec1Handler",
        0x5a: "elec23Handler",
        0x5b: "elec4Handler",
        0x5c: "elec5Handler",
        0x5d: "weightHandler",
        0x70: "rfxsensorHandler",
        0x71: "rfxmeterHandler"
    };

    // Running counter for command numbers.
    self._cmd = 0;

    // Allow for faking out the SerialPort
    if (typeof self.options.port !== "undefined") {
        self.serialport = options.port;
    }

    // Store the device to use
    self.device = device;

    // This is a buffering parser which accumulates bytes until it receives the
    // number of bytes specified in the first byte of the message.
    // It relies on a flushed buffer, to ensure the first byte corresponds to the
    // size of the first message.
    // The 'data' message emitted has all the bytes from the message.
    // This is the version from Kev's drop-zero-length-bytes fork
    self.rfxtrxParser = function() {
        var data = [],
            requiredBytes = null;
        return function(emitter, buffer) {
            // Collect data
            // If we have no required bytes and the number of expected bytes != 0 then we can store the bytes.
            if (requiredBytes === null && buffer[0] != 0) {
                requiredBytes = buffer[0] + 1;
            }
            if (requiredBytes != null) {
                data.push.apply(data, buffer);
                if (data.length >= requiredBytes) {
                    emitter.emit("data", data.slice(0, requiredBytes));
                    data = data.slice(requiredBytes);
                    requiredBytes = null
                }
            }
        };
    };

    self.readyCallback = null;
    self.on("ready", function() {
        self.reset(function(err, response, cmdId) {
            if (err) {
                self.close();
                self.emit("disconnect", err);
            } else {
                self.delay(500);
                self.flush(function (err, result) {
                    if (err) {
                        self.close();
                        self.emit("disconnect", err);
                    } else {
                        self.getStatus(function (err, response, cmdId) {
                            if (err) {
                                self.close();
                                self.emit("disconnect", err);
                            } else {
                                if (typeof(self.readyCallback) === "function") {
                                    self.readyCallback();
                                }
                            }
                        });
                    }
                });
            }
        });
    });

    // This is how long a caller must wait between initialisation attempts
    // It is long enough for the 'ready' event to have been emitted if the
    // previous call to initialise() succeeded
    self.initialiseWaitTime = 6000;
    self.connected = false;
    self.initialising = false;
}

util.inherits(RfxCom, EventEmitter);

RfxCom.prototype.open = function() {
    var self = this;
    // If we weren't supplied a serialport in the constructor, create one
    if (typeof self.serialport === "undefined") {
        // Delay opening the serialport until after the event handlers are installed
        self.serialport = new serialport.SerialPort(self.device, {
            baudrate: 38400,
            parser: self.rfxtrxParser()
        }, /* openImmediately = */ false);
    }
    // If the RFXTRX has just been connected, we must wait for at least 5s before any
    // attempt to communicate with it, or it will enter the flash bootloader.
    // We can't know how long it has been connected, so we must always wait!
    self.serialport.on("open", function () {
        self.connected = true;
        self.emit("connecting");
        setTimeout(function () { self.emit("ready") }, self.initialiseWaitTime - 500);
    });

    // Add data read event listener
    self.serialport.on("data", function(data) {
        if (self.options.debug) {
            console.log("[rfxcom] on " + self.device + " - " + "Received: %s", self.dumpHex(data));
        }
        self.emit("receive", data);

        var length = data.shift(),
            packetType = data.shift(),
            handler = self.handlers[packetType];

        if (typeof handler !== "undefined") {
            self[handler](data);
        } else {
            if (self.options.debug) {
                console.log("[rfxcom] on " + self.device + " - " + "Unhandled packet type = %s", self.dumpHex([packetType]));
            }<commit_msg>Parser can now emit more than one "data" event per call, to empty a buffer containing multiple packets An invalid packet length byte (<4) now empties data[] Don't call packet handler if the actual packet length does not match its first byte<commit_after>var serialport = require("serialport"),
    rfxcom = require("./index"),
    EventEmitter = require("events").EventEmitter,
    util = require("util");

function RfxCom(device, options) {
    var self = this;

    self.options = options || {};
    self.handlers = {
        0x01: "statusHandler",
        0x02: "messageHandler",
        0x10: "lighting1Handler",
        0x11: "lighting2Handler",
        0x13: "lighting4Handler",
        0x14: "lighting5Handler",
        0x15: "lighting6Handler",
        0x16: "chime1Handler",
        0x20: "security1Handler",
        0x4f: "temprain1handler",
        0x50: "temp19Handler",
        0x51: "humidity1Handler",
        0x52: "temphumidity19Handler",
        0x54: "temphumbaro12Handler",
        0x55: "rain16Handler",
        0x56: "wind16Handler",
        0x57: "uv13Handler",
        0x59: "elec1Handler",
        0x5a: "elec23Handler",
        0x5b: "elec4Handler",
        0x5c: "elec5Handler",
        0x5d: "weightHandler",
        0x70: "rfxsensorHandler",
        0x71: "rfxmeterHandler"
    };

    // Running counter for command numbers.
    self._cmd = 0;

    // Allow for faking out the SerialPort
    if (typeof self.options.port !== "undefined") {
        self.serialport = options.port;
    }

    // Store the device to use
    self.device = device;

    // This is a buffering parser which accumulates bytes until it receives the
    // number of bytes specified in the first byte of the message.
    // It relies on a flushed buffer, to ensure the first byte corresponds to the
    // size of the first message.
    // The 'data' message emitted has all the bytes from the message.
    // This is the version from Kev's drop-zero-length-bytes fork
    self.rfxtrxParser = function() {
        var data = [],
            requiredBytes = null;
        return function(emitter, buffer) {
            // Collect data
            // If we have no required bytes and the number of expected bytes >= 4 then we can store the bytes.
            // (this is the length of the shortest packet type)
            if (requiredBytes === null && buffer[0] >= 4) {
                requiredBytes = buffer[0] + 1;
            }
            if (requiredBytes != null) {
                data.push.apply(data, buffer);
                while (data.length >= requiredBytes) {
                    emitter.emit("data", data.slice(0, requiredBytes));
                    data = data.slice(requiredBytes);
                    if (data.length > 0 && data[0] >= 4) {
                        requiredBytes = data[0] + 1;
                    } else {
                        requiredBytes = null;
                        data = [];
                        break;
                    }
                }
            }
        };
    };

    self.readyCallback = null;
    self.on("ready", function() {
        self.reset(function(err, response, cmdId) {
            if (err) {
                self.close();
                self.emit("disconnect", err);
            } else {
                self.delay(500);
                self.flush(function (err, result) {
                    if (err) {
                        self.close();
                        self.emit("disconnect", err);
                    } else {
                        self.getStatus(function (err, response, cmdId) {
                            if (err) {
                                self.close();
                                self.emit("disconnect", err);
                            } else {
                                if (typeof(self.readyCallback) === "function") {
                                    self.readyCallback();
                                }
                            }
                        });
                    }
                });
            }
        });
    });

    // This is how long a caller must wait between initialisation attempts
    // It is long enough for the 'ready' event to have been emitted if the
    // previous call to initialise() succeeded
    self.initialiseWaitTime = 6000;
    self.connected = false;
    self.initialising = false;
}

util.inherits(RfxCom, EventEmitter);

RfxCom.prototype.open = function() {
    var self = this;
    // If we weren't supplied a serialport in the constructor, create one
    if (typeof self.serialport === "undefined") {
        // Delay opening the serialport until after the event handlers are installed
        self.serialport = new serialport.SerialPort(self.device, {
            baudrate: 38400,
            parser: self.rfxtrxParser()
        }, /* openImmediately = */ false);
    }
    // If the RFXTRX has just been connected, we must wait for at least 5s before any
    // attempt to communicate with it, or it will enter the flash bootloader.
    // We can't know how long it has been connected, so we must always wait!
    self.serialport.on("open", function () {
        self.connected = true;
        self.emit("connecting");
        setTimeout(function () { self.emit("ready") }, self.initialiseWaitTime - 500);
    });

    // Add data read event listener
    self.serialport.on("data", function(data) {
        if (self.options.debug) {
            console.log("[rfxcom] on " + self.device + " - " + "Received: %s", self.dumpHex(data));
        }
        self.emit("receive", data);

        var length = data[0] + 1,
            packetType = data[1],
            handler = self.handlers[packetType];
        // Avoid calling a handler with the wrong length packet
        if (data.length != length) {
            if (self.options.debug) {
                console.log("[rfxcom] on " + self.device + " - " + "Wrong packet length: %d bytes, should be %d", data.length, length + 1);
            }
        } else {
            if (typeof handler !== "undefined") {
                self[handler](data.slice(2));
            } else {
                if (self.options.debug) {
                    console.log("[rfxcom] on " + self.device + " - " + "Unhandled packet type = %s", self.dumpHex([packetType]));
                }
            }
{'fraction_non_alphanumeric': 0.11152732845223906, 'fraction_numerical': 0.020687893751064192, 'mean_word_length': 1.653489948046081, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3163561', 'n_tokens_mistral': 3317, 'n_tokens_neox': 3121, 'n_words': 915}