Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

used decaffeinate to convert coffeescript into javascript #119

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
module.exports = function(grunt) {

grunt.initConfig({
pkg: require('./package'),
coffee: {
src: {
options: {
bare: true,
noHeader: true
},
expand: true,
cwd: 'src',
src: '**/*.coffee',
dest: 'lib',
ext: '.js'
},
index: {
src: 'index.coffee',
dest: 'index.js'
}
},
clean: {
lib: {
src: 'lib'
},
index: {
src: 'index.js'
}
},
coffeelint: {
options: {
indentation: {
level: 'ignore'
},
no_backticks: {
level: 'ignore'
}
},
src: {
src: '<%= coffee.src.cwd %>/<%= coffee.src.src %>'
},
index: {
src: '<%= coffee.index.src %>'
},
test: {
src: 'test/**/*.coffee'
},
tasks: {
src: 'tasks/**/*.coffee'
},
gruntfile: {
src: 'Gruntfile.coffee'
}
},
jsonlint: {
packagejson: {
src: 'package.json'
}
},
watch: {
src: {
files: '<%= coffee.src.cwd %>/<%= coffee.src.src %>',
tasks: ['coffeelint:src', 'test']
},
index: {
files: '<%= coffee.index.src %>',
tasks: ['coffeelint:index', 'test']
},
test: {
files: '<%= coffeelint.test.src %>',
tasks: ['coffeelint:test', 'test']
},
gruntfile: {
files: '<%= coffeelint.gruntfile.src %>',
tasks: ['coffeelint:gruntfile']
},
packagejson: {
files: '<%= jsonlint.packagejson.src %>',
tasks: ['jsonlint:packagejson']
}
},
exec: {
mocha: {
options: [
'--compilers coffee:coffee-script/register',
'--reporter spec',
'--colors',
'--recursive'
],
cmd: './node_modules/.bin/mocha <%= exec.mocha.options.join(" ") %>'
}
},
keycode: {
generate: {
dest: 'src/adb/keycode.coffee'
}
}
});

grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-coffeelint');
grunt.loadNpmTasks('grunt-jsonlint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-notify');
grunt.loadNpmTasks('grunt-exec');
grunt.loadTasks('./tasks');

grunt.registerTask('test', ['jsonlint', 'coffeelint', 'exec:mocha']);
grunt.registerTask('build', ['coffee']);
return grunt.registerTask('default', ['test']);
};
31 changes: 31 additions & 0 deletions bench/sync/pull.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const Bench = require('bench');
const {spawn} = require('child_process');

const Adb = require('../..');

const deviceId = process.env.DEVICE_ID;

module.exports = {
compareCount: 3,
compare: {
"pull /dev/graphics/fb0 using ADB CLI"(done) {
const proc = spawn('adb',
['-s', deviceId, 'pull', '/dev/graphics/fb0', '/dev/null']);
return proc.stdout.on('end', done);
},
"pull /dev/graphics/fb0 using client.pull()"(done) {
const client = Adb.createClient();
return client.pull(deviceId, '/dev/graphics/fb0', function(err, stream) {
stream.resume();
return stream.on('end', done);
});
}
}
};

Bench.runMain();
24 changes: 24 additions & 0 deletions src/adb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const Client = require('./adb/client');
const Keycode = require('./adb/keycode');
const util = require('./adb/util');

class Adb {
static createClient(options) {
if (options == null) { options = {}; }
if (!options.host) { options.host = process.env.ADB_HOST; }
if (!options.port) { options.port = process.env.ADB_PORT; }
return new Client(options);
}
}

Adb.Keycode = Keycode;

Adb.util = util;

module.exports = Adb;
106 changes: 106 additions & 0 deletions src/adb/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS206: Consider reworking classes to avoid initClass
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const Promise = require('bluebird');
const forge = require('node-forge');
const {
BigInteger
} = forge.jsbn;

/*
The stucture of an ADB RSAPublicKey is as follows:

*define RSANUMBYTES 256 // 2048 bit key length
*define RSANUMWORDS (RSANUMBYTES / sizeof(uint32_t))

typedef struct RSAPublicKey {
int len; // Length of n[] in number of uint32_t
uint32_t n0inv; // -1 / n[0] mod 2^32
uint32_t n[RSANUMWORDS]; // modulus as little endian array
uint32_t rr[RSANUMWORDS]; // R^2 as little endian array
int exponent; // 3 or 65537
} RSAPublicKey;

*/
var Auth = (function() {
let RE = undefined;
let readPublicKeyFromStruct = undefined;
Auth = class Auth {
static initClass() {
// coffeelint: disable=max_line_length
RE = /^((?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?)\0?( .*|)\s*$/;
// coffeelint: enable=max_line_length

readPublicKeyFromStruct = function(struct, comment) {
if (!struct.length) { throw new Error("Invalid public key"); }

// Keep track of what we've read already
let offset = 0;

// Get len
const len = struct.readUInt32LE(offset) * 4;
offset += 4;

if (struct.length !== (4 + 4 + len + len + 4)) {
throw new Error("Invalid public key");
}

// Skip n0inv, we don't need it
offset += 4;

// Get n
const n = new Buffer(len);
struct.copy(n, 0, offset, offset + len);
[].reverse.call(n);
offset += len;

// Skip rr, we don't need it
offset += len;

// Get e
const e = struct.readUInt32LE(offset);

if ((e !== 3) && (e !== 65537)) {
throw new Error(`Invalid exponent ${e}, only 3 and 65537 are supported`);
}

// Restore the public key
const key = forge.pki.setRsaPublicKey(
new BigInteger(n.toString('hex'), 16),
new BigInteger(e.toString(), 10)
);

// It will be difficult to retrieve the fingerprint later as it's based
// on the complete struct data, so let's just extend the key with it.
const md = forge.md.md5.create();
md.update(struct.toString('binary'));
key.fingerprint = md.digest().toHex().match(/../g).join(':');

// Expose comment for the same reason
key.comment = comment;

return key;
};
}

static parsePublicKey(buffer) {
return new Promise(function(resolve, reject) {
let match;
if (match = RE.exec(buffer)) {
const struct = new Buffer(match[1], 'base64');
const comment = match[2].trim();
return resolve(readPublicKeyFromStruct(struct, comment));
} else {
return reject(new Error("Unrecognizable public key format"));
}
});
}
};
Auth.initClass();
return Auth;
})();

module.exports = Auth;
Loading