<commit_before>
/*

rest3d-server.js

The MIT License (MIT)

Copyright (c) 2013 Rémi Arnaud - Advanced Micro Devices, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

'use strict';

if (process.env['NODETIME_KEY']) {
	console.log("+=+=+= Starting http://nodetime.com");
	console.log("Key = '"+process.env['NODETIME_KEY']+"'");
	require('nodetime').profile({
    accountKey: process.env['NODETIME_KEY'],
    appName: 'rest3d.fl4re.com node server'
  });
}

var restify = require('restify');
//var connect = require('connect');
var http = require('http');
var utils = require('./src/utils');
var childProcess = require('child_process');
var os= require('os');
require('shelljs/global');

var fs = require('fs');
var path = require('path');
var cache = require('./src/diskcache').Cache;
// fast html scrapping
var request = require('request');
// get content from zip files
var zip = require("zip");

var formidable = require('formidable');

var rmdirSync = require('./src/rmdir');
var copyFileSync = require('./src/cp');

var toJSON = require('./src/tojson');

var FileInfo = require('./src/fileinfo');
var sendFile = require('./src/sendfile');
var handler= require('./src/handler');

var platform = os.type().match(/^Win/) ? 'win' :
				(os.type().match(/^Dar/) ? 'mac' : 'unix');

console.log('host platform=',platform);
var staticPath = path.join(__dirname , '../static');

console.log('static folder=',staticPath);

var httpPort = process.env.OPENSHIFT_NODEJS_PORT ||
                   process.env.HTTP ||
                   8000;
var httpsPort = process.env.HTTPS || 443;
var ip_address = process.env.OPENSHIFT_NODEJS_IP || null;
var listenToPort = httpPort;

// see where collada2gltf is located
var openshift = process.env.OPENSHIFT_DATA_DIR;
var collada2gltf = 'collada2gltf';
if (openshift)
    collada2gltf = openshift + 'bin/collada2gltf-latest';
if (process.env.GLTF_BIN_PATH)
    collada2gltf = process.env.GLTF_BIN_PATH+'/collada2gltf';

// find out if we are running http or https
// if https, create two servers, the http server only does redirect to https

var params = {name: 'rest3d'};

if (fs.existsSync('./server.pem') && fs.existsSync('./server.key')){
	console.log('found https certficates');
	params.key = fs.readFileSync('./server.key');
	params.certificate = fs.readFileSync('./server.pem');
	listenToPort = httpsPort;
};

var server = module.exports.server = restify.createServer(params);

if (params.key) {
  var http_server = restify.createServer();
  http_server.get(/.*/,function(req,res,next) {
    // Assume https port is on the default port
    var redirect = "https://" + req.headers.host.replace (/(.*):.*/, '$1') +  req.url;
  	res.writeHead(302, {'Location': redirect});

    //console.log('**** https redirect to '+redirect)
    res.end();
    next();
	});
	http_server.listen( httpPort, ip_address);
}

rmdirSync('tmp');
rmdirSync('cache');
rmdirSync('upload');

fs.mkdirSync('tmp');
fs.mkdirSync('upload');
fs.mkdirSync('cache');

fs.chmodSync('tmp', '777');
fs.chmodSync('upload', '777');
fs.chmodSync('cache', '777');

//fs.mkdirSync('upload/thumbnail');

server.use(restify.acceptParser(server.acceptable));
//server.use(restify.authorizationParser());
server.use(restify.dateParser());
server.use(restify.queryParser());
//server.use(restify.bodyParser()); -> use formidable instead
server.use(restify.gzipResponse());
restify.defaultResponseHeaders = false;

var session=require('./src/session')();
server.sessionManager = session;
server.use(session.sessionManager);

// include routes
require('./src/warehouse')(server);
require('./src/3dvia')(server);
require('./src/upload')(server);

require('./src/basex')(server);

// create diskcache (no mem caching, no gzip)
server.diskcache = new cache('cache',true,false,false);

function unknownMethodHandler(req, res) {
	console.log('unkownMethodHandler method='+req.method.toLowerCase());
  if (req.method.toLowerCase() === 'options') {
    var allowHeaders = ['Accept', 'Accept-Version', 'Content-Type', 'Api-Version'];

    if (res.methods.indexOf('OPTIONS') === -1) res.methods.push('OPTIONS');

    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Headers', allowHeaders.join(', '));
    res.header('Access-Control-Allow-Methods', res.methods.join(', '));
    res.header('Access-Control-Allow-Origin', req.headers.origin);

    return res.send(204);
  }
  else
    return res.send(new restify.MethodNotAllowedError());
}

server.on('MethodNotAllowed', unknownMethodHandler);
/*
server.use(restify.throttle({
  burst: 100,
  rate: 50,
  ip: true,
  overrides: {
    '192.168.1.1': {
      rate: 0,        // unlimited
      burst: 0
    }
  }
}));
*/
//server.use(restify.conditionalRequest());

// rest3d API

// convert

server.post(/^\/rest3d\/convert.*/,function(req,res,next){
	 console.log('post -> convert');

	 var form = new formidable.IncomingForm(),
         url = '',
         params = {};

   var h = new handler(req,res, next);

     form.on('field', function (name, data) {
     	params[name] = data;
     }).on('error', function (e) {
     	h.handleError(e);
     }).on('end', function(){//
     	console.log(params);
     	console.log('now converting collada');
     	if (!params.name && !params.path || !params.name.toLowerCase().endsWith('dae')) {
     		h.handleError({error: 'invalid file '+params.name+' in convert'});
     		return;
     	}
     	if(params.hasOwnProperty("path")){
     		// new API, path specified in the params of the request in order to convert the right file.
     		var output_dir = params.path.split('/');
     		output_dir[output_dir.length-2] = output_dir[output_dir.length-2] + '_gltf';
     		output_dir[output_dir.length-1] = output_dir[output_dir.length-1].replace('.dae','.json').replace('.DAE','.json');
     		var output_path=output_dir[0];
     		for(var i =1;i<output_dir.length;i++){
     			output_path = output_path + "/" +output_dir[i];
     	// 		 fs.readdirSync("upload", function (err, list) {
      //           list.forEach(function (name) {
      //           	console.log(name);
		    //     });
		    // });
     			// console.log(output_path,fs.existsSync(output_path+"/"));
     			if(i!==output_dir.length-1){
     				fs.exists(output_path,function(res){
     					if(!res){
     							console.log("create folder "+output_path)
     				fs.mkdirSync(output_path);
     					}
     				})

     			}
     		}
	     	console.log(collada2gltf+" -p -f \"" + params.path+"\" -o \""+output_path+"\"");
	     	var cmd = collada2gltf+" -p -f \"" + params.path+"\" -o \""+output_path+"\"";
	     	var input_dir = params.path.replace(/[^\/]*$/,'');
	     	output_dir = output_path.replace(/[^\/]*$/,'');
     	}
     	else{
     		// let's considered the model is stocked under rest3d/upload/ repository in case any path isn't specified
     		// the conversion will create a folder for stocking the gltf file
     		// CODE NOT TESTED, maybe get some conflicts for copying all textures to the gltf folder.
     		console.log("PART NOT TESTED YET")
	     	var output_dir = params.name.split('\.')[0]+'_gltf';
	     	var output_file = params.name.replace('.dae','.json');
	     	fs.mkdirSync('upload/'+output_dir);
	     	var output_path = 'upload/'+output_dir+'/'+output_file;
	     	var cmd = collada2gltf+" -p -f \"upload/" + params.name+"\" -o \""+output_path+"\"";
	     	 var input_dir = "upload/";
	     	output_dir = output_path.replace(/[^\/]*$/,'');
     }
     	console.log('exec '+cmd);
     	// todo -> manage progress !!!
		var outputC2J;
     	var codeC2J;
     	// todo -> manage progress !!!
		var ls = childProcess.exec(cmd, function (error, stdout, stderr) {
		   if (error) {
		     console.log(error.stack);
		     //console.log('Error code: '+error.code);
		     //console.log('Signal received: '+error.signal);

			 h.handleError({"code":error.code, "message": stderr});

		   }
		   console.log('Child Process STDOUT: '+stdout);
		   console.log('Child Process STDERR: '+stderr);
		 });
		 ls.on('exit', function (code, output) {
		  console.log('Child process exited with exit code '+code);
		  if (code !== 0) {
				h.handleError({errorCode:code, message:'Child process exited with exit code '});
				return;
			}
			codeC2J= code;
			outputC2J = output;
			console.log('Exit code:', code);
	  		console.log('Program output:', output);

			// // hack, copy all images in the output_dir, so the viewer will work
		    fs.readdir(input_dir, function (err, list) {
                list.forEach(function (name) {
                	if (!name.endsWith('.json')||!name.endsWith('.dae'))
                	{
                		copyFileSync(input_dir+name, output_dir+name);
                		console.log(input_dir+name+'  TO  '+output_dir+name);
                	}
		        });
		    });
		    // end hack
			var files = [];
			fs.readdir(output_dir, function (err, list) {
                list.forEach(function (name) {
		            var stats = fs.statSync(output_dir+name),
		                fileInfo;
		            if (stats.isFile() && name[0] !== '.') {
		                fileInfo = new FileInfo({
		                    name: output_dir+name,
		                    size: stats.size
		                });
		                //fileInfo.initUrls(req);
		                files.push(fileInfo);
		            }
		        });
		        var timeout = function() {
                    	rmdirSync(output_dir);
                    	console.log('timeout !! '+output_dir+' was deleted');
                    }
                    setTimeout(function() { timeout()},5 * 60 * 1000);
		        h.handleResult({files: files, code:codeC2J, output:outputC2J});
		    });
	     });
	     });
    form.parse(req);
});

// static server
server.get(/^\/.*/, function (req, res, next) {

	// parse out parameters from url
	var filename = req.url.split('\?')[0];
	var p=path.resolve(staticPath + filename);

	console.log('http get path='+filename);

	sendFile(req,res,p);
	return next();
});

// clean exit
function sigterm_handler() {
    console.warn('Kaboom Baby!');
    process.exit(0);
}

process.on('SIGTERM', sigterm_handler);

// run server
server.listen( listenToPort, ip_address);
console.log ('rest3d server running on port '+listenToPort);

