You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					398 lines
				
				10 KiB
			
		
		
			
		
	
	
					398 lines
				
				10 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								var Chainsaw = require('chainsaw');
							 | 
						||
| 
								 | 
							
								var EventEmitter = require('events').EventEmitter;
							 | 
						||
| 
								 | 
							
								var Buffers = require('buffers');
							 | 
						||
| 
								 | 
							
								var Vars = require('./lib/vars.js');
							 | 
						||
| 
								 | 
							
								var Stream = require('stream').Stream;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports = module.exports = function (bufOrEm, eventName) {
							 | 
						||
| 
								 | 
							
								    if (Buffer.isBuffer(bufOrEm)) {
							 | 
						||
| 
								 | 
							
								        return exports.parse(bufOrEm);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    var s = exports.stream();
							 | 
						||
| 
								 | 
							
								    if (bufOrEm && bufOrEm.pipe) {
							 | 
						||
| 
								 | 
							
								        bufOrEm.pipe(s);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    else if (bufOrEm) {
							 | 
						||
| 
								 | 
							
								        bufOrEm.on(eventName || 'data', function (buf) {
							 | 
						||
| 
								 | 
							
								            s.write(buf);
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        bufOrEm.on('end', function () {
							 | 
						||
| 
								 | 
							
								            s.end();
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return s;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.stream = function (input) {
							 | 
						||
| 
								 | 
							
								    if (input) return exports.apply(null, arguments);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    var pending = null;
							 | 
						||
| 
								 | 
							
								    function getBytes (bytes, cb, skip) {
							 | 
						||
| 
								 | 
							
								        pending = {
							 | 
						||
| 
								 | 
							
								            bytes : bytes,
							 | 
						||
| 
								 | 
							
								            skip : skip,
							 | 
						||
| 
								 | 
							
								            cb : function (buf) {
							 | 
						||
| 
								 | 
							
								                pending = null;
							 | 
						||
| 
								 | 
							
								                cb(buf);
							 | 
						||
| 
								 | 
							
								            },
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        dispatch();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    var offset = null;
							 | 
						||
| 
								 | 
							
								    function dispatch () {
							 | 
						||
| 
								 | 
							
								        if (!pending) {
							 | 
						||
| 
								 | 
							
								            if (caughtEnd) done = true;
							 | 
						||
| 
								 | 
							
								            return;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (typeof pending === 'function') {
							 | 
						||
| 
								 | 
							
								            pending();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            var bytes = offset + pending.bytes;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            if (buffers.length >= bytes) {
							 | 
						||
| 
								 | 
							
								                var buf;
							 | 
						||
| 
								 | 
							
								                if (offset == null) {
							 | 
						||
| 
								 | 
							
								                    buf = buffers.splice(0, bytes);
							 | 
						||
| 
								 | 
							
								                    if (!pending.skip) {
							 | 
						||
| 
								 | 
							
								                        buf = buf.slice();
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else {
							 | 
						||
| 
								 | 
							
								                    if (!pending.skip) {
							 | 
						||
| 
								 | 
							
								                        buf = buffers.slice(offset, bytes);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    offset = bytes;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                if (pending.skip) {
							 | 
						||
| 
								 | 
							
								                    pending.cb();
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                else {
							 | 
						||
| 
								 | 
							
								                    pending.cb(buf);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    function builder (saw) {
							 | 
						||
| 
								 | 
							
								        function next () { if (!done) saw.next() }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        var self = words(function (bytes, cb) {
							 | 
						||
| 
								 | 
							
								            return function (name) {
							 | 
						||
| 
								 | 
							
								                getBytes(bytes, function (buf) {
							 | 
						||
| 
								 | 
							
								                    vars.set(name, cb(buf));
							 | 
						||
| 
								 | 
							
								                    next();
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self.tap = function (cb) {
							 | 
						||
| 
								 | 
							
								            saw.nest(cb, vars.store);
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self.into = function (key, cb) {
							 | 
						||
| 
								 | 
							
								            if (!vars.get(key)) vars.set(key, {});
							 | 
						||
| 
								 | 
							
								            var parent = vars;
							 | 
						||
| 
								 | 
							
								            vars = Vars(parent.get(key));
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            saw.nest(function () {
							 | 
						||
| 
								 | 
							
								                cb.apply(this, arguments);
							 | 
						||
| 
								 | 
							
								                this.tap(function () {
							 | 
						||
| 
								 | 
							
								                    vars = parent;
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								            }, vars.store);
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self.flush = function () {
							 | 
						||
| 
								 | 
							
								            vars.store = {};
							 | 
						||
| 
								 | 
							
								            next();
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self.loop = function (cb) {
							 | 
						||
| 
								 | 
							
								            var end = false;
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            saw.nest(false, function loop () {
							 | 
						||
| 
								 | 
							
								                this.vars = vars.store;
							 | 
						||
| 
								 | 
							
								                cb.call(this, function () {
							 | 
						||
| 
								 | 
							
								                    end = true;
							 | 
						||
| 
								 | 
							
								                    next();
							 | 
						||
| 
								 | 
							
								                }, vars.store);
							 | 
						||
| 
								 | 
							
								                this.tap(function () {
							 | 
						||
| 
								 | 
							
								                    if (end) saw.next()
							 | 
						||
| 
								 | 
							
								                    else loop.call(this)
							 | 
						||
| 
								 | 
							
								                }.bind(this));
							 | 
						||
| 
								 | 
							
								            }, vars.store);
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self.buffer = function (name, bytes) {
							 | 
						||
| 
								 | 
							
								            if (typeof bytes === 'string') {
							 | 
						||
| 
								 | 
							
								                bytes = vars.get(bytes);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            getBytes(bytes, function (buf) {
							 | 
						||
| 
								 | 
							
								                vars.set(name, buf);
							 | 
						||
| 
								 | 
							
								                next();
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self.skip = function (bytes) {
							 | 
						||
| 
								 | 
							
								            if (typeof bytes === 'string') {
							 | 
						||
| 
								 | 
							
								                bytes = vars.get(bytes);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            getBytes(bytes, function () {
							 | 
						||
| 
								 | 
							
								                next();
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self.scan = function find (name, search) {
							 | 
						||
| 
								 | 
							
								            if (typeof search === 'string') {
							 | 
						||
| 
								 | 
							
								                search = new Buffer(search);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else if (!Buffer.isBuffer(search)) {
							 | 
						||
| 
								 | 
							
								                throw new Error('search must be a Buffer or a string');
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            var taken = 0;
							 | 
						||
| 
								 | 
							
								            pending = function () {
							 | 
						||
| 
								 | 
							
								                var pos = buffers.indexOf(search, offset + taken);
							 | 
						||
| 
								 | 
							
								                var i = pos-offset-taken;
							 | 
						||
| 
								 | 
							
								                if (pos !== -1) {
							 | 
						||
| 
								 | 
							
								                    pending = null;
							 | 
						||
| 
								 | 
							
								                    if (offset != null) {
							 | 
						||
| 
								 | 
							
								                        vars.set(
							 | 
						||
| 
								 | 
							
								                            name,
							 | 
						||
| 
								 | 
							
								                            buffers.slice(offset, offset + taken + i)
							 | 
						||
| 
								 | 
							
								                        );
							 | 
						||
| 
								 | 
							
								                        offset += taken + i + search.length;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    else {
							 | 
						||
| 
								 | 
							
								                        vars.set(
							 | 
						||
| 
								 | 
							
								                            name,
							 | 
						||
| 
								 | 
							
								                            buffers.slice(0, taken + i)
							 | 
						||
| 
								 | 
							
								                        );
							 | 
						||
| 
								 | 
							
								                        buffers.splice(0, taken + i + search.length);
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    next();
							 | 
						||
| 
								 | 
							
								                    dispatch();
							 | 
						||
| 
								 | 
							
								                } else {
							 | 
						||
| 
								 | 
							
								                    i = Math.max(buffers.length - search.length - offset - taken, 0);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
								                taken += i;
							 | 
						||
| 
								 | 
							
								            };
							 | 
						||
| 
								 | 
							
								            dispatch();
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self.peek = function (cb) {
							 | 
						||
| 
								 | 
							
								            offset = 0;
							 | 
						||
| 
								 | 
							
								            saw.nest(function () {
							 | 
						||
| 
								 | 
							
								                cb.call(this, vars.store);
							 | 
						||
| 
								 | 
							
								                this.tap(function () {
							 | 
						||
| 
								 | 
							
								                    offset = null;
							 | 
						||
| 
								 | 
							
								                });
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    var stream = Chainsaw.light(builder);
							 | 
						||
| 
								 | 
							
								    stream.writable = true;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    var buffers = Buffers();
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    stream.write = function (buf) {
							 | 
						||
| 
								 | 
							
								        buffers.push(buf);
							 | 
						||
| 
								 | 
							
								        dispatch();
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    var vars = Vars();
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    var done = false, caughtEnd = false;
							 | 
						||
| 
								 | 
							
								    stream.end = function () {
							 | 
						||
| 
								 | 
							
								        caughtEnd = true;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    stream.pipe = Stream.prototype.pipe;
							 | 
						||
| 
								 | 
							
								    Object.getOwnPropertyNames(EventEmitter.prototype).forEach(function (name) {
							 | 
						||
| 
								 | 
							
								        stream[name] = EventEmitter.prototype[name];
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    return stream;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.parse = function parse (buffer) {
							 | 
						||
| 
								 | 
							
								    var self = words(function (bytes, cb) {
							 | 
						||
| 
								 | 
							
								        return function (name) {
							 | 
						||
| 
								 | 
							
								            if (offset + bytes <= buffer.length) {
							 | 
						||
| 
								 | 
							
								                var buf = buffer.slice(offset, offset + bytes);
							 | 
						||
| 
								 | 
							
								                offset += bytes;
							 | 
						||
| 
								 | 
							
								                vars.set(name, cb(buf));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            else {
							 | 
						||
| 
								 | 
							
								                vars.set(name, null);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            return self;
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    var offset = 0;
							 | 
						||
| 
								 | 
							
								    var vars = Vars();
							 | 
						||
| 
								 | 
							
								    self.vars = vars.store;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    self.tap = function (cb) {
							 | 
						||
| 
								 | 
							
								        cb.call(self, vars.store);
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    self.into = function (key, cb) {
							 | 
						||
| 
								 | 
							
								        if (!vars.get(key)) {
							 | 
						||
| 
								 | 
							
								            vars.set(key, {});
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        var parent = vars;
							 | 
						||
| 
								 | 
							
								        vars = Vars(parent.get(key));
							 | 
						||
| 
								 | 
							
								        cb.call(self, vars.store);
							 | 
						||
| 
								 | 
							
								        vars = parent;
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    self.loop = function (cb) {
							 | 
						||
| 
								 | 
							
								        var end = false;
							 | 
						||
| 
								 | 
							
								        var ender = function () { end = true };
							 | 
						||
| 
								 | 
							
								        while (end === false) {
							 | 
						||
| 
								 | 
							
								            cb.call(self, ender, vars.store);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    self.buffer = function (name, size) {
							 | 
						||
| 
								 | 
							
								        if (typeof size === 'string') {
							 | 
						||
| 
								 | 
							
								            size = vars.get(size);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        var buf = buffer.slice(offset, Math.min(buffer.length, offset + size));
							 | 
						||
| 
								 | 
							
								        offset += size;
							 | 
						||
| 
								 | 
							
								        vars.set(name, buf);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    self.skip = function (bytes) {
							 | 
						||
| 
								 | 
							
								        if (typeof bytes === 'string') {
							 | 
						||
| 
								 | 
							
								            bytes = vars.get(bytes);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        offset += bytes;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    self.scan = function (name, search) {
							 | 
						||
| 
								 | 
							
								        if (typeof search === 'string') {
							 | 
						||
| 
								 | 
							
								            search = new Buffer(search);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        else if (!Buffer.isBuffer(search)) {
							 | 
						||
| 
								 | 
							
								            throw new Error('search must be a Buffer or a string');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        vars.set(name, null);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        // simple but slow string search
							 | 
						||
| 
								 | 
							
								        for (var i = 0; i + offset <= buffer.length - search.length + 1; i++) {
							 | 
						||
| 
								 | 
							
								            for (
							 | 
						||
| 
								 | 
							
								                var j = 0;
							 | 
						||
| 
								 | 
							
								                j < search.length && buffer[offset+i+j] === search[j];
							 | 
						||
| 
								 | 
							
								                j++
							 | 
						||
| 
								 | 
							
								            );
							 | 
						||
| 
								 | 
							
								            if (j === search.length) break;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        vars.set(name, buffer.slice(offset, offset + i));
							 | 
						||
| 
								 | 
							
								        offset += i + search.length;
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    self.peek = function (cb) {
							 | 
						||
| 
								 | 
							
								        var was = offset;
							 | 
						||
| 
								 | 
							
								        cb.call(self, vars.store);
							 | 
						||
| 
								 | 
							
								        offset = was;
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    self.flush = function () {
							 | 
						||
| 
								 | 
							
								        vars.store = {};
							 | 
						||
| 
								 | 
							
								        return self;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    self.eof = function () {
							 | 
						||
| 
								 | 
							
								        return offset >= buffer.length;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    return self;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// convert byte strings to unsigned little endian numbers
							 | 
						||
| 
								 | 
							
								function decodeLEu (bytes) {
							 | 
						||
| 
								 | 
							
								    var acc = 0;
							 | 
						||
| 
								 | 
							
								    for (var i = 0; i < bytes.length; i++) {
							 | 
						||
| 
								 | 
							
								        acc += Math.pow(256,i) * bytes[i];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return acc;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// convert byte strings to unsigned big endian numbers
							 | 
						||
| 
								 | 
							
								function decodeBEu (bytes) {
							 | 
						||
| 
								 | 
							
								    var acc = 0;
							 | 
						||
| 
								 | 
							
								    for (var i = 0; i < bytes.length; i++) {
							 | 
						||
| 
								 | 
							
								        acc += Math.pow(256, bytes.length - i - 1) * bytes[i];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return acc;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// convert byte strings to signed big endian numbers
							 | 
						||
| 
								 | 
							
								function decodeBEs (bytes) {
							 | 
						||
| 
								 | 
							
								    var val = decodeBEu(bytes);
							 | 
						||
| 
								 | 
							
								    if ((bytes[0] & 0x80) == 0x80) {
							 | 
						||
| 
								 | 
							
								        val -= Math.pow(256, bytes.length);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return val;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// convert byte strings to signed little endian numbers
							 | 
						||
| 
								 | 
							
								function decodeLEs (bytes) {
							 | 
						||
| 
								 | 
							
								    var val = decodeLEu(bytes);
							 | 
						||
| 
								 | 
							
								    if ((bytes[bytes.length - 1] & 0x80) == 0x80) {
							 | 
						||
| 
								 | 
							
								        val -= Math.pow(256, bytes.length);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return val;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function words (decode) {
							 | 
						||
| 
								 | 
							
								    var self = {};
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    [ 1, 2, 4, 8 ].forEach(function (bytes) {
							 | 
						||
| 
								 | 
							
								        var bits = bytes * 8;
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self['word' + bits + 'le']
							 | 
						||
| 
								 | 
							
								        = self['word' + bits + 'lu']
							 | 
						||
| 
								 | 
							
								        = decode(bytes, decodeLEu);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self['word' + bits + 'ls']
							 | 
						||
| 
								 | 
							
								        = decode(bytes, decodeLEs);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self['word' + bits + 'be']
							 | 
						||
| 
								 | 
							
								        = self['word' + bits + 'bu']
							 | 
						||
| 
								 | 
							
								        = decode(bytes, decodeBEu);
							 | 
						||
| 
								 | 
							
								        
							 | 
						||
| 
								 | 
							
								        self['word' + bits + 'bs']
							 | 
						||
| 
								 | 
							
								        = decode(bytes, decodeBEs);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    // word8be(n) == word8le(n) for all n
							 | 
						||
| 
								 | 
							
								    self.word8 = self.word8u = self.word8be;
							 | 
						||
| 
								 | 
							
								    self.word8s = self.word8bs;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    return self;
							 | 
						||
| 
								 | 
							
								}
							 |