<commit_msg>Touch<commit_after>
/*

rest3d-server.js

The MIT License (MIT)

Copyright (c) 2013 Rémi Arnaud - Advanced Micro Devices, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

'use strict';

if (process.env['NODETIME_KEY']) {
	console.log("+=+=+= Starting http://nodetime.com");
	console.log("Key = '"+process.env['NODETIME_KEY']+"'");
	require('nodetime').profile({
    accountKey: process.env['NODETIME_KEY'],
    appName: 'rest3d.fl4re.com node server'
  });
}

var restify = require('restify');
//var connect = require('connect');
var http = require('http');
var utils = require('./src/utils');
var childProcess = require('child_process');
var os= require('os');
require('shelljs/global');

var fs = require('fs');
var path = require('path');
var cache = require('./src/diskcache').Cache;
// fast html scrapping
var request = require('request');
// get content from zip files
var zip = require("zip");

var formidable = require('formidable');

var rmdirSync = require('./src/rmdir');
var copyFileSync = require('./src/cp');

var toJSON = require('./src/tojson');

var FileInfo = require('./src/fileinfo');
var sendFile = require('./src/sendfile');
var handler= require('./src/handler');

var platform = os.type().match(/^Win/) ? 'win' :
				(os.type().match(/^Dar/) ? 'mac' : 'unix');

console.log('host platform=',platform);
var staticPath = path.join(__dirname , '../static');

console.log('static folder=',staticPath);

var httpPort = process.env.OPENSHIFT_NODEJS_PORT ||
                   process.env.HTTP ||
                   8000;
var httpsPort = process.env.HTTPS || 443;
var ip_address = process.env.OPENSHIFT_NODEJS_IP || null;
var listenToPort = httpPort;

// see where collada2gltf is located
var openshift = process.env.OPENSHIFT_DATA_DIR;
var collada2gltf = 'collada2gltf';
if (openshift)
    collada2gltf = openshift + 'bin/collada2gltf-latest';
if (process.env.GLTF_BIN_PATH)
    collada2gltf = process.env.GLTF_BIN_PATH+'/collada2gltf';

// find out if we are running http or https
// if https, create two servers, the http server only does redirect to https

var params = {name: 'rest3d'};

if (fs.existsSync('./server.pem') && fs.existsSync('./server.key')){
	console.log('found https certficates');
	params.key = fs.readFileSync('./server.key');
	params.certificate = fs.readFileSync('./server.pem');
	listenToPort = httpsPort;
};

var server = module.exports.server = restify.createServer(params);

if (params.key) {
  var http_server = restify.createServer();
  http_server.get(/.*/,function(req,res,next) {
    // Assume https port is on the default port
    var redirect = "https://" + req.headers.host.replace (/(.*):.*/, '$1') +  req.url;
  	res.writeHead(302, {'Location': redirect});

    //console.log('**** https redirect to '+redirect)
    res.end();
    next();
	});
	http_server.listen( httpPort, ip_address);
}

rmdirSync('tmp');
rmdirSync('cache');
rmdirSync('upload');

fs.mkdirSync('tmp');
fs.mkdirSync('upload');
fs.mkdirSync('cache');

fs.chmodSync('tmp', '777');
fs.chmodSync('upload', '777');
fs.chmodSync('cache', '777');

//fs.mkdirSync('upload/thumbnail');

server.use(restify.acceptParser(server.acceptable));
//server.use(restify.authorizationParser());
server.use(restify.dateParser());
server.use(restify.queryParser());
//server.use(restify.bodyParser()); -> use formidable instead
server.use(restify.gzipResponse());
restify.defaultResponseHeaders = false;

var session=require('./src/session')();
server.sessionManager = session;
server.use(session.sessionManager);

// include routes
require('./src/warehouse')(server);
require('./src/3dvia')(server);
require('./src/upload')(server);

require('./src/basex')(server);

// create diskcache (no mem caching, no gzip)
server.diskcache = new cache('cache',true,false,false);

function unknownMethodHandler(req, res) {
	console.log('unkownMethodHandler method='+req.method.toLowerCase());
  if (req.method.toLowerCase() === 'options') {
    var allowHeaders = ['Accept', 'Accept-Version', 'Content-Type', 'Api-Version'];

    if (res.methods.indexOf('OPTIONS') === -1) res.methods.push('OPTIONS');

    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Headers', allowHeaders.join(', '));
    res.header('Access-Control-Allow-Methods', res.methods.join(', '));
    res.header('Access-Control-Allow-Origin', req.headers.origin);

    return res.send(204);
  }
  else
    return res.send(new restify.MethodNotAllowedError());
}

server.on('MethodNotAllowed', unknownMethodHandler);
/*
server.use(restify.throttle({
  burst: 100,
  rate: 50,
  ip: true,
  overrides: {
    '192.168.1.1': {
      rate: 0,        // unlimited
      burst: 0
    }
  }
}));
*/
//server.use(restify.conditionalRequest());

// rest3d API

// convert

server.post(/^\/rest3d\/convert.*/,function(req,res,next){
	 console.log('post -> convert');

	 var form = new formidable.IncomingForm(),
         url = '',
         params = {};

   var h = new handler(req,res, next);

     form.on('field', function (name, data) {
     	params[name] = data;
     }).on('error', function (e) {
     	h.handleError(e);
     }).on('end', function(){//
     	console.log(params);
     	console.log('now converting collada');
     	if (!params.name && !params.path || !params.name.toLowerCase().endsWith('dae')) {
     		h.handleError({error: 'invalid file '+params.name+' in convert'});
     		return;
     	}
     	if(params.hasOwnProperty("path")){
     		// new API, path specified in the params of the request in order to convert the right file.
     		var output_dir = params.path.split('/');
     		output_dir[output_dir.length-2] = output_dir[output_dir.length-2] + '_gltf';
     		output_dir[output_dir.length-1] = output_dir[output_dir.length-1].replace('.dae','.json').replace('.DAE','.json');
     		var output_path=output_dir[0];
     		console.log(output_dir);
     		for(var i =1;i<output_dir.length;i++){
     			output_path = output_path + "/" +output_dir[i];
     	// 		 fs.readdirSync("upload", function (err, list) {
      //           list.forEach(function (name) {
      //           	console.log(name);
		    //     });
		    // });
     			// console.log(output_path,fs.existsSync(output_path+"/"));
     			if(i!==output_dir.length-1){
     				console.log(output_dir[i]);
     				fs.exists(output_path,function(res){
     					if(!res){
     							console.log("create folder "+output_path)
     				fs.mkdirSync(output_path);
     					}
     						     	var cmd = collada2gltf+" -p -f \"" + params.path+"\" -o \""+output_path+"\"";
	     	var input_dir = params.path.replace(/[^\/]*$/,'');
	     	output_dir = output_path.replace(/[^\/]*$/,'');
     				})

     			}
     		}
	     	console.log(collada2gltf+" -p -f \"" + params.path+"\" -o \""+output_path+"\"");

     	}
     	else{
     		// let's considered the model is stocked under rest3d/upload/ repository in case any path isn't specified
     		// the conversion will create a folder for stocking the gltf file
     		// CODE NOT TESTED, maybe get some conflicts for copying all textures to the gltf folder.
     		console.log("PART NOT TESTED YET")
	     	var output_dir = params.name.split('\.')[0]+'_gltf';
	     	var output_file = params.name.replace('.dae','.json');
	     	fs.mkdirSync('upload/'+output_dir);
	     	var output_path = 'upload/'+output_dir+'/'+output_file;
	     	var cmd = collada2gltf+" -p -f \"upload/" + params.name+"\" -o \""+output_path+"\"";
	     	 var input_dir = "upload/";
	     	output_dir = output_path.replace(/[^\/]*$/,'');
     }
     	console.log('exec '+cmd);
     	// todo -> manage progress !!!
		var outputC2J;
     	var codeC2J;
     	// todo -> manage progress !!!
		var ls = childProcess.exec(cmd, function (error, stdout, stderr) {
		   if (error) {
		     console.log(error.stack);
		     //console.log('Error code: '+error.code);
		     //console.log('Signal received: '+error.signal);

			 h.handleError({"code":error.code, "message": stderr});

		   }
		   console.log('Child Process STDOUT: '+stdout);
		   console.log('Child Process STDERR: '+stderr);
		 });
		 ls.on('exit', function (code, output) {
		  console.log('Child process exited with exit code '+code);
		  if (code !== 0) {
				h.handleError({errorCode:code, message:'Child process exited with exit code '});
				return;
			}
			codeC2J= code;
			outputC2J = output;
			console.log('Exit code:', code);
	  		console.log('Program output:', output);

			// // hack, copy all images in the output_dir, so the viewer will work
		    fs.readdir(input_dir, function (err, list) {
                list.forEach(function (name) {
                	if (!name.endsWith('.json')||!name.endsWith('.dae'))
                	{
                		copyFileSync(input_dir+name, output_dir+name);
                		console.log(input_dir+name+'  TO  '+output_dir+name);
                	}
		        });
		    });
		    // end hack
			var files = [];
			fs.readdir(output_dir, function (err, list) {
                list.forEach(function (name) {
		            var stats = fs.statSync(output_dir+name),
		                fileInfo;
		            if (stats.isFile() && name[0] !== '.') {
		                fileInfo = new FileInfo({
		                    name: output_dir+name,
		                    size: stats.size
		                });
		                //fileInfo.initUrls(req);
		                files.push(fileInfo);
		            }
		        });
		        var timeout = function() {
                    	rmdirSync(output_dir);
                    	console.log('timeout !! '+output_dir+' was deleted');
                    }
                    setTimeout(function() { timeout()},5 * 60 * 1000);
		        h.handleResult({files: files, code:codeC2J, output:outputC2J});
		    });
	     });
	     });
    form.parse(req);
});

// static server
server.get(/^\/.*/, function (req, res, next) {

	// parse out parameters from url
	var filename = req.url.split('\?')[0];
	var p=path.resolve(staticPath + filename);

	console.log('http get path='+filename);

	sendFile(req,res,p);
	return next();
});

// clean exit
function sigterm_handler() {
    console.warn('Kaboom Baby!');
    process.exit(0);
}

process.on('SIGTERM', sigterm_handler);

// run server
server.listen( listenToPort, ip_address);
console.log ('rest3d server running on port '+listenToPort);

<|endoftext|>


<commit_before>var express = require('express');
var models = require('../db/models.js');
var util = require('../core/utilities.js');
var router = express.Router();

router.get('/', function (req, res) {
  util.log('RECEIVED a GET request', req.query);

  models.retrieve(req.query, function(msg) {
    if (Array.isArray(msg)) {
      util.log('SENT message array to user', msg);
      res.send(msg);
    } else {
      util.log('SENT error code to user', msg);
      res.send(msg);
    }
  });
});

router.post('/', function(req, res) {
  util.log('RECEIVED a POST request', req.body);

  models.insert(req.body, function(msg) {
    util.log('SENT success code to user', msg);

    res.status(201).send();
  });
});

router.post('/upvote', function (req, res) {
  util.log('RECEIVED upvote request', req.body);
  res.status(200).send();
});

router.post('/comment', function (req, res) {
  util.log("RECEIVED comment", req.body)
  res.status(200).send();
});

module.exports = router;
<commit_msg>User can upvote messages<commit_after>var express = require('express');
var models = require('../db/models.js');
var util = require('../core/utilities.js');
var router = express.Router();

router.get('/', function (req, res) {
  util.log('RECEIVED a GET request', req.query);

  models.retrieve(req.query, function(msg) {
    if (Array.isArray(msg)) {
      util.log('SENT message array to user', msg);
      res.send(msg);
    } else {
      util.log('SENT error code to user', msg);
      res.send(msg);
    }
  });
});

router.post('/', function(req, res) {
  util.log('RECEIVED a POST request', req.body);

  models.insert(req.body, function(msg) {
    util.log('SENT success code to user', msg);

    res.status(201).send();
  });
});

router.post('/upvote', function (req, res) {
  util.log('RECEIVED upvote request', req.body);
  models.createVote(+req.body.messageId, req.body.userToken);
  res.status(200).send();
});

router.post('/comment', function (req, res) {
  util.log("RECEIVED comment", req.body)
  res.status(200).send();
});

module.exports = router;
<|endoftext|>


<commit_before>const express = require('express')
const bodyParser = require('body-parser');
const app = express();
const mongoose = require('mongoose');
const dbController = require('./controllers/dbController.js')
const foodpairingController = require('./controllers/foodpairingController.js');
const recipesController = require('./controllers/recipesController.js');
const cameraController = require('./controllers/cameraController.js');

// connect to local database
// mongoose.connect('mongodb://localhost/snacktimetest');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  console.log('we are connected!')
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/foodPairing', foodpairingController.getFoodpairing);
app.post('/recipeList', recipesController.getRecipeList);
app.post('/recipeSelector', recipesController.getRecipe);
app.post('/compareRecipes', recipesController.compareRecipes);
app.post('/getFoodID', foodpairingController.getFoodID);
app.post('/getMultipleFoodpairings', foodpairingController.getMultipleFoodpairings);

// find user in db and send back to cilent
app.get('/database', function(req, res){
  dbController.findUserId(req.query.ID, function(err, data) {
    if(err) {
  		console.log(err);
  }
  res.send(data);
  })
});

// created a new user because no user is find
app.post('/database', function(req, res){
  var newUser = {
    'name': 'testing',
    'FacebookUserID': req.body.id,
    'InstagramToken': [],
    'FavoriteRecipe': [],
  }
  dbController.insertNewUser(newUser, function(err, data){
    if(err) {
      console.log(err);
    }
    console.log('server created user', data)
    res.send(data)
  })
});

// create a recipe schema

// send userid from store
// then use userModel findoneandUpdate to save recipe

app.post('/AddRecipe', function(req, res){
  var facebookuserid = req.body.facebookuserid
  var saveRecipe = {
    "name": req.body.name,
    "id": req.body.id,
    "image": req.body.image,
    "analyzedInstructions": req.body.analyzedInstructions
  }
  dbController.createRecipe(saveRecipe, function(err, newRecipe){
    if(err) {
      console.log(err);
    }
    var newR = newRecipe;
    dbController.findUserId(facebookuserid, function(err, user) {
      if(err) {
    		console.log(err);
    	}
      user[0].FavoriteRecipe.push(newR)
      user[0].save(function(err, user, num){
        if(err) {
          console.log(err)
        }
        console.log('user', user)
      });
    })
  })
})

module.exports = app;
<commit_msg>db routes<commit_after>const express = require('express')
const bodyParser = require('body-parser');
const app = express();
const mongoose = require('mongoose');
const dbController = require('./controllers/dbController.js')
const foodpairingController = require('./controllers/foodpairingController.js');
const recipesController = require('./controllers/recipesController.js');
const cameraController = require('./controllers/cameraController.js');

// connect to local database
// mongoose.connect('mongodb://localhost/snacktimetest');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  console.log('we are connected!')
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/foodPairing', foodpairingController.getFoodpairing);
app.post('/recipeList', recipesController.getRecipeList);
app.post('/recipeSelector', recipesController.getRecipe);
app.post('/compareRecipes', recipesController.compareRecipes);
app.post('/getFoodID', foodpairingController.getFoodID);
app.post('/getMultipleFoodpairings', foodpairingController.getMultipleFoodpairings);

// find user in db and send back to cilent
app.get('/database', function(req, res){
  dbController.findUserId(req.query.ID, function(err, data) {
    if(err) {
  		console.log(err);
  }
  res.send(data);
  })
});

// created a new user because no user is find
app.post('/database', function(req, res){
  var newUser = {
    'name': 'testing',
    'FacebookUserID': req.body.id,
    'InstagramToken': [],
    'FavoriteRecipe': [],
  }
  dbController.insertNewUser(newUser, function(err, data){
    if(err) {
      console.log(err);
    }
    console.log('server created user', data)
    res.send(data)
  })
});

// create a recipe schema

// send userid from store
// then use userModel findoneandUpdate to save recipe
app.post('/AddRecipe', function(req, res){
  var facebookuserid = req.body.facebookuserid
  var saveRecipe = {
    "name": req.body.name,
    "id": req.body.id,
    "image": req.body.image,
    "analyzedInstructions": req.body.analyzedInstructions
  }
  dbController.createRecipe(saveRecipe, function(err, newRecipe){
    if(err) {
      console.log(err);
    }
    var newR = newRecipe;
    dbController.findUserId(facebookuserid, function(err, user) {
      if(err) {
    		console.log(err);
    	}
      user[0].FavoriteRecipe.push(newR)
      user[0].save(function(err, user, num){
        if(err) {
          console.log(err)
        }
        console.log('user', user)
      });
    })
  })
})

module.exports = app;
<|endoftext|>


<commit_before>const express = require('express')
const bodyParser = require('body-parser');
const app = express();
const foodpairingController = require('./controllers/foodpairingController.js');
const recipesController = require('./controllers/recipesController.js');
const cameraController = require('./controllers/cameraController.js');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/foodPairing', foodpairingController.getFoodpairing);
app.post('/recipeList', recipesController.getRecipeList);
app.post('/recipeSelector', recipesController.getRecipe);
app.post('/compareRecipes', recipesController.compareRecipes);
app.post('/getFoodID', foodpairingController.getFoodID);
app.post('/getMultipleFoodpairings', foodpairingController.getMultipleFoodpairings);

module.exports = app;<commit_msg>db stuff<commit_after>const express = require('express')
const bodyParser = require('body-parser');
const app = express();
const mongoose = require('mongoose');
const dbController = require('./controllers/dbController.js')
const foodpairingController = require('./controllers/foodpairingController.js');
const recipesController = require('./controllers/recipesController.js');
const cameraController = require('./controllers/cameraController.js');

// connect to local database
// mongoose.connect('mongodb://localhost/snacktimetest');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
  console.log('we are connected!')
});

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/foodPairing', foodpairingController.getFoodpairing);
app.post('/recipeList', recipesController.getRecipeList);
app.post('/recipeSelector', recipesController.getRecipe);
app.post('/compareRecipes', recipesController.compareRecipes);
app.post('/getFoodID', foodpairingController.getFoodID);
app.post('/getMultipleFoodpairings', foodpairingController.getMultipleFoodpairings);

// find user in db and send back to cilent
app.get('/database', function(req, res){
  dbController.findUserId(req.query.ID, function(err, data) {
    if(err) {
  		console.log(err);
  	}
  console.log('server sending back data', data)
  res.send(data);
  })
});

// created a new user because no user is find
app.post('/database', function(req, res){
  var newUser = {
    'name': 'testing',
    'FacebookUserID': req.body.id,
    'InstagramToken': [],
    'FavoriteRecipe': [],
  }
  dbController.insertNewUser(newUser, function(err, data){
    if(err) {
      console.log(err);
    }
    console.log('server created user', data)
    res.send(data)
  })
});

// create a recipe schema

app.post('/AddRecipe', function(req, res){
  // var saveRecipe = {
  //   "name": req.body.name,
  //   "id": req.body.id,
  //   "image": req.body.image,
  //   "analyzedInstructions": req.body.analyzedInstructions
  // }
  // dbController.createRecipe(saveRecipe, function(err, newRecipe){
  //   if(err) {
  //     console.log(err);
  //   }
  //   console.log('server create recipe', newRecipe)
  //   res.send(newRecipe)
  // })
  res.send('hi')
})

module.exports = app;
<|endoftext|>


<commit_before>var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');

function helloRoute() {
  var hello = new express.Router();
  hello.use(cors());
  hello.use(bodyParser());

  // GET REST endpoint - query params may or may not be populated
  hello.get('/', function(req, res) {
    console.log(new Date(), 'In hello route GET / req.query=', req.query);
    var world = req.query && req.query.hello ? req.query.hello : 'World';

    res.json({
                status: "warn",
                summary: "This is a health result similar in format to the Aer Lingus health endpoint format",
                details: [
                {
                  description: "Test booking confirmation endpoint",
                  test_status: "ok",
                  result: "Successfully loaded booking confirmation endpoint in 56ms",
                  runtime: 56
                }
              ]
            });
  });

  hello.post('/', function(req, res) {
    console.log(new Date(), 'In hello route POST / req.body=', req.body);
  });

  return hello;
}

module.exports = helloRoute;
<commit_msg>removed hello.js<commit_after><|endoftext|>


<commit_before>'use strict'

var fs = require('fs')
var child_process = require('child_process')
var through = require('through2')
var split = require('split')
var elasticsearch = require('elasticsearch')
var htmlProcess = require('./html_process')
var CONF = require('../config.js')

function batchify(size) {
  let queue = []

  return through.obj(function(data, enc, cb) {
    queue.push(data)

    if (queue.length < size) {
      // Return immediately
      cb()
    } else {
      // Yield a batch
      let batch = queue
      queue = []
      this.push(batch)
      cb()
    }
  }, function(cb) {
    // Flush on end
    let batch = queue
    queue = []
    this.push(batch)
    cb()
  })
}

function jsonsToElasticBatch() {
  return through.obj((jsons, enc, cb) => {
    let batch = []
    jsons.forEach(json => {
      let typeParts = json.type.split(/\//g)
      let type = typeParts[typeParts.length - 1]

      batch.push({ index: {
        _type: type,
        _id: json.id
      } })
      batch.push(json)
    })
    cb(null, batch)
  })
}

function elasticSink() {
  let es = new elasticsearch.Client({
    host: CONF.elasticsearchUrl,
    log: 'info'
  })

  return through.obj((data, enc, cb) => {
    console.log(`Indexing ${data.length / 2} documents`)
    es.bulk({
      index: CONF.elasticsearchOparlIndex,
      body: data
    }, (err, res) => cb(err))
  })
}

function pdftohtml(pdfPath, htmlPath, cb) {
  child_process.exec(`pdftohtml -i -s ${pdfPath}`, (err, stdout, stderr) => {
    if (err) return cb(err)

    stderr = stderr.toString()
    if (stderr) return cb(new Error(stderr))

    let basePath = pdfPath.replace(/\.pdf$/i, "")
    fs.unlink(`${basePath}s.html`, err => {
      // Ignore this err
      fs.rename(`${basePath}-html.html`, htmlPath, err => {
        cb(err)
      })
    })
  })
}

function pdftotext(pdfPath, cb) {
  child_process.exec(`pdftotext -enc UTF-8 -layout ${pdfPath}`, (err, stdout, stderr) => {
    if (err) return cb(err)

    stderr = stderr.toString()
    if (stderr) return cb(new Error(stderr))

    let txtPath = pdfPath.replace(/\.pdf$/i, ".txt")
    cb(null, txtPath)
  })
}

function htmlEscape(text) {
  return text
    .replace(/&/g, "&")
    .replace(/</g, "<")
    .replace(/>/g, ">")
}

function writeHtml(text, htmlPath, cb) {
  let html = fs.createWriteStream(htmlPath)
  html.write(`<!DOCTYPE html>
<html>
  <head>
    <style>
      body { font-family: serif; }
      .page { padding: 2em 4em; }
      p { margin: 0; white-space: pre; }
    </style>
  </head>
  <body>
`)

  // Remove superfluous page breaks:
  text = text.replace(/\f\s*$/, "")

  for(var pageText of text.split(/\f/g)) {
    html.write(`<div class="page">`)
    for(var lineText of pageText.split(/\n/g)) {
      html.write(`<p>${htmlEscape(lineText)}</p>\n`)
    }
    html.write(`</div>\n`)
  }

  html.write(`  </body>
</html>
`)
  cb()
}

function htmlToText(htmlPath, cb) {
  let pages = []

  let proc = htmlProcess()
  proc.on('error', err => {
    cb(err)
    cb = () => {}
  })

  fs.createReadStream(htmlPath)
    .pipe(proc)
    .pipe(through.obj((page, enc, cb) => {
      pages.push(page.contents.map(
        block =>
          block.contents.map(getFragmentText).join("")
      ).join("\n"))
      cb()
    }, flushCb => {
      flushCb()
      cb(null, pages.join("\n\n\n"))
    }))
}

function getFragmentText(frag) {
  if (typeof frag === 'string') {
    return frag
  } else if (frag.contents) {
    return frag.contents.map(getFragmentText).join("")
  } else {
    return ""
  }
}

/*** Main pipeline ***/

child_process.spawn("/usr/bin/env", ["find", CONF.scrapeData, "-name", "*.json", "-type", "f"]).stdout
  .pipe(split())
  .pipe(through.obj((line, enc, cb) => {
    cb(null, line.toString('utf8'))
  }))
  .pipe(through.obj((path, enc, cb) => {
    if (!path) return cb()

    fs.readFile(path, (err, data) => {
      cb(err, {
        path: path,
        data: data
      })
    })
  }))
  .pipe(through.obj((data, enc, cb) => {
    let json = JSON.parse(data.data)
    cb(null, {
      path: data.path,
      json: json
    })
  }))
  .pipe(through.obj((data, enc, cb) => {
    // pdftohtml for Files
    if (/\/File$/.test(data.json.type)) {
      let pdfPath = data.path.replace(/\.json$/, ".pdf")
      let htmlPath = pdfPath.replace(/\.pdf$/i, ".html")
      fs.access(htmlPath, err => {
        if (!err) {
          // .html already exists, skip
          data.htmlPath = htmlPath
          return cb(null, data)
        }

        fs.access(pdfPath, err => {
          if (err) {
            // Can't access .pdf, ignore
            return cb(null, data)
          }

          let t1 = Date.now()
          pdftohtml(pdfPath, htmlPath, err => {
            if (err) {
              console.log("pdftohtml error: " + err.message)
              return cb(null, data)
            }

            let t2 = Date.now()
            console.log(`pdftohtml [${t2 - t1}ms] ${pdfPath}`)

            data.htmlPath = htmlPath
            cb(null, data)
          })
        })
      })
    } else {
      // Pass through non-Files
      cb(null, data)
    }
  }))
  .pipe(through.obj((data, enc, cb) => {
    // extract text from pdftohtml result
    if (data.htmlPath) {
      htmlToText(data.htmlPath, (err, text) => {
        if (err) {
          console.log("htmlToText error: " + err.message)
          return cb(null, data)
        }

        data.json.text = text
        cb(err, data)
      })
    } else {
      cb(null, data)
    }
  }))
  .pipe(through.obj((data, enc, cb) => {
      if (/\/File$/.test(data.json.type) &&
          (!data.json.text ||
           (data.json.text && !/\S/.test(data.json.text)))) {
        // No characters in text? Fixup with pdftotext:

        let pdfPath = data.path.replace(/\.json$/, ".pdf")
        let t1 = Date.now()
        pdftotext(pdfPath, (err, txtPath) => {
          if (err) return cb(err)

          let t2 = Date.now()
          console.log(`pdftotext [${t2 - t1}ms] ${pdfPath}`)

          fs.readFile(txtPath, {
            encoding: 'utf8'
          }, (err, text) => {
            if (err) return cb(err)

            // Keep for indexing
            data.json.text = text.replace(/\f/g, "\n")
            // Generate processHtml-compatible HTML
            let htmlPath = data.path.replace(/\.json$/, ".html")
            writeHtml(text, htmlPath, err => cb(err, data))
          })
        })
      } else {
        cb(null, data)
      }
  }))
  .pipe(through.obj((data, enc, cb) => {
    // Actually, we only send the JSON to ES, not the paths
    cb(null, data.json)
  }))
  .pipe(batchify(64))
  .pipe(jsonsToElasticBatch())
  .pipe(elasticSink())
<commit_msg>server es_upload: gracefully catch pdftotext errors<commit_after>'use strict'

var fs = require('fs')
var child_process = require('child_process')
var through = require('through2')
var split = require('split')
var elasticsearch = require('elasticsearch')
var htmlProcess = require('./html_process')
var CONF = require('../config.js')

function batchify(size) {
  let queue = []

  return through.obj(function(data, enc, cb) {
    queue.push(data)

    if (queue.length < size) {
      // Return immediately
      cb()
    } else {
      // Yield a batch
      let batch = queue
      queue = []
      this.push(batch)
      cb()
    }
  }, function(cb) {
    // Flush on end
    let batch = queue
    queue = []
    this.push(batch)
    cb()
  })
}

function jsonsToElasticBatch() {
  return through.obj((jsons, enc, cb) => {
    let batch = []
    jsons.forEach(json => {
      let typeParts = json.type.split(/\//g)
      let type = typeParts[typeParts.length - 1]

      batch.push({ index: {
        _type: type,
        _id: json.id
      } })
      batch.push(json)
    })
    cb(null, batch)
  })
}

function elasticSink() {
  let es = new elasticsearch.Client({
    host: CONF.elasticsearchUrl,
    log: 'info'
  })

  return through.obj((data, enc, cb) => {
    console.log(`Indexing ${data.length / 2} documents`)
    es.bulk({
      index: CONF.elasticsearchOparlIndex,
      body: data
    }, (err, res) => cb(err))
  })
}

function pdftohtml(pdfPath, htmlPath, cb) {
  child_process.exec(`pdftohtml -i -s ${pdfPath}`, (err, stdout, stderr) => {
    if (err) return cb(err)

    stderr = stderr.toString()
    if (stderr) return cb(new Error(stderr))

    let basePath = pdfPath.replace(/\.pdf$/i, "")
    fs.unlink(`${basePath}s.html`, err => {
      // Ignore this err
      fs.rename(`${basePath}-html.html`, htmlPath, err => {
        cb(err)
      })
    })
  })
}

function pdftotext(pdfPath, cb) {
  child_process.exec(`pdftotext -enc UTF-8 -layout ${pdfPath}`, (err, stdout, stderr) => {
    if (err) return cb(err)

    stderr = stderr.toString()
    if (stderr) return cb(new Error(stderr))

    let txtPath = pdfPath.replace(/\.pdf$/i, ".txt")
    cb(null, txtPath)
  })
}

function htmlEscape(text) {
  return text
    .replace(/&/g, "&")
    .replace(/</g, "<")
    .replace(/>/g, ">")
}

function writeHtml(text, htmlPath, cb) {
  let html = fs.createWriteStream(htmlPath)
  html.write(`<!DOCTYPE html>
<html>
  <head>
    <style>
      body { font-family: serif; }
      .page { padding: 2em 4em; }
      p { margin: 0; white-space: pre; }
    </style>
  </head>
  <body>
`)

  // Remove superfluous page breaks:
  text = text.replace(/\f\s*$/, "")

  for(var pageText of text.split(/\f/g)) {
    html.write(`<div class="page">`)
    for(var lineText of pageText.split(/\n/g)) {
      html.write(`<p>${htmlEscape(lineText)}</p>\n`)
    }
    html.write(`</div>\n`)
  }

  html.write(`  </body>
</html>
`)
  cb()
}

function htmlToText(htmlPath, cb) {
  let pages = []

  let proc = htmlProcess()
  proc.on('error', err => {
    cb(err)
    cb = () => {}
  })

  fs.createReadStream(htmlPath)
    .pipe(proc)
    .pipe(through.obj((page, enc, cb) => {
      pages.push(page.contents.map(
        block =>
          block.contents.map(getFragmentText).join("")
      ).join("\n"))
      cb()
    }, flushCb => {
      flushCb()
      cb(null, pages.join("\n\n\n"))
    }))
}

function getFragmentText(frag) {
  if (typeof frag === 'string') {
    return frag
  } else if (frag.contents) {
    return frag.contents.map(getFragmentText).join("")
  } else {
    return ""
  }
}

/*** Main pipeline ***/

child_process.spawn("/usr/bin/env", ["find", CONF.scrapeData, "-name", "*.json", "-type", "f"]).stdout
  .pipe(split())
  .pipe(through.obj((line, enc, cb) => {
    cb(null, line.toString('utf8'))
  }))
  .pipe(through.obj((path, enc, cb) => {
    if (!path) return cb()

    fs.readFile(path, (err, data) => {
      cb(err, {
        path: path,
        data: data
      })
    })
  }))
  .pipe(through.obj((data, enc, cb) => {
    let json = JSON.parse(data.data)
    cb(null, {
      path: data.path,
      json: json
    })
  }))
  .pipe(through.obj((data, enc, cb) => {
    // pdftohtml for Files
    if (/\/File$/.test(data.json.type)) {
      let pdfPath = data.path.replace(/\.json$/, ".pdf")
      let htmlPath = pdfPath.replace(/\.pdf$/i, ".html")
      fs.access(htmlPath, err => {
        if (!err) {
          // .html already exists, skip
          data.htmlPath = htmlPath
          return cb(null, data)
        }

        fs.access(pdfPath, err => {
          if (err) {
            // Can't access .pdf, ignore
            return cb(null, data)
          }

          let t1 = Date.now()
          pdftohtml(pdfPath, htmlPath, err => {
            if (err) {
              console.log("pdftohtml error: " + err.message)
              return cb(null, data)
            }

            let t2 = Date.now()
            console.log(`pdftohtml [${t2 - t1}ms] ${pdfPath}`)

            data.htmlPath = htmlPath
            cb(null, data)
          })
        })
      })
    } else {
      // Pass through non-Files
      cb(null, data)
    }
  }))
  .pipe(through.obj((data, enc, cb) => {
    // extract text from pdftohtml result
    if (data.htmlPath) {
      htmlToText(data.htmlPath, (err, text) => {
        if (err) {
          console.log("htmlToText error: " + err.message)
          return cb(null, data)
        }

        data.json.text = text
        cb(err, data)
      })
    } else {
      cb(null, data)
    }
  }))
  .pipe(through.obj((data, enc, cb) => {
      if (/\/File$/.test(data.json.type) &&
          (!data.json.text ||
           (data.json.text && !/\S/.test(data.json.text)))) {
        // No characters in text? Fixup with pdftotext:

        let pdfPath = data.path.replace(/\.json$/, ".pdf")
        let t1 = Date.now()
        pdftotext(pdfPath, (err, txtPath) => {
          if (err) {
            console.log("pdftotext error: " + err.message)
            return cb(null, data)
          }

          let t2 = Date.now()
          console.log(`pdftotext [${t2 - t1}ms] ${pdfPath}`)

          fs.readFile(txtPath, {
            encoding: 'utf8'
          }, (err, text) => {
            if (err) return cb(err)

            // Keep for indexing
            data.json.text = text.replace(/\f/g, "\n")
            // Generate processHtml-compatible HTML
            let htmlPath = data.path.replace(/\.json$/, ".html")
            writeHtml(text, htmlPath, err => cb(err, data))
          })
        })
      } else {
        cb(null, data)
      }
  }))
  .pipe(through.obj((data, enc, cb) => {
    // Actually, we only send the JSON to ES, not the paths
    cb(null, data.json)
  }))
  .pipe(batchify(64))
  .pipe(jsonsToElasticBatch())
  .pipe(elasticSink())
<|endoftext|>


<commit_before>var huffman = require('./huffman');

var HeaderTable = function () {
    this.table = [[void(0), void(0), void(0)]];
    this._seq = 0;
};
HeaderTable.prototype.get = function (index) {
    return this.table[index];
};
HeaderTable.prototype.insert = function (name, value) {
    var ref = 'r' + ++this._seq;
    this.table.splice(1, 0, [name, value, ref]);
    return ref;
};
HeaderTable.prototype.refer = function (ref) {
    var i, n = this.table.length;
    for (i = 0; i < n; i++) {
        if (this.table[i][2] == ref) {
            return this.table[i];
        }
    }
};
HeaderTable.prototype.find = function (name, value) {
    var i, n = this.table.length;
    for (i = 0; i< n; i++) {
        if (this.table[i][0] === name && this.table[i][1] === value) {
            return i;
        }
    }
    return void(0);
};
Object.defineProperty(HeaderTable.prototype, 'length', {
    get: function () {
             return this.table.length;
         }
});

var HPACK = function () {
    this.lHeaderTable = new HeaderTable();
    this.rHeaderTable = new HeaderTable();
    this.refSet = {};
};

HPACK.prototype.encode = function (input) {
    var i, j;
    var output = [];
    var bufPos = 0;
    var name, value, block;

    // Clear Reference Set (to simplify encoding logic)
    output.push(new Buffer([0x30]));

    for (i = 0; i < input.length; i++) {
        name = input[i][0];
        value = input[i][1];
        block = encodeField.call(this, name, value);
        if (block) {
            output.push(block);
        }
    }
    // console.log('-- HPACK encode --');
    // console.log(input);
    // console.log('------------------');
    // console.log(output);
    // console.log('------------------');
    return Buffer.concat(output);
};

HPACK.prototype.decode = function (input) {
    var output = [];
    var index, result, field;
    var pos = 0;
    while (pos < input.length) {
        if (input[pos] & 0x80) {
            // console.log('HPACK-DEBUG: Indexed Header Field Representation');
            result = decodeInteger(input.slice(pos), 7);
            index = result.value;
            pos += result.len;
            // console.log('HPACK-DEBUG: Index: ' + index);
            if (index < this.lHeaderTable.length) {
                field = this.lHeaderTable.get(index);
                if (this.refSet[field[2]]) {
                    delete this.refSet[field[2]];
                } else {
                    // console.log('HPACK-DEBUG: Emit: ' + [field[0], field[1]]);
                    output.push([field[0], field[1]]);
                    this.refSet[field[2]] = true;
                }
            } else {
                field = staticTable[index - (this.lHeaderTable.length - 1)];
                // console.log('HPACK-DEBUG: Emit: ' + [field[0], field[1]]);
                ref = this.lHeaderTable.insert(field[0], field[1]);
                this.refSet[ref] = true;
                output.push([field[0], field[1]]);
            }
        } else if (input[pos] & 0x40 || (!(input[pos] & 0x20) && input[pos] & 0x10)) {
            var doIndex = input[pos] & 0x40;

            // console.log('HPACK-DEBUG: Literal Header Field');
            result = decodeInteger(input.slice(pos), 6);
            index = result.value;
            pos += result.len;
            // console.log('HPACK-DEBUG: Index: ' + index);
            if (index === 0) {
                result = decodeString(input.slice(pos));
                pos += result.len;
                field = result.value;
            } else {
                if (index < this.lHeaderTable.length) {
                    field = this.lHeaderTable.get(index)[0];
                } else {
                    field = staticTable[index - (this.lHeaderTable.length - 1)][0];
                }
            }
            result = decodeString(input.slice(pos));
            pos += result.len;
            // console.log('HPACK-DEBUG: Emit: ' + [field, result.value]);
            if (doIndex) {
                ref = this.lHeaderTable.insert(field, result.value);
                this.refSet[ref] = true;
            }
            output.push([field, result.value]);
        } else if (input[pos] & 0x20) {
            // console.log('HPACK-DEBUG: Encoding Context Update');
            if (input[pos] & 0x10) {
                // console.log('HPACK-DEBUG: Reference Set Emptying');
                Object.keys(this.refSet).forEach(function (elm) {
                    delete this.refSet[elm];
                }, this);
                pos += 1;
            } else {
                // console.log('HPACK-DEBUG: Maximum Header Table Size Change is not implemented yet');
                result = decodeInteger(input.slice(pos), 4);
                pos += result.len;
            }
        } else {
            // console.log('HPACK-DEBUG: Literal Header Field without Indexing');
            result = decodeInteger(input.slice(pos), 4);
            index = result.value;
            pos += result.len;
            // console.log('HPACK-DEBUG: Index: ' + index);
            if (index === 0) {
                result = decodeString(input.slice(pos));
                pos += result.len;
                field = result.value;
            } else {
                if (index < this.lHeaderTable.length) {
                    field = this.lHeaderTable.get(index)[0];
                } else {
                    field = staticTable[index - (this.lHeaderTable.length - 1)][0];
                }
            }
            result = decodeString(input.slice(pos));
            pos += result.len;
            // console.log('HPACK-DEBUG: Emit: ' + [field, result.value]);
            output.push([field, result.value]);
        }
    }
    var output2 = [];
    for (ref in this.refSet) {
        field = this.lHeaderTable.refer(ref);
        for (i = 0; i < output.length; i++) {
            if (output[i][0] === field[0]) {
                break;
            }
        }
        if (i === output.length) {
            // console.log('HPACK-DEBUG: Append ' + field[0] + ': ' + field[1] + ' from RefSet');
            output2.push([field[0], field[1]]);
        }
    }
    // console.log('-- HPACK decode --');
    // console.log(input);
    // console.log('------------------');
    // console.log(output);
    // console.log('------------------');
    return output2.concat(output);
};

var encodeInteger = function (input, n) {
    var output = [];
    var x = Math.pow(2, n) - 1;
    if (input < x) {
        output.push(input);
    } else {
        output.push(x);
        input = input - x;
        while (input >= 128) {
            output.push(input % 128 + 128);
            input = parseInt(input / 128);
        }
        output.push(input);
    }
    return new Buffer(output);
};

var decodeInteger = function (input, n) {
    var i, j = 0, m = 0;
    i = input[0] & Math.pow(2, n) - 1;
    if (i == Math.pow(2, n) - 1) {
        do {
            j++;
            i += (input[j] & 0x7F) * Math.pow(2, m);
            m += 7;
        } while (input[j] & 0x80);
    }
    return {
        'value': i,
        'len': j + 1
    };
};

var encodeString = function (input, huffman) {
    // Never use huffman (because it's not implemented yet)
    var length = encodeInteger(input.length, 7);
    var data = new Buffer(input, 'ascii');
    return Buffer.concat([length, data], length.length + data.length);
};

var decodeString = function (input) {
    var result = decodeInteger(input, 7);
    var str;
    if (input[0] & 0x80) {
        str = huffman.decode(input.slice(result.len, result.len + result.value));
    } else {
        str = input.toString('ascii', result.len, result.len + result.value);
    }
    return {
        'value': str,
        'len': result.len + result.value
    };
};

var encodeField = function (name, value) {
    var i, j, index;

    index = this.rHeaderTable.find(name, value);
    if (index) {
        output = encodeInteger(index, 7);
        output[0] |= 0x80;
        return output;
    }

    for (i = 0; i < staticTable.length; i++) {
        if (staticTable[i][0] === name) {
            break;
        }
    }
    if (i !== staticTable.length) {
        for (j = i; j < staticTable.length; j++) {
            if (staticTable[j][0] !== name) {
                j = -1;
                break;
            }
            if (staticTable[j][1] === value) {
                break;
            }
        }
        if (j !== -1 && j !== staticTable.length) {
            output = encodeInteger(this.rHeaderTable.length - 1 + j, 7);
            output[0] |= 0x80;
            this.rHeaderTable.insert(name, value);
        } else {
            output = Buffer.concat([
                        encodeInteger(this.rHeaderTable.length - 1 + i, 6),
                        encodeString(value)]);
            output[0] |= 0x40;
            this.rHeaderTable.insert(name, value);
        }
        return output;
    }

    output = Buffer.concat([
                encodeInteger(0, 6),
                encodeString(name),
                encodeString(value)]);
    output[0] |= 0x40;
    this.rHeaderTable.insert(name, value);
    return output;
};

var staticTable = HPACK.prototype.staticTable = [
    [void(0), void(0)],
    [':authority', void(0)],
    [':method',    'GET'],
    [':method',    'POST'],
    [':path',      '/'],
    [':path',      '/index.html'],
    [':scheme',    'http'],
    [':scheme',    'https'],
    [':status',    '200'],
    [':status',    '204'],
    [':status',    '206'],
    [':status',    '304'],
    [':status',    '400'],
    [':status',    '404'],
    [':status',    '500'],
    ['accept-charset', void(0)],
    ['accept-encoding', 'gzip, deflate'],
    ['accept-language', void(0)],
    ['accept-ranges', void(0)],
    ['accept', void(0)],
    ['access-control-allow-origin', void(0)],
    ['age', void(0)],
    ['allow', void(0)],
    ['authorization', void(0)],
    ['cache-control', void(0)],
    ['content-disposition', void(0)],
    ['content-encoding', void(0)],
    ['content-language', void(0)],
    ['content-length', void(0)],
    ['content-location', void(0)],
    ['content-range', void(0)],
    ['content-type', void(0)],
    ['cookie', void(0)],
    ['date', void(0)],
    ['etag', void(0)],
    ['expect', void(0)],
    ['expires', void(0)],
    ['from', void(0)],
    ['host', void(0)],
    ['if-match', void(0)],
    ['if-modified-since', void(0)],
    ['if-none-match', void(0)],
    ['if-range', void(0)],
    ['if-unmodified-since', void(0)],
    ['last-modified', void(0)],
    ['link', void(0)],
    ['location', void(0)],
    ['max-forwards', void(0)],
    ['proxy-authenticate', void(0)],
    ['proxy-authorization', void(0)],
    ['range', void(0)],
    ['referer', void(0)],
    ['refresh', void(0)],
    ['retry-after', void(0)],
    ['server', void(0)],
    ['set-cookie', void(0)],
    ['strict-transport-security', void(0)],
    ['transfer-encoding', void(0)],
    ['user-agent', void(0)],
    ['vary', void(0)],
    ['via ', void(0)],
    ['www-authenticate', void(0)],
];

module.exports = {
    'HPACK': HPACK,
};
<commit_msg>fix a typo in static table of HPACK<commit_after>var huffman = require('./huffman');

var HeaderTable = function () {
    this.table = [[void(0), void(0), void(0)]];
    this._seq = 0;
};
HeaderTable.prototype.get = function (index) {
    return this.table[index];
};
HeaderTable.prototype.insert = function (name, value) {
    var ref = 'r' + ++this._seq;
    this.table.splice(1, 0, [name, value, ref]);
    return ref;
};
HeaderTable.prototype.refer = function (ref) {
    var i, n = this.table.length;
    for (i = 0; i < n; i++) {
        if (this.table[i][2] == ref) {
            return this.table[i];
        }
    }
};
HeaderTable.prototype.find = function (name, value) {
    var i, n = this.table.length;
    for (i = 0; i< n; i++) {
        if (this.table[i][0] === name && this.table[i][1] === value) {
            return i;
        }
    }
    return void(0);
};
Object.defineProperty(HeaderTable.prototype, 'length', {
    get: function () {
             return this.table.length;
         }
});

var HPACK = function () {
    this.lHeaderTable = new HeaderTable();
    this.rHeaderTable = new HeaderTable();
    this.refSet = {};
};

HPACK.prototype.encode = function (input) {
    var i, j;
    var output = [];
    var bufPos = 0;
    var name, value, block;

    // Clear Reference Set (to simplify encoding logic)
    output.push(new Buffer([0x30]));

    for (i = 0; i < input.length; i++) {
        name = input[i][0];
        value = input[i][1];
        block = encodeField.call(this, name, value);
        if (block) {
            output.push(block);
        }
    }
    // console.log('-- HPACK encode --');
    // console.log(input);
    // console.log('------------------');
    // console.log(output);
    // console.log('------------------');
    return Buffer.concat(output);
};

HPACK.prototype.decode = function (input) {
    var output = [];
    var index, result, field;
    var pos = 0;
    while (pos < input.length) {
        if (input[pos] & 0x80) {
            // console.log('HPACK-DEBUG: Indexed Header Field Representation');
            result = decodeInteger(input.slice(pos), 7);
            index = result.value;
            pos += result.len;
            // console.log('HPACK-DEBUG: Index: ' + index);
            if (index < this.lHeaderTable.length) {
                field = this.lHeaderTable.get(index);
                if (this.refSet[field[2]]) {
                    delete this.refSet[field[2]];
                } else {
                    // console.log('HPACK-DEBUG: Emit: ' + [field[0], field[1]]);
                    output.push([field[0], field[1]]);
                    this.refSet[field[2]] = true;
                }
            } else {
                field = staticTable[index - (this.lHeaderTable.length - 1)];
                // console.log('HPACK-DEBUG: Emit: ' + [field[0], field[1]]);
                ref = this.lHeaderTable.insert(field[0], field[1]);
                this.refSet[ref] = true;
                output.push([field[0], field[1]]);
            }
        } else if (input[pos] & 0x40 || (!(input[pos] & 0x20) && input[pos] & 0x10)) {
            var doIndex = input[pos] & 0x40;

            // console.log('HPACK-DEBUG: Literal Header Field');
            result = decodeInteger(input.slice(pos), 6);
            index = result.value;
            pos += result.len;
            // console.log('HPACK-DEBUG: Index: ' + index);
            if (index === 0) {
                result = decodeString(input.slice(pos));
                pos += result.len;
                field = result.value;
            } else {
                if (index < this.lHeaderTable.length) {
                    field = this.lHeaderTable.get(index)[0];
                } else {
                    field = staticTable[index - (this.lHeaderTable.length - 1)][0];
                }
            }
            result = decodeString(input.slice(pos));
            pos += result.len;
            // console.log('HPACK-DEBUG: Emit: ' + [field, result.value]);
            if (doIndex) {
                ref = this.lHeaderTable.insert(field, result.value);
                this.refSet[ref] = true;
            }
            output.push([field, result.value]);
        } else if (input[pos] & 0x20) {
            // console.log('HPACK-DEBUG: Encoding Context Update');
            if (input[pos] & 0x10) {
                // console.log('HPACK-DEBUG: Reference Set Emptying');
                Object.keys(this.refSet).forEach(function (elm) {
                    delete this.refSet[elm];
                }, this);
                pos += 1;
            } else {
                // console.log('HPACK-DEBUG: Maximum Header Table Size Change is not implemented yet');
                result = decodeInteger(input.slice(pos), 4);
                pos += result.len;
            }
        } else {
            // console.log('HPACK-DEBUG: Literal Header Field without Indexing');
            result = decodeInteger(input.slice(pos), 4);
            index = result.value;
            pos += result.len;
            // console.log('HPACK-DEBUG: Index: ' + index);
            if (index === 0) {
                result = decodeString(input.slice(pos));
                pos += result.len;
                field = result.value;
            } else {
                if (index < this.lHeaderTable.length) {
                    field = this.lHeaderTable.get(index)[0];
                } else {
                    field = staticTable[index - (this.lHeaderTable.length - 1)][0];
                }
            }
            result = decodeString(input.slice(pos));
            pos += result.len;
            // console.log('HPACK-DEBUG: Emit: ' + [field, result.value]);
            output.push([field, result.value]);
        }
    }
    var output2 = [];
    for (ref in this.refSet) {
        field = this.lHeaderTable.refer(ref);
        for (i = 0; i < output.length; i++) {
            if (output[i][0] === field[0]) {
                break;
            }
        }
        if (i === output.length) {
            // console.log('HPACK-DEBUG: Append ' + field[0] + ': ' + field[1] + ' from RefSet');
            output2.push([field[0], field[1]]);
        }
    }
    // console.log('-- HPACK decode --');
    // console.log(input);
    // console.log('------------------');
    // console.log(output);
    // console.log('------------------');
    return output2.concat(output);
};

var encodeInteger = function (input, n) {
    var output = [];
    var x = Math.pow(2, n) - 1;
    if (input < x) {
        output.push(input);
    } else {
        output.push(x);
        input = input - x;
        while (input >= 128) {
            output.push(input % 128 + 128);
            input = parseInt(input / 128);
        }
        output.push(input);
    }
    return new Buffer(output);
};

var decodeInteger = function (input, n) {
    var i, j = 0, m = 0;
    i = input[0] & Math.pow(2, n) - 1;
    if (i == Math.pow(2, n) - 1) {
        do {
            j++;
            i += (input[j] & 0x7F) * Math.pow(2, m);
            m += 7;
        } while (input[j] & 0x80);
    }
    return {
        'value': i,
        'len': j + 1
    };
};

var encodeString = function (input, huffman) {
    // Never use huffman (because it's not implemented yet)
    var length = encodeInteger(input.length, 7);
    var data = new Buffer(input, 'ascii');
    return Buffer.concat([length, data], length.length + data.length);
};

var decodeString = function (input) {
    var result = decodeInteger(input, 7);
    var str;
    if (input[0] & 0x80) {
        str = huffman.decode(input.slice(result.len, result.len + result.value));
    } else {
        str = input.toString('ascii', result.len, result.len + result.value);
    }
    return {
        'value': str,
        'len': result.len + result.value
    };
};

var encodeField = function (name, value) {
    var i, j, index;

    index = this.rHeaderTable.find(name, value);
    if (index) {
        output = encodeInteger(index, 7);
        output[0] |= 0x80;
        return output;
    }

    for (i = 0; i < staticTable.length; i++) {
        if (staticTable[i][0] === name) {
            break;
        }
    }
    if (i !== staticTable.length) {
        for (j = i; j < staticTable.length; j++) {
            if (staticTable[j][0] !== name) {
                j = -1;
                break;
            }
            if (staticTable[j][1] === value) {
                break;
            }
        }
        if (j !== -1 && j !== staticTable.length) {
            output = encodeInteger(this.rHeaderTable.length - 1 + j, 7);
            output[0] |= 0x80;
            this.rHeaderTable.insert(name, value);
        } else {
            output = Buffer.concat([
                        encodeInteger(this.rHeaderTable.length - 1 + i, 6),
                        encodeString(value)]);
            output[0] |= 0x40;
            this.rHeaderTable.insert(name, value);
        }
        return output;
    }

    output = Buffer.concat([
                encodeInteger(0, 6),
                encodeString(name),
                encodeString(value)]);
    output[0] |= 0x40;
    this.rHeaderTable.insert(name, value);
    return output;
};

var staticTable = HPACK.prototype.staticTable = [
    [void(0), void(0)],
    [':authority', void(0)],
    [':method',    'GET'],
    [':method',    'POST'],
    [':path',      '/'],
    [':path',      '/index.html'],
    [':scheme',    'http'],
    [':scheme',    'https'],
    [':status',    '200'],
    [':status',    '204'],
    [':status',    '206'],
    [':status',    '304'],
    [':status',    '400'],
    [':status',    '404'],
    [':status',    '500'],
    ['accept-charset', void(0)],
    ['accept-encoding', 'gzip, deflate'],
    ['accept-language', void(0)],
    ['accept-ranges', void(0)],
    ['accept', void(0)],
    ['access-control-allow-origin', void(0)],
    ['age', void(0)],
    ['allow', void(0)],
    ['authorization', void(0)],
    ['cache-control', void(0)],
    ['content-disposition', void(0)],
    ['content-encoding', void(0)],
    ['content-language', void(0)],
    ['content-length', void(0)],
    ['content-location', void(0)],
    ['content-range', void(0)],
    ['content-type', void(0)],
    ['cookie', void(0)],
    ['date', void(0)],
    ['etag', void(0)],
    ['expect', void(0)],
    ['expires', void(0)],
    ['from', void(0)],
    ['host', void(0)],
    ['if-match', void(0)],
    ['if-modified-since', void(0)],
    ['if-none-match', void(0)],
    ['if-range', void(0)],
    ['if-unmodified-since', void(0)],
    ['last-modified', void(0)],
    ['link', void(0)],
    ['location', void(0)],
    ['max-forwards', void(0)],
    ['proxy-authenticate', void(0)],
    ['proxy-authorization', void(0)],
    ['range', void(0)],
    ['referer', void(0)],
    ['refresh', void(0)],
    ['retry-after', void(0)],
    ['server', void(0)],
    ['set-cookie', void(0)],
    ['strict-transport-security', void(0)],
    ['transfer-encoding', void(0)],
    ['user-agent', void(0)],
    ['vary', void(0)],
    ['via', void(0)],
    ['www-authenticate', void(0)],
];

module.exports = {
    'HPACK': HPACK,
};
<|endoftext|>


<commit_before>var strtok = require('strtok');
var parser = require('./id3v2_frames');
var common = require('./common');

module.exports = function (stream, callback, done) {
  strtok.parse(stream, function (v, cb) {
    if (!v) {
      cb.state = 0;
      return new strtok.BufferType(10);
    }

    switch (cb.state) {
      case -1: // skip
        cb.state = 2;
        return readFrameHeader(cb.header.major);
      case 0: // header
        if (v.toString('ascii', 0, 3) !== 'ID3') {
          done(new Error('expected id3 header but was not found'));
        }

        cb.header = {
          version: '2.' + v[3] + '.' + v[4],
          major: v[3],
          unsync: strtok.BITSET.get(v, 5, 7),
          xheader: strtok.BITSET.get(v, 5, 6),
          xindicator: strtok.BITSET.get(v, 5, 5),
          footer: strtok.BITSET.get(v, 5, 4),
          size: strtok.INT32SYNCSAFE.get(v, 6)
        };

        if (cb.header.xheader) {
          cb.state = 1;
          return strtok.UINT32_BE;
        }

        // expect the first frames header next
        cb.state = 2;
        return readFrameHeader(cb.header.major);

      case 1: // xheader
        cb.state = -1;
        return new strtok.BufferType(v - 4);

      case 2: // frameheader
        var header = cb.frameHeader = {};
        switch (cb.header.major) {
          case 2:
            header.id = v.toString('ascii', 0, 3);
            header.length = strtok.UINT24_BE.get(v, 3, 6);
            break;
          case 3:
            header.id = v.toString('ascii', 0, 4);
            header.length = strtok.UINT32_BE.get(v, 4, 8);
            header.flags = readFrameFlags(v.slice(8, 10));
            break;
          case 4:
            header.id = v.toString('ascii', 0, 4);
            header.length = strtok.INT32SYNCSAFE.get(v, 4, 8);
            header.flags = readFrameFlags(v.slice(8, 10));
            break;
        }

        // Last frame. Check first char is a letter, bit of defensive programming
        if (header.id === '' || header.id === '\u0000\u0000\u0000\u0000'
            || 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.search(header.id[0]) === -1) {
          return done();
        }
        cb.state++;
        return new strtok.BufferType(header.length);

      case 3: // framedata
        cb.state = 2; // frameheader up next
        var frame, encoding;
        switch (cb.header.major) {
          case 2:
            frame = parser.readData(v, cb.frameHeader.id, null, cb.header.major);
            callback(cb.frameHeader.id, frame);
            return new strtok.BufferType(6);
          case 3:
          case 4:
            if (cb.frameHeader.flags.format.unsync) {
              v = common.removeUnsyncBytes(v);
            }
            if (cb.frameHeader.flags.format.data_length_indicator) {
              v = v.slice(4, v.length);
            }
            frame = parser.readData(v, cb.frameHeader.id, cb.frameHeader.flags, cb.header.major);
            callback(cb.frameHeader.id, frame);
            return new strtok.BufferType(10);
        }
    }
  })

  function readFrameHeader (majorVer) {
    switch (majorVer) {
      case 2:
        return new strtok.BufferType(6);
      case 3:
      case 4:
        return new strtok.BufferType(10);
      default:
        done(new Error('header version is incorrect'))
    }
  }
}

function readFrameFlags (b) {
  return {
    status: {
      tag_alter_preservation: strtok.BITSET.get(b, 0, 6),
      file_alter_preservation: strtok.BITSET.get(b, 0, 5),
      read_only: strtok.BITSET.get(b, 0, 4)
    },
    format: {
      grouping_identity: strtok.BITSET.get(b, 1, 7),
      compression: strtok.BITSET.get(b, 1, 3),
      encryption: strtok.BITSET.get(b, 1, 2),
      unsync: strtok.BITSET.get(b, 1, 1),
      data_length_indicator: strtok.BITSET.get(b, 1, 0)
    }
  }
}<commit_msg>add missing return statements<commit_after>var strtok = require('strtok');
var parser = require('./id3v2_frames');
var common = require('./common');

module.exports = function (stream, callback, done) {
  strtok.parse(stream, function (v, cb) {
    if (!v) {
      cb.state = 0;
      return new strtok.BufferType(10);
    }

    switch (cb.state) {
      case -1: // skip
        cb.state = 2;
        return readFrameHeader(cb.header.major);
      case 0: // header
        if (v.toString('ascii', 0, 3) !== 'ID3') {
          return done(new Error('expected id3 header but was not found'));
        }

        cb.header = {
          version: '2.' + v[3] + '.' + v[4],
          major: v[3],
          unsync: strtok.BITSET.get(v, 5, 7),
          xheader: strtok.BITSET.get(v, 5, 6),
          xindicator: strtok.BITSET.get(v, 5, 5),
          footer: strtok.BITSET.get(v, 5, 4),
          size: strtok.INT32SYNCSAFE.get(v, 6)
        };

        if (cb.header.xheader) {
          cb.state = 1;
          return strtok.UINT32_BE;
        }

        // expect the first frames header next
        cb.state = 2;
        return readFrameHeader(cb.header.major);

      case 1: // xheader
        cb.state = -1;
        return new strtok.BufferType(v - 4);

      case 2: // frameheader
        var header = cb.frameHeader = {};
        switch (cb.header.major) {
          case 2:
            header.id = v.toString('ascii', 0, 3);
            header.length = strtok.UINT24_BE.get(v, 3, 6);
            break;
          case 3:
            header.id = v.toString('ascii', 0, 4);
            header.length = strtok.UINT32_BE.get(v, 4, 8);
            header.flags = readFrameFlags(v.slice(8, 10));
            break;
          case 4:
            header.id = v.toString('ascii', 0, 4);
            header.length = strtok.INT32SYNCSAFE.get(v, 4, 8);
            header.flags = readFrameFlags(v.slice(8, 10));
            break;
        }

        // Last frame. Check first char is a letter, bit of defensive programming
        if (header.id === '' || header.id === '\u0000\u0000\u0000\u0000'
            || 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.search(header.id[0]) === -1) {
          return done();
        }
        cb.state++;
        return new strtok.BufferType(header.length);

      case 3: // framedata
        cb.state = 2; // frameheader up next
        var frame, encoding;
        switch (cb.header.major) {
          case 2:
            frame = parser.readData(v, cb.frameHeader.id, null, cb.header.major);
            callback(cb.frameHeader.id, frame);
            return new strtok.BufferType(6);
          case 3:
          case 4:
            if (cb.frameHeader.flags.format.unsync) {
              v = common.removeUnsyncBytes(v);
            }
            if (cb.frameHeader.flags.format.data_length_indicator) {
              v = v.slice(4, v.length);
            }
            frame = parser.readData(v, cb.frameHeader.id, cb.frameHeader.flags, cb.header.major);
            callback(cb.frameHeader.id, frame);
            return new strtok.BufferType(10);
        }
    }
  })

  function readFrameHeader (majorVer) {
    switch (majorVer) {
      case 2:
        return new strtok.BufferType(6);
      case 3:
      case 4:
        return new strtok.BufferType(10);
      default:
        return done(new Error('header version is incorrect'));
    }
  }
}

function readFrameFlags (b) {
  return {
    status: {
      tag_alter_preservation: strtok.BITSET.get(b, 0, 6),
      file_alter_preservation: strtok.BITSET.get(b, 0, 5),
      read_only: strtok.BITSET.get(b, 0, 4)
    },
    format: {
      grouping_identity: strtok.BITSET.get(b, 1, 7),
      compression: strtok.BITSET.get(b, 1, 3),
      encryption: strtok.BITSET.get(b, 1, 2),
      unsync: strtok.BITSET.get(b, 1, 1),
      data_length_indicator: strtok.BITSET.get(b, 1, 0)
    }
  }
}<|endoftext|>


<commit_before>'use strict';
/**
 *  index.js - Shawn Rapp 2014-10-10
 *  Party Line subsystem interface library file.
 *  @author Shawn Rapp
 *  @version 1.0.0
 *  @license MIT. Read LICENSE for more information.
 *  @fileOverview Main library file.
 */

/**
 * Module dependencies.
 */

/**
 * Constructor for PartyLineSub
 */
function PartyLineSub() {
    var self = this;

    self.worker_id = "";
    self.bus_id = "";
    self.listen_context = [];
    self.packet_handlers = [];
    self.input_stream = require('JSONStream').parse();
    process.stdin.pipe(self.input_stream);
    self.outbound_packets = [];
    self.sending_state = false;

    /**
     *  Outputs a single packet to stdout stream.
     *  Defined inside of block because function is needed immediately.
     */
    self.send = function(transmit_packet) {
        self.outbound_packets.push(transmit_packet);

        //already running send in a different thread.
        if (self.sending_state) return;

        //set state high this thread is going to send.
        self.sending_state = true;

        //keep sending till we run out of packets
        while(self.outbound_packets.length > 0) {
            var packet = self.outbound_packets.pop();
            console.log(JSON.stringify(packet));
        }

        //set state low this thread is finished.
        self.sending_state = false;
    };
}

var partylinesub = module.exports = exports = new PartyLineSub;

/**
 * Sends to the bus what contexts this subsystem wants to listen to.
 * Accepts no parameters because the context should be set to
 * self.listen_context array.
 */
PartyLineSub.prototype.sendSetListenerContext = function(){
    var self = this;
    var setContextPacket = {
        context: "bus",
        type: "setListenContext",
        listen_context: self.listen_context
    };
    self.send(setContextPacket);
};

/**
 * Adds a context this sub wants to listen on in the stack and sends the stack
 * to the bus.
 */
PartyLineSub.prototype.addListeningContext = function(new_context) {
    var self = this;

    self.listen_context.push(new_context);
    self.sendSetListenerContext();
};

/**
 * Removes the specified listening context from the stack of listening and sends
 * the results to the bus.
 */
PartyLineSub.prototype.removeListeningContext = function(delete_context) {
    var self = this;

    var new_context_stack = [];

    self.listen_context.forEach(function(context){
       if (context != delete_context) {
           new_context_stack.push(context);
       }
    });

    self.listen_context = new_context_stack;
    self.sendSetListenerContext();
};

/**
 * used to transmit large files accross the bus.
 */
PartyLineSub.prototype.sendFile = function(fd, packet, stats) {
    var self = this;
    var fs = require('fs');
    //size of each block
    var block_size = 1024;
    //total number of blocks including ending partial
    var total_blocks = Math.floor(stats.size / block_size) + (block_size%stats.size?1:0);
    var resend_blocks = [];
    var quit_xfer = false;

    function sendBlock(block_number) {
        if (quit_xfer) return;  //abort if flag is high

        var block_position = block_number * block_size;
        var read_buffer = new Buffer(block_size);
        var bytesRead = fs.readSync(fd, read_buffer, 0, block_size, block_position);
        var file_packet = {
            context: packet.from,
            type: "blockLongTransfer",
            block_number: current_block,
            block_size: bytesRead,
            data:read_buffer.toString('base64')
        };
        self.send(file_packet);
    }

    function resendBlocks() {
        if (quit_xfer) {
            //clear resend_blocks stack to try to prevent logic that would come back
            resend_blocks = [];
            return;
        }
        while (resend_blocks.length > 0) {
            var block_number = resend_blocks.pop();
            sendBlock(block_number);
        }
    }

    //setup a listener for packets to be resent
    self.on("resendBlock", function(resend_packet){
        //if it doesn't belong to us, just ignore it
        if (resend_packet.request_id != packet.request_id) return;

        resend_blocks.push(resend_packet.resend_block);
    });

    //event that only the client should send on a transfer abort or
    //file has been sent successfully
    self.on("endLongTransfer", function(end_packet){
        fs.close(fd);
        quit_xfer = true;
    });

    var ack_packet = {
        context: packet.from,
        type: "startLongTransfer",
        request_id: packet.request_id,
        block_size: block_size,
        total_blocks: total_blocks
    };
    self.send(ack_packet);

    for (var current_block=0; current_block<total_blocks; current_block++) {
        sendBlock(current_block);

        //every 8 blocks lets do some resends.
        //We don't want to go past 8k so our client handler won't have to pause streaming to user.
        if (current_block%8 === 0) {
            resendBlocks();
        }
    }

    resendBlocks();
};

/**
 * used to receive large files accross the bus.
 */
PartyLineSub.prototype.receiveFile = function(file_buffer, init_packet){
    var self = this;
    //chunks being processed
    var chunks = [];
    //chunks written
    var last_chunk_written = -1;

    /**
     * Object for managing transfered blocks into chunks.
     */
    function ReceiveChunk(chunk_pos){
        var rchunk = this;
        // buffer is 8 blocks long
        var outgoing_buffer = new Buffer(8*init_packet.block_size);
        var received_blocks = [];
        this.completed = false;
        this.chunk_pos = chunk_pos;

        function incomingBlock(packet) {
            //check to see if some how we ended up in the wrong chunk
            if (Math.floor(packet.block_position/8) != chunk_pos) return;
            //calculate the offset in buffer based on block_position
            var buffer_pos = packet.block_position % 8;

            //check to see if we have already received this block
            if (received_blocks.indexOf(packet.block_position) != -1) return;
            //check to see if we missed a packet
            if (received_blocks[received_blocks.length-1]+1 < packet.block_position) {
                var resend_packet = {
                    context: packet.from,
                    type: "resendBlock",
                    resend_block: received_blocks[received_blocks.length-1]+1
                };
                self.send(resend_packet);
            }

            outgoing_buffer[buffer_pos] = (new Buffer(packet.data, "base64")).toString();
            //mark this block as successful
            received_blocks.push(packet.block_position);

            //check to see if chunk has been completed.
            if (received_blocks.length > 7) {
                if (last_chunk_written+1 == chunk_pos) {
                    file_buffer.write(outgoing_buffer);
                }
                rchunk.completed = true;
            }
        }

        self.on("blockLongTransfer", function(packet) {
            var chunk_position = Math.floor(packet.block_position/8);
            if (chunk_position == rchunk.chunk_pos) {
                var buffer_offset = packet.block_position%8;
                outgoing_buffer[buffer_offset] = (new Buffer(packet.data, "base64")).toString();
                received_blocks.push(packet.block_position);

                if (received_blocks.length > 7) {
                    rchunk.completed = true;
                }
            }
        });
    }

    self.on("blockLongTransfer", function(packet){
        var chunk_position = Math.floor(packet.block_position/8);
        if (chunks.indexOf(chunk_position)==-1) {
            new ReceiveChunk(chunk_position);
            chunks.push(chunk_position);
        }
    })
};

/**
 * allows developers to attach functions to packets based on packet
 * type.
 * More than one function can be attached to the same "event"
 */
PartyLineSub.prototype.on = function(packet_type, cb_packet_handler) {
    var self = this;

    var new_handler = {
        packet_type: packet_type,
        cb_packet_handler: cb_packet_handler
    };
    self.packet_handlers.push(new_handler);
};

/**
 * Process incoming JSON data looking for packets.
 */
partylinesub.input_stream.on("data",function(packet){
    var self = partylinesub;

    //check if packet has context and if its for this sub
    if (typeof(packet.context) == 'undefined' || !packet.context.match(self.listen_context)) {
        return; //packet is not for this service
    }

    //send this packet to calling application
    self.packet_handlers.forEach(function(packet_handler){
       if (packet.type == packet_handler.packet_type) {
           packet_handler.cb_packet_handler(packet);
       }
    });
});

/**
 * A general catch for when something goes wrong in the down stream and
 * sends a message to the upstream.
 */
partylinesub.input_stream.on("error", function(err){
    var error_packet = {
        type: 'error',
        data: err
    };
    partylinesub.send(error_packet);
});
<commit_msg>fixed some path bugs.<commit_after>'use strict';
/**
 *  index.js - Shawn Rapp 2014-10-10
 *  Party Line subsystem interface library file.
 *  @author Shawn Rapp
 *  @version 1.0.0
 *  @license MIT. Read LICENSE for more information.
 *  @fileOverview Main library file.
 */

/**
 * Module dependencies.
 */

/**
 * Constructor for PartyLineSub
 */
function PartyLineSub() {
    var self = this;

    self.worker_id = "";
    self.bus_id = "";
    self.listen_context = [];
    self.packet_handlers = [];
    self.input_stream = require('JSONStream').parse();
    process.stdin.pipe(self.input_stream);
    self.outbound_packets = [];
    self.sending_state = false;

    /**
     *  Outputs a single packet to stdout stream.
     *  Defined inside of block because function is needed immediately.
     */
    self.send = function(transmit_packet) {
        self.outbound_packets.push(transmit_packet);

        //already running send in a different thread.
        if (self.sending_state) return;

        //set state high this thread is going to send.
        self.sending_state = true;

        //keep sending till we run out of packets
        while(self.outbound_packets.length > 0) {
            var packet = self.outbound_packets.pop();
            console.log(JSON.stringify(packet));
        }

        //set state low this thread is finished.
        self.sending_state = false;
    };
}

var partylinesub = module.exports = exports = new PartyLineSub;

/**
 * Sends to the bus what contexts this subsystem wants to listen to.
 * Accepts no parameters because the context should be set to
 * self.listen_context array.
 */
PartyLineSub.prototype.sendSetListenerContext = function(){
    var self = this;
    var setContextPacket = {
        context: "bus",
        type: "setListenContext",
        listen_context: self.listen_context
    };
    self.send(setContextPacket);
};

/**
 * Adds a context this sub wants to listen on in the stack and sends the stack
 * to the bus.
 */
PartyLineSub.prototype.addListeningContext = function(new_context) {
    var self = this;

    self.listen_context.push(new_context);
    self.sendSetListenerContext();
};

/**
 * Removes the specified listening context from the stack of listening and sends
 * the results to the bus.
 */
PartyLineSub.prototype.removeListeningContext = function(delete_context) {
    var self = this;

    var new_context_stack = [];

    self.listen_context.forEach(function(context){
       if (context != delete_context) {
           new_context_stack.push(context);
       }
    });

    self.listen_context = new_context_stack;
    self.sendSetListenerContext();
};

/**
 * used to transmit large files accross the bus.
 */
PartyLineSub.prototype.sendFile = function(fd, packet, stats) {
    var self = this;
    var fs = require('fs');
    //size of each block
    var block_size = 1024;
    //total number of blocks including ending partial
    var total_blocks = Math.floor(stats.size / block_size) + (block_size%stats.size?1:0);
    var resend_blocks = [];
    var quit_xfer = false;

    function sendBlock(block_number) {
        if (quit_xfer) return;  //abort if flag is high

        var block_position = block_number * block_size;
        var read_buffer = new Buffer(block_size);
        var bytesRead = fs.readSync(fd, read_buffer, 0, block_size, block_position);
        var file_packet = {
            context: packet.from,
            type: "blockLongTransfer",
            block_number: current_block,
            block_size: bytesRead,
            data:read_buffer.toString('base64')
        };
        self.send(file_packet);
    }

    function resendBlocks() {
        if (quit_xfer) {
            //clear resend_blocks stack to try to prevent logic that would come back
            resend_blocks = [];
            return;
        }
        while (resend_blocks.length > 0) {
            var block_number = resend_blocks.pop();
            sendBlock(block_number);
        }
    }

    //setup a listener for packets to be resent
    self.on("resendBlock", function(resend_packet){
        //if it doesn't belong to us, just ignore it
        if (resend_packet.request_id != packet.request_id) return;

        resend_blocks.push(resend_packet.resend_block);
    });

    //event that only the client should send on a transfer abort or
    //file has been sent successfully
    self.on("endLongTransfer", function(end_packet){
        fs.close(fd);
        quit_xfer = true;
    });

    var ack_packet = {
        context: packet.from,
        type: "startLongTransfer",
        request_id: packet.request_id,
        block_size: block_size,
        total_blocks: total_blocks
    };
    self.send(ack_packet);

    for (var current_block=0; current_block<total_blocks; current_block++) {
        sendBlock(current_block);

        //every 8 blocks lets do some resends.
        //We don't want to go past 8k so our client handler won't have to pause streaming to user.
        if (current_block%8 === 0) {
            resendBlocks();
        }
    }

    resendBlocks();
};

/**
 * used to receive large files accross the bus.
 */
PartyLineSub.prototype.receiveFile = function(file_buffer, init_packet){
    var self = this;
    //chunks being processed
    var chunks = [];
    //chunks written
    var last_chunk_written = -1;

    /**
     * Object for managing transfered blocks into chunks.
     */
    function ReceiveChunk(chunk_pos){
        var rchunk = this;
        // buffer is 8 blocks long
        var outgoing_buffer = new Buffer(8*init_packet.block_size);
        var received_blocks = [];
        this.completed = false;
        this.chunk_pos = chunk_pos;

        function incomingBlock(packet) {
            //check to see if some how we ended up in the wrong chunk
            if (Math.floor(packet.block_position/8) != chunk_pos) return;
            //calculate the offset in buffer based on block_position
            var buffer_pos = packet.block_position % 8;

            //check to see if we have already received this block
            if (received_blocks.indexOf(packet.block_position) != -1) return;
            //check to see if we missed a packet
            if (received_blocks[received_blocks.length-1]+1 < packet.block_position) {
                var resend_packet = {
                    context: packet.from,
                    type: "resendBlock",
                    resend_block: received_blocks[received_blocks.length-1]+1
                };
                self.send(resend_packet);
            }

            outgoing_buffer[buffer_pos] = (new Buffer(packet.data, "base64")).toString();
            //mark this block as successful
            received_blocks.push(packet.block_position);

            //check to see if chunk has been completed.
            if (received_blocks.length > 7) {
                if (last_chunk_written+1 == chunk_pos) {
                    file_buffer.write(outgoing_buffer);
                }
                rchunk.completed = true;
            }
        }

        self.on("blockLongTransfer", function(packet) {
            var chunk_position = Math.floor(packet.block_position/8);
            if (chunk_position == rchunk.chunk_pos) {
                var buffer_offset = packet.block_position%8;
                outgoing_buffer[buffer_offset] = (new Buffer(packet.data, "base64")).toString();
                received_blocks.push(packet.block_position);

                if (received_blocks.length > 7) {
                    rchunk.completed = true;
                }
            }
        });
    }

    self.on("blockLongTransfer", function(packet){
        var chunk_position = Math.floor(packet.block_position/8);
        if (chunks.indexOf(chunk_position)==-1) {
            new ReceiveChunk(chunk_position);
            chunks.push(chunk_position);
        }
    });
};

/**
 * allows developers to attach functions to packets based on packet
 * type.
 * More than one function can be attached to the same "event"
 */
PartyLineSub.prototype.on = function(packet_type, cb_packet_handler) {
    var self = this;

    var new_handler = {
        packet_type: packet_type,
        cb_packet_handler: cb_packet_handler
    };
    self.packet_handlers.push(new_handler);
};

/**
 * Process incoming JSON data looking for packets.
 */
partylinesub.input_stream.on("data",function(packet){
    var self = partylinesub;

    //check if packet has context and if its for this sub
    if (typeof(packet.context) == 'undefined' || !packet.context.match(self.listen_context)) {
        return; //packet is not for this service
    }

    //send this packet to calling application
    self.packet_handlers.forEach(function(packet_handler){
       if (packet.type == packet_handler.packet_type) {
           packet_handler.cb_packet_handler(packet);
       }
    });
});

/**
 * A general catch for when something goes wrong in the down stream and
 * sends a message to the upstream.
 */
partylinesub.input_stream.on("error", function(err){
    var error_packet = {
        type: 'error',
        data: err
    };
    partylinesub.send(error_packet);
});
<|endoftext|>


<commit_before>const Copter = require('./copter');
const Obstacle = require('./obstacle');
const Boundary = require('./boundary');

var canvas = document.getElementById('game');
var context = canvas.getContext('2d');

var copter1 = new Copter(200, 280, 20, 20);
copter1.draw();

var boundaries = [];
boundaries.push(new Boundary(0, 0, 800, 20));
boundaries.push(new Boundary(0, 580, 800, 20));

var obstacles = [];
obstacles.push(new Obstacle(1400, 400, 20, 100));
obstacles.push(new Obstacle(1100, 60, 20, 120));
obstacles.push(new Obstacle(800, 250, 20, 120));

window.requestAnimationFrame(function gameLoop() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  copter1.draw().gravity();
  boundaries.forEach(function(boundary){
    boundary.draw();
  });
  obstacles.forEach(function(obstacle){
    if (obstacle.x === 0) {
      obstacle.x = 900;
      obstacle.shuffle();
    }
    obstacle.draw().move();
  });
  requestAnimationFrame(gameLoop);
});

window.addEventListener('keypress', function (event) {
  event.preventDefault();
  if (event.keyCode === 32) {
    copter1.upLift();
  }
});
<commit_msg>collision detection is working with alert for obstacles<commit_after>const Copter = require('./copter');
const Obstacle = require('./obstacle');
const Boundary = require('./boundary');

var canvas = document.getElementById('game');
var context = canvas.getContext('2d');

var copter1 = new Copter(200, 280, 20, 20);
copter1.draw();

var boundaries = [];
boundaries.push(new Boundary(0, 0, 800, 20));
boundaries.push(new Boundary(0, 580, 800, 20));

var obstacles = [];
obstacles.push(new Obstacle(1400, 400, 20, 100));
obstacles.push(new Obstacle(1100, 60, 20, 120));
obstacles.push(new Obstacle(800, 250, 20, 120));

window.requestAnimationFrame(function gameLoop() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  copter1.draw().gravity();
  boundaries.forEach(function(boundary){
    boundary.draw();
  });
  obstacles.forEach(function(obstacle){
    if (obstacle.x === 0) {
      obstacle.x = 900;
      obstacle.shuffle();
    }
    if (copter1.x < obstacle.x + obstacle.width &&
      copter1.x + copter1.width > obstacle.x &&
      copter1.y < obstacle.y + obstacle.height &&
      copter1.height + copter1.y > obstacle.y) {
        // collision detected!
        alert('game over');
      }
    obstacle.draw().move();
  });
  requestAnimationFrame(gameLoop);
});

window.addEventListener('keypress', function (event) {
  event.preventDefault();
  if (event.keyCode === 32) {
    copter1.upLift();
  }
});
<|endoftext|>