<commit_before>#include <iostream>
using std::cout;
using std::endl;

#include <boost/multi_array.hpp>

typedef boost::multi_array<float,1> array_f;

// class definition
class Test
{
public:
  Test( float, float, float );
  void printarr();
  void setarr( float, float, float );
  array_f& getarr();

private:
  array_f arrmem;
};

// Define some function
float vectorsum( array_f& );

// implement function
float vectorsum( array_f& h )
{
  float sum = 0;
  for ( int i=0; i<3; i++)
    sum += h[i];
  return sum;
}

// constructor
Test::Test( float x, float y, float z )
  : arrmem( boost::extents[3] )
{
  setarr( x, y, z );
}

// Set arr function
void Test::setarr( float x, float y, float z )
{
  arrmem[0] = x;
  arrmem[1] = y;
  arrmem[2] = z;
}

// get arr function
array_f& Test::getarr()
{
  return arrmem;
}

// print function
void Test::printarr()
{
  cout << arrmem[0] << arrmem[1] << arrmem[2] << endl;
}

int main( void )
{
  Test t( 1.0, 2.0, 3.0 );
  cout << "Created test class instance with 1.0 2.0 3.0" << endl;
  t.printarr();

  t.setarr( 6.0, 5.0, 4.0 );
  cout << "Set array to 4.0 5.0 6.0" << endl;
  t.printarr();

  array_f arr( boost::extents[3] );
  cout << "Created boost array" << endl;

  arr[0] = 1.2;
  arr[1] = 2.2;
  arr[2] = 3.2;

  cout << "Sum of vector [1.2,2.2,3.2] is..." << endl;
  cout << vectorsum( arr ) << endl;

  return 1;
}
<commit_msg>Some more small examples written to boosttest<commit_after>#include <iostream>
using std::cout;
using std::endl;

#include <boost/multi_array.hpp>

typedef boost::multi_array<float,1> array_f;

// class definition
class Test
{
public:
  Test( float, float, float );
  void printarr();
  void setarr( float, float, float );
  array_f& getarr();

private:
  array_f arrmem;
};

// Define some function
float vectorsum( array_f& );

// implement function
float vectorsum( array_f& h )
{
  float sum = 0;
  for ( int i=0; i<3; i++)
    sum += h[i];
  return sum;
}

// constructor
Test::Test( float x, float y, float z )
  : arrmem( boost::extents[3] )
{
  setarr( x, y, z );
}

// Set arr function
void Test::setarr( float x, float y, float z )
{
  arrmem[0] = x;
  arrmem[1] = y;
  arrmem[2] = z;
}

// get arr function
array_f& Test::getarr()
{
  return arrmem;
}

// print function
void Test::printarr()
{
  cout << arrmem[0] << arrmem[1] << arrmem[2] << endl;
}

int main( void )
{
  Test t( 1.0, 2.0, 3.0 );
  cout << "Created test class instance with 1.0 2.0 3.0" << endl;
  t.printarr();

  t.setarr( 6.0, 5.0, 4.0 );
  cout << "Set array to 4.0 5.0 6.0" << endl;
  t.printarr();

  array_f arr( boost::extents[3] );
  cout << "Created boost array" << endl;

  arr[0] = 1.2;
  arr[1] = 2.2;
  arr[2] = 3.2;

  cout << "Sum of vector [1.2,2.2,3.2] is..." << endl;
  cout << vectorsum( arr ) << endl;

  array_f x( boost::extents[2] );
  x[0] = 1;
  x[1] = 0;
  array_f& xref = x;

  array_f y( boost::extents[2] );
  y = xref;
  y[1] = 2;
  cout << "y is [" << y[0] << "," << y[1] << "]" << endl;
  cout << "x is [" << x[0] << "," << x[1] << "]" << endl;

  return 1;
}
<|endoftext|>


<commit_before>//=====================================================================
//
// CoreTimer.cpp -
//
// Created by skywind on 2021/12/01
// Last Modified: 2021/12/01 17:44:14
//
//=====================================================================

#include <stddef.h>
#include <assert.h>

#include "CoreTimer.h"

//---------------------------------------------------------------------
// ctor
//---------------------------------------------------------------------
Timer::Timer(Scheduler *sched)
{
	_sched = sched;
	callback = NULL;
	user = NULL;
	timestamp = 0;
	itimer_evt_init(&_evt, evt_callback, this, NULL);
}

//---------------------------------------------------------------------
// dtor
//---------------------------------------------------------------------
Timer::~Timer()
{
	stop();
	user = NULL;
	callback = NULL;
	_sched = NULL;
}

//---------------------------------------------------------------------
// callback
//---------------------------------------------------------------------
void Timer::evt_callback(void *obj, void *user)
{
	Timer *self = (Timer*)obj;
	if (self->callback) {
		if (self->_sched) {
			// 更新标准时间戳
			self->timestamp = self->_sched->_mgr.current;
		}
		self->callback(self);
	}
}

//---------------------------------------------------------------------
// start timer
//---------------------------------------------------------------------
bool Timer::start(uint32_t period, int repeat)
{
	assert(_sched != NULL);
	if (_sched == NULL) {
		return false;
	}
	if (_sched->_inited == false) {
		return false;
	}
	itimer_evt_start(&(_sched->_mgr), &_evt, period, repeat);
	return true;
}

//---------------------------------------------------------------------
// stop timer
//---------------------------------------------------------------------
void Timer::stop()
{
	assert(_sched != NULL);
	itimer_evt_stop(&(_sched->_mgr), &_evt);
}

//---------------------------------------------------------------------
// check is running
//---------------------------------------------------------------------
bool Timer::is_running() const
{
	if (_sched) {
		return itimer_evt_status(&_evt)? true : false;
	}
	return false;
}

//---------------------------------------------------------------------
// 返回还剩多少次调用
//---------------------------------------------------------------------
int Timer::remain() const
{
	return _evt.remain;
}

//---------------------------------------------------------------------
// ctor
//---------------------------------------------------------------------
Scheduler::Scheduler()
{
	_inited = false;
	itimer_mgr_init(&_mgr, 0, 10);
}

//---------------------------------------------------------------------
// dtor
//---------------------------------------------------------------------
Scheduler::~Scheduler()
{
	itimer_mgr_destroy(&_mgr);
}

//---------------------------------------------------------------------
// init
//---------------------------------------------------------------------
void Scheduler::init(uint32_t current, uint32_t interval)
{
	if (_inited) {
		itimer_mgr_destroy(&_mgr);
	}
	itimer_mgr_init(&_mgr, current, interval);
	_inited = true;
}

//---------------------------------------------------------------------
// update timers
//---------------------------------------------------------------------
void Scheduler::update(uint32_t current)
{
	if (_inited) {
		itimer_mgr_run(&_mgr, current);
	}
}

<commit_msg>commit new CoreTimer.cpp<commit_after>//=====================================================================
//
// CoreTimer.cpp -
//
// Created by skywind on 2021/12/01
// Last Modified: 2021/12/01 17:44:14
//
//=====================================================================

#include <stddef.h>
#include <assert.h>

#include "CoreTimer.h"

//---------------------------------------------------------------------
// ctor
//---------------------------------------------------------------------
Timer::Timer(Scheduler *sched)
{
	_sched = sched;
	callback = NULL;
	user = NULL;
	timestamp = 0;
	itimer_evt_init(&_evt, evt_callback, this, NULL);
}

//---------------------------------------------------------------------
// dtor
//---------------------------------------------------------------------
Timer::~Timer()
{
	stop();
	user = NULL;
	callback = NULL;
	_sched = NULL;
}

//---------------------------------------------------------------------
// callback
//---------------------------------------------------------------------
void Timer::evt_callback(void *obj, void *user)
{
	Timer *self = (Timer*)obj;
	if (self->callback) {
		if (self->_sched) {
			// 更新标准时间戳
			self->timestamp = self->_sched->_mgr.current;
		}
		self->callback(self);
	}
}

//---------------------------------------------------------------------
// start timer
//---------------------------------------------------------------------
bool Timer::start(uint32_t period, int repeat)
{
	assert(_sched != NULL);
	if (_sched == NULL) {
		return false;
	}
	if (_sched->_inited == false) {
		return false;
	}
	itimer_evt_start(&(_sched->_mgr), &_evt, period, repeat);
	return true;
}

//---------------------------------------------------------------------
// stop timer
//---------------------------------------------------------------------
void Timer::stop()
{
	assert(_sched != NULL);
	itimer_evt_stop(&(_sched->_mgr), &_evt);
}

//---------------------------------------------------------------------
// check is running
//---------------------------------------------------------------------
bool Timer::is_running() const
{
	if (_sched) {
		return itimer_evt_status(&_evt)? true : false;
	}
	return false;
}

//---------------------------------------------------------------------
// 返回还剩多少次调用
//---------------------------------------------------------------------
int Timer::remain() const
{
	return _evt.remain;
}

//---------------------------------------------------------------------
// ctor
//---------------------------------------------------------------------
Scheduler::Scheduler()
{
	_inited = false;
	itimer_mgr_init(&_mgr, 0, 5);
}

//---------------------------------------------------------------------
// dtor
//---------------------------------------------------------------------
Scheduler::~Scheduler()
{
	itimer_mgr_destroy(&_mgr);
}

//---------------------------------------------------------------------
// init
//---------------------------------------------------------------------
void Scheduler::init(uint32_t current, uint32_t interval)
{
	if (_inited) {
		itimer_mgr_destroy(&_mgr);
	}
	itimer_mgr_init(&_mgr, current, interval);
	_inited = true;
}

//---------------------------------------------------------------------
// update timers
//---------------------------------------------------------------------
void Scheduler::update(uint32_t current)
{
	itimer_mgr_run(&_mgr, current);
}

<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS a11ysep (1.1.2); FILE ADDED 2007/02/28 07:26:18 fs 1.1.2.3: #i10000# 2005/09/28 11:36:43 fs 1.1.2.2: manual resync (files have been moved herein from another location): licence change 2005/03/07 08:29:21 fs 1.1.2.1: #i44293# moved implementations herein from svtools module<commit_after><|endoftext|>


<commit_before><commit_msg>COMP: avoid definition of SpectralForwardModelImageFilter for DRM binning<commit_after><|endoftext|>


<commit_before>// lab3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <queue>
#include <iostream>
#include <random>
#include <Windows.h>

using namespace std;

queue<int> numbers;
const int NUMBER_COUNT = 100;

//
void GenerateNumbers();
void ProcessNumbers(int*);

//
int _tmain(int argc, _TCHAR* argv[])
{
	int sum;

	//     ( ).
	//srand(200);

	GenerateNumbers();
	ProcessNumbers(&sum);

	return 0;
}

void GenerateNumbers()
{
	for (size_t i = 0; i < NUMBER_COUNT; i++)
	{
		//      0-99
		numbers.push(rand()%100);
		cout << "Generated number " << numbers.back() << endl;
		//    (  )
		Sleep(2000);
	}
}

void ProcessNumbers(int* sumAddress)
{
	while (numbers.size() != 0)
	{
		//
		int current = numbers.front();
		cout << "Processing element " << current << endl;
		//
		numbers.pop();
		//   ,
		*sumAddress+=current;
		//    (  )
		Sleep(2000);
	}
}<commit_msg>Флаг завершения генератора<commit_after>// lab3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <queue>
#include <iostream>
#include <random>
#include <Windows.h>

using namespace std;

queue<int> numbers;
const int NUMBER_COUNT = 100;
volatile bool GeneratorCompleted = FALSE;

//
void GenerateNumbers();
void ProcessNumbers(int*);

//
int _tmain(int argc, _TCHAR* argv[])
{
	int sum;

	//     ( ).
	//srand(200);

	GenerateNumbers();
	ProcessNumbers(&sum);

	return 0;
}

void GenerateNumbers()
{
	for (size_t i = 0; i < NUMBER_COUNT; i++)
	{
		//      0-99
		numbers.push(rand()%100);
		cout << "Generated number " << numbers.back() << endl;
		//    (  )
		Sleep(2000);
	}
	GeneratorCompleted = TRUE;
}

void ProcessNumbers(int* sumAddress)
{
	while (!GeneratorCompleted)
	{
		while (numbers.size() != 0)
		{
			//
			int current = numbers.front();
			cout << "Processing element " << current << endl;
			//
			numbers.pop();
			//   ,
			*sumAddress += current;
			//    (  )
			Sleep(1000);
		}
	}
}<|endoftext|>


<commit_before>#include <AndroidClient.h>
#include <jni.h>
#include <android/log.h>

class AndroidClient : public HTTPClient {
 public:

	AndroidClient(JNIEnv * _env, const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive)
 : HTTPClient(_user_agent, _enable_cookies, _enable_keepalive), env(_env) {

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient Constructor called");

	}

	void androidInit(){

		cookieManagerClass =  env->FindClass("android/webkit/CookieManager");
		httpClass = env->FindClass("java/net/HttpURLConnection");
		urlClass = env->FindClass("java/net/URL");
	 	inputStreamClass = env->FindClass("java/io/InputStream");

		getHeaderMethod = env->GetMethodID(httpClass, "getHeaderField", "(Ljava/lang/String;)Ljava/lang/String;");
	 	readMethod = env->GetMethodID(inputStreamClass, "read", "([B)I");
	 	urlConstructor =  env->GetMethodID(urlClass, "<init>", "(Ljava/lang/String;)V");
		openConnectionMethod = env->GetMethodID(urlClass, "openConnection", "()Ljava/net/URLConnection;");
		setRequestProperty = env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		setRequestMethod = env->GetMethodID(httpClass, "setRequestMethod", "(Ljava/lang/String;)V");
		setFollowMethod = env->GetMethodID(httpClass, "setInstanceFollowRedirects", "(Z)V");
		setDoInputMethod = env->GetMethodID(httpClass, "setDoInput", "(Z)V");
		connectMethod = env->GetMethodID(httpClass, "connect", "()V");
		getResponseCodeMethod = env->GetMethodID(httpClass, "getResponseCode", "()I");
		getResponseMessageMethod = env->GetMethodID(httpClass, "getResponseMessage", "()Ljava/lang/String;");
		setRequestPropertyMethod =  env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		clearCookiesMethod =  env->GetMethodID(cookieManagerClass, "removeAllCookie", "()V");
		getInputStreamMethod =  env->GetMethodID(httpClass, "getInputStream", "()Ljava/io/InputStream;");

		initDone = true;

	}

  HTTPResponse request(const HTTPRequest & req, const Authorization & auth){

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient request called");

  	if (!initDone){
  		androidInit();
  	}

  	jobject url = env->NewObject(urlClass, urlConstructor, env->NewStringUTF(req.getURI().c_str()));
  	jobject connection = env->CallObjectMethod(url, openConnectionMethod);

  	//Authorization example
		//env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF("Authorization"), env->NewStringUTF("myUsername"));

		//  std::string auth_header = auth.createHeader();

		// if (!auth_header.empty()) {
		//		env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF(auth.getHeaderName()), env->NewStringUTF(auth_header.c_str()));
		//}

		env->CallVoidMethod(connection, setFollowMethod, req.getFollowLocation() ? JNI_TRUE : JNI_FALSE);

		switch (req.getType()) {
		case HTTPRequest::POST:
			env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("POST"));
			break;
		case HTTPRequest::GET:
			env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("GET"));
			;
			break;
		}

		int responseCode = env->CallIntMethod(connection, getResponseCodeMethod);

		if (env->ExceptionCheck()) {
			env->ExceptionClear();
			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "EXCEPTION http request responsecode = %i", responseCode);
			return HTTPResponse(0, "exception");
		}
		__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "http request responsecode = %i", responseCode);

		const char *errorMessage = "";

		if (responseCode >= 400 && responseCode <= 599){
			jstring javaMessage = (jstring)env->CallObjectMethod(connection, getResponseMessageMethod);
			errorMessage = env->GetStringUTFChars(javaMessage, 0);

		}

		jobject input = env->CallObjectMethod(connection, getInputStreamMethod);
		env->ExceptionClear();

		jbyteArray array = env->NewByteArray(4096);
		int g = 0;
		std::string content;

		while ((g = env->CallIntMethod(input, readMethod, array)) != -1) {

			jbyte* content_array = env->GetByteArrayElements(array, NULL);
			if (callback) {
				callback->handleChunk(g, (char*) content_array);
			} else {
				content += std::string((char*) content_array, g);
			}

			env->ReleaseByteArrayElements(array, content_array, JNI_ABORT);

		}

		const char *followString = "";

		if (responseCode >= 300 && responseCode <= 399) {

			jstring followURL = (jstring)env->CallObjectMethod(connection, getHeaderMethod, env->NewStringUTF("location"));
			followString = env->GetStringUTFChars(followURL, 0);

			__android_log_print(ANDROID_LOG_INFO, "content", "followURL = %s", followString);

		}

		__android_log_print(ANDROID_LOG_INFO, "content", "contentti = %Ld", content.size());

		return HTTPResponse(responseCode, errorMessage, followString, content);

  }

  void clearCookies() {

  	env->CallVoidMethod(cookieManagerClass, clearCookiesMethod);

  }

 protected:
  bool initialize() { return true; }

 private:
	bool initDone = false;

  JNIEnv * env;
  jclass cookieManagerClass;
  jmethodID clearCookiesMethod;

  jclass bitmapClass;
  jclass factoryClass;
  jclass httpClass;
  jclass urlClass;
  jclass bufferedReaderClass;
  jclass inputStreamReaderClass;
  jclass inputStreamClass;
  jmethodID urlConstructor;
  jmethodID openConnectionMethod;
  jmethodID setRequestProperty;
  jmethodID setRequestMethod;
  jmethodID setDoInputMethod;
  jmethodID connectMethod;
  jmethodID getResponseCodeMethod;
  jmethodID getResponseMessageMethod;
  jmethodID setRequestPropertyMethod;
  jmethodID outputStreamConstructor;
  jmethodID factoryDecodeMethod;
  jmethodID getInputStreamMethod;
  jmethodID bufferedReaderConstructor;
  jmethodID inputStreamReaderConstructor;
  jmethodID readLineMethod;
  jmethodID readerCloseMethod;
  jmethodID readMethod;
  jmethodID inputStreamCloseMethod;
  jmethodID setFollowMethod;
  jmethodID getHeaderMethod;

};

std::shared_ptr<HTTPClient>
AndroidClientFactory::createClient(const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive) {
  return std::make_shared<AndroidClient>(env, _user_agent, _enable_cookies, _enable_keepalive);
}

<commit_msg>Change exception error message in exception check<commit_after>#include <AndroidClient.h>
#include <jni.h>
#include <android/log.h>

class AndroidClient : public HTTPClient {
 public:

	AndroidClient(JNIEnv * _env, const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive)
 : HTTPClient(_user_agent, _enable_cookies, _enable_keepalive), env(_env) {

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient Constructor called");

	}

	void androidInit(){

		cookieManagerClass =  env->FindClass("android/webkit/CookieManager");
		httpClass = env->FindClass("java/net/HttpURLConnection");
		urlClass = env->FindClass("java/net/URL");
	 	inputStreamClass = env->FindClass("java/io/InputStream");

		getHeaderMethod = env->GetMethodID(httpClass, "getHeaderField", "(Ljava/lang/String;)Ljava/lang/String;");
	 	readMethod = env->GetMethodID(inputStreamClass, "read", "([B)I");
	 	urlConstructor =  env->GetMethodID(urlClass, "<init>", "(Ljava/lang/String;)V");
		openConnectionMethod = env->GetMethodID(urlClass, "openConnection", "()Ljava/net/URLConnection;");
		setRequestProperty = env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		setRequestMethod = env->GetMethodID(httpClass, "setRequestMethod", "(Ljava/lang/String;)V");
		setFollowMethod = env->GetMethodID(httpClass, "setInstanceFollowRedirects", "(Z)V");
		setDoInputMethod = env->GetMethodID(httpClass, "setDoInput", "(Z)V");
		connectMethod = env->GetMethodID(httpClass, "connect", "()V");
		getResponseCodeMethod = env->GetMethodID(httpClass, "getResponseCode", "()I");
		getResponseMessageMethod = env->GetMethodID(httpClass, "getResponseMessage", "()Ljava/lang/String;");
		setRequestPropertyMethod =  env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		clearCookiesMethod =  env->GetMethodID(cookieManagerClass, "removeAllCookie", "()V");
		getInputStreamMethod =  env->GetMethodID(httpClass, "getInputStream", "()Ljava/io/InputStream;");

		initDone = true;

	}

  HTTPResponse request(const HTTPRequest & req, const Authorization & auth){

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient request called");

  	if (!initDone){
  		androidInit();
  	}

  	jobject url = env->NewObject(urlClass, urlConstructor, env->NewStringUTF(req.getURI().c_str()));
  	jobject connection = env->CallObjectMethod(url, openConnectionMethod);

  	//Authorization example
		//env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF("Authorization"), env->NewStringUTF("myUsername"));

		//  std::string auth_header = auth.createHeader();

		// if (!auth_header.empty()) {
		//		env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF(auth.getHeaderName()), env->NewStringUTF(auth_header.c_str()));
		//}

		env->CallVoidMethod(connection, setFollowMethod, req.getFollowLocation() ? JNI_TRUE : JNI_FALSE);

		switch (req.getType()) {
		case HTTPRequest::POST:
			env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("POST"));
			break;
		case HTTPRequest::GET:
			env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("GET"));
			;
			break;
		}

		int responseCode = env->CallIntMethod(connection, getResponseCodeMethod);

		if (env->ExceptionCheck()) {
			env->ExceptionClear();
			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "EXCEPTION http request responsecode = %i", responseCode);
			return HTTPResponse(0, "Server not found");
		}
		__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "http request responsecode = %i", responseCode);

		const char *errorMessage = "";

		if (responseCode >= 400 && responseCode <= 599){
			jstring javaMessage = (jstring)env->CallObjectMethod(connection, getResponseMessageMethod);
			errorMessage = env->GetStringUTFChars(javaMessage, 0);

		}

		jobject input = env->CallObjectMethod(connection, getInputStreamMethod);
		env->ExceptionClear();

		jbyteArray array = env->NewByteArray(4096);
		int g = 0;
		std::string content;

		while ((g = env->CallIntMethod(input, readMethod, array)) != -1) {

			jbyte* content_array = env->GetByteArrayElements(array, NULL);
			if (callback) {
				callback->handleChunk(g, (char*) content_array);
			} else {
				content += std::string((char*) content_array, g);
			}

			env->ReleaseByteArrayElements(array, content_array, JNI_ABORT);

		}

		const char *followString = "";

		if (responseCode >= 300 && responseCode <= 399) {

			jstring followURL = (jstring)env->CallObjectMethod(connection, getHeaderMethod, env->NewStringUTF("location"));
			followString = env->GetStringUTFChars(followURL, 0);

			__android_log_print(ANDROID_LOG_INFO, "content", "followURL = %s", followString);

		}

		__android_log_print(ANDROID_LOG_INFO, "content", "contentti = %Ld", content.size());

		return HTTPResponse(responseCode, errorMessage, followString, content);

  }

  void clearCookies() {

  	env->CallVoidMethod(cookieManagerClass, clearCookiesMethod);

  }

 protected:
  bool initialize() { return true; }

 private:
	bool initDone = false;

  JNIEnv * env;
  jclass cookieManagerClass;
  jmethodID clearCookiesMethod;

  jclass bitmapClass;
  jclass factoryClass;
  jclass httpClass;
  jclass urlClass;
  jclass bufferedReaderClass;
  jclass inputStreamReaderClass;
  jclass inputStreamClass;
  jmethodID urlConstructor;
  jmethodID openConnectionMethod;
  jmethodID setRequestProperty;
  jmethodID setRequestMethod;
  jmethodID setDoInputMethod;
  jmethodID connectMethod;
  jmethodID getResponseCodeMethod;
  jmethodID getResponseMessageMethod;
  jmethodID setRequestPropertyMethod;
  jmethodID outputStreamConstructor;
  jmethodID factoryDecodeMethod;
  jmethodID getInputStreamMethod;
  jmethodID bufferedReaderConstructor;
  jmethodID inputStreamReaderConstructor;
  jmethodID readLineMethod;
  jmethodID readerCloseMethod;
  jmethodID readMethod;
  jmethodID inputStreamCloseMethod;
  jmethodID setFollowMethod;
  jmethodID getHeaderMethod;

};

std::shared_ptr<HTTPClient>
AndroidClientFactory::createClient(const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive) {
  return std::make_shared<AndroidClient>(env, _user_agent, _enable_cookies, _enable_keepalive);
}

<|endoftext|>


<commit_before>#include <AndroidClient.h>
#include <jni.h>
#include <android/log.h>

class AndroidClient : public HTTPClient {
 public:

	AndroidClient(JNIEnv * _env, const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive)
 : HTTPClient(_user_agent, _enable_cookies, _enable_keepalive), env(_env) {

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient Constructor called");

	}

	void androidInit(){

		cookieManagerClass =  env->FindClass("android/webkit/CookieManager");
		httpClass = env->FindClass("java/net/HttpURLConnection");
		urlClass = env->FindClass("java/net/URL");
	 	inputStreamClass = env->FindClass("java/io/InputStream");

		getHeaderMethod = env->GetMethodID(httpClass, "getHeaderField", "(Ljava/lang/String;)Ljava/lang/String;");
		getHeaderMethodInt = env->GetMethodID(httpClass, "getHeaderField", "(I)Ljava/lang/String;");
		getHeaderKeyMethod = env->GetMethodID(httpClass, "getHeaderFieldKey", "(I)Ljava/lang/String;");
	 	readMethod = env->GetMethodID(inputStreamClass, "read", "([B)I");
	 	urlConstructor =  env->GetMethodID(urlClass, "<init>", "(Ljava/lang/String;)V");
		openConnectionMethod = env->GetMethodID(urlClass, "openConnection", "()Ljava/net/URLConnection;");
		setRequestProperty = env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		setRequestMethod = env->GetMethodID(httpClass, "setRequestMethod", "(Ljava/lang/String;)V");
		setFollowMethod = env->GetMethodID(httpClass, "setInstanceFollowRedirects", "(Z)V");
		setDoInputMethod = env->GetMethodID(httpClass, "setDoInput", "(Z)V");
		connectMethod = env->GetMethodID(httpClass, "connect", "()V");
		getResponseCodeMethod = env->GetMethodID(httpClass, "getResponseCode", "()I");
		getResponseMessageMethod = env->GetMethodID(httpClass, "getResponseMessage", "()Ljava/lang/String;");
		setRequestPropertyMethod =  env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		clearCookiesMethod =  env->GetMethodID(cookieManagerClass, "removeAllCookie", "()V");
		getInputStreamMethod =  env->GetMethodID(httpClass, "getInputStream", "()Ljava/io/InputStream;");
		getErrorStreamMethod =  env->GetMethodID(httpClass, "getErrorStream", "()Ljava/io/InputStream;");

		initDone = true;

	}

  HTTPResponse request(const HTTPRequest & req, const Authorization & auth){

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient request called");

  	if (!initDone){
  		androidInit();
  	}

  	jobject url = env->NewObject(urlClass, urlConstructor, env->NewStringUTF(req.getURI().c_str()));
  	jobject connection = env->CallObjectMethod(url, openConnectionMethod);

  	//Authorization example
		//env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF("Authorization"), env->NewStringUTF("myUsername"));

		//  std::string auth_header = auth.createHeader();

		// if (!auth_header.empty()) {
		//		env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF(auth.getHeaderName()), env->NewStringUTF(auth_header.c_str()));
		//}

		env->CallVoidMethod(connection, setFollowMethod, req.getFollowLocation() ? JNI_TRUE : JNI_FALSE);

		switch (req.getType()) {
		case HTTPRequest::POST:
			env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("POST"));
			break;
		case HTTPRequest::GET:
			env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("GET"));
			;
			break;
		}

		int responseCode = env->CallIntMethod(connection, getResponseCodeMethod);

		//Server not found error
		if (env->ExceptionCheck()) {
			env->ExceptionClear();
			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "EXCEPTION http request responsecode = %i", responseCode);
			return HTTPResponse(0, "Server not found");
		}

		const char *errorMessage = "";
		jobject input;

		if (responseCode >= 400 && responseCode <= 599 ){
			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "request responsecode = %i", responseCode);

			jstring javaMessage = (jstring)env->CallObjectMethod(connection, getResponseMessageMethod);
			errorMessage = env->GetStringUTFChars(javaMessage, 0);

			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "errorMessage = %s", errorMessage);
			input = env->CallObjectMethod(connection, getErrorStreamMethod);

		} else {

			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "http request responsecode = %i", responseCode);

			input = env->CallObjectMethod(connection, getInputStreamMethod);
			env->ExceptionClear();
		}

		jbyteArray array = env->NewByteArray(4096);
		int g = 0;

		HTTPResponse response;
		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Starting to gather content");

		//Gather content
		while ((g = env->CallIntMethod(input, readMethod, array)) != -1) {

			jbyte* content_array = env->GetByteArrayElements(array, NULL);
			if (callback) {
				callback->handleChunk(g, (char*) content_array);
			} else {
				response.appendContent(std::string((char*) content_array, g));
			}
			env->ReleaseByteArrayElements(array, content_array, JNI_ABORT);
		}

		//Gather headers and values
		for (int i = 0; i < 1000; i++) {
			auto headerKey = env->GetStringUTFChars((jstring) env->CallObjectMethod(connection, getHeaderKeyMethod, i), 0);
			__android_log_print(ANDROID_LOG_INFO, "content", "header key = %s", headerKey);
			auto header = env->GetStringUTFChars((jstring) env->CallObjectMethod(connection, getHeaderMethodInt, i), 0);
			__android_log_print(ANDROID_LOG_INFO, "content", "header value = %s", header);
			if (headerKey == NULL) {
				break;
			}
			response.addHeader(headerKey, header);
		}

		response.setResultCode(responseCode);

		if (responseCode >= 300 && responseCode <= 399) {

			jstring followURL = (jstring)env->CallObjectMethod(connection, getHeaderMethod, env->NewStringUTF("location"));
			const char *followString = env->GetStringUTFChars(followURL, 0);
			response.setRedirectUrl(followString);
			env->ReleaseStringUTFChars(followURL, followString);
			__android_log_print(ANDROID_LOG_INFO, "content", "followURL = %s", followString);

		}

//		response.addHeader("", "");
		return response; // HTTPResponse(responseCode, errorMessage, followString, content);

  }

  void clearCookies() {

  	env->CallVoidMethod(cookieManagerClass, clearCookiesMethod);

  }

 protected:
  bool initialize() { return true; }

 private:
	bool initDone = false;

  JNIEnv * env;
  jclass cookieManagerClass;
  jmethodID clearCookiesMethod;

  jclass bitmapClass;
  jclass factoryClass;
  jclass httpClass;
  jclass urlClass;
  jclass bufferedReaderClass;
  jclass inputStreamReaderClass;
  jclass inputStreamClass;
  jmethodID urlConstructor;
  jmethodID openConnectionMethod;
  jmethodID setRequestProperty;
  jmethodID setRequestMethod;
  jmethodID setDoInputMethod;
  jmethodID connectMethod;
  jmethodID getResponseCodeMethod;
  jmethodID getResponseMessageMethod;
  jmethodID setRequestPropertyMethod;
  jmethodID outputStreamConstructor;
  jmethodID factoryDecodeMethod;
  jmethodID getInputStreamMethod;
  jmethodID getErrorStreamMethod;
  jmethodID bufferedReaderConstructor;
  jmethodID inputStreamReaderConstructor;
  jmethodID readLineMethod;
  jmethodID readerCloseMethod;
  jmethodID readMethod;
  jmethodID inputStreamCloseMethod;
  jmethodID setFollowMethod;
  jmethodID getHeaderMethod;
  jmethodID getHeaderMethodInt;
  jmethodID getHeaderKeyMethod;

};

std::shared_ptr<HTTPClient>
AndroidClientFactory::createClient(const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive) {
  return std::make_shared<AndroidClient>(env, _user_agent, _enable_cookies, _enable_keepalive);
}
<commit_msg>Get headers from request and add them<commit_after>#include <AndroidClient.h>
#include <jni.h>
#include <android/log.h>
#include <vector>

class AndroidClient : public HTTPClient {
 public:

	AndroidClient(JNIEnv * _env, const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive)
 : HTTPClient(_user_agent, _enable_cookies, _enable_keepalive), env(_env) {

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient Constructor called");

	}

	void androidInit(){

		cookieManagerClass =  env->FindClass("android/webkit/CookieManager");
		httpClass = env->FindClass("java/net/HttpURLConnection");
		urlClass = env->FindClass("java/net/URL");
	 	inputStreamClass = env->FindClass("java/io/InputStream");

		getHeaderMethod = env->GetMethodID(httpClass, "getHeaderField", "(Ljava/lang/String;)Ljava/lang/String;");
		getHeaderMethodInt = env->GetMethodID(httpClass, "getHeaderField", "(I)Ljava/lang/String;");
		getHeaderKeyMethod = env->GetMethodID(httpClass, "getHeaderFieldKey", "(I)Ljava/lang/String;");
	 	readMethod = env->GetMethodID(inputStreamClass, "read", "([B)I");
	 	urlConstructor =  env->GetMethodID(urlClass, "<init>", "(Ljava/lang/String;)V");
		openConnectionMethod = env->GetMethodID(urlClass, "openConnection", "()Ljava/net/URLConnection;");
		setRequestProperty = env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		setRequestMethod = env->GetMethodID(httpClass, "setRequestMethod", "(Ljava/lang/String;)V");
		setFollowMethod = env->GetMethodID(httpClass, "setInstanceFollowRedirects", "(Z)V");
		setDoInputMethod = env->GetMethodID(httpClass, "setDoInput", "(Z)V");
		connectMethod = env->GetMethodID(httpClass, "connect", "()V");
		getResponseCodeMethod = env->GetMethodID(httpClass, "getResponseCode", "()I");
		getResponseMessageMethod = env->GetMethodID(httpClass, "getResponseMessage", "()Ljava/lang/String;");
		setRequestPropertyMethod =  env->GetMethodID(httpClass, "setRequestProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
		clearCookiesMethod =  env->GetMethodID(cookieManagerClass, "removeAllCookie", "()V");
		getInputStreamMethod =  env->GetMethodID(httpClass, "getInputStream", "()Ljava/io/InputStream;");
		getErrorStreamMethod =  env->GetMethodID(httpClass, "getErrorStream", "()Ljava/io/InputStream;");

		initDone = true;

	}

  HTTPResponse request(const HTTPRequest & req, const Authorization & auth){

		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "AndroidClient request called");

  	if (!initDone){
  		androidInit();
  	}

  	jobject url = env->NewObject(urlClass, urlConstructor, env->NewStringUTF(req.getURI().c_str()));
  	jobject connection = env->CallObjectMethod(url, openConnectionMethod);

  	//Authorization example
		//env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF("Authorization"), env->NewStringUTF("myUsername"));

		//  std::string auth_header = auth.createHeader();

		// if (!auth_header.empty()) {
		//		env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF(auth.getHeaderName()), env->NewStringUTF(auth_header.c_str()));
		//}

		env->CallVoidMethod(connection, setFollowMethod, req.getFollowLocation() ? JNI_TRUE : JNI_FALSE);

		//Setting headers for request
		auto headerMap = req.getHeaders();
		std::vector<std::string> headerNames;
		std::vector<std::string> headerValues;

		for (std::map<std::string, std::string>::iterator i = headerMap.begin(); i != headerMap.end(); ++i)
		{
			headerNames.insert(headerNames.end(), i->first.c_str());
			headerValues.insert(headerValues.end(), i->second.c_str());
		}

		for (int i = 0; i<headerNames.size(); i++){
			__android_log_print(ANDROID_LOG_INFO, "httpRequest", "Setting header property name = %s", headerNames[i].c_str());
			__android_log_print(ANDROID_LOG_INFO, "httpRequest", "Setting header property value = %s", headerValues[i].c_str());
		env->CallVoidMethod(connection, setRequestPropertyMethod, env->NewStringUTF(headerNames[i].c_str()), env->NewStringUTF(headerValues[i].c_str()));
		}

		switch (req.getType()) {
		case HTTPRequest::POST:
			env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("POST"));
			break;
		case HTTPRequest::GET:
			env->CallVoidMethod(connection, setRequestMethod, env->NewStringUTF("GET"));
			;
			break;
		}

		int responseCode = env->CallIntMethod(connection, getResponseCodeMethod);

		//Server not found error
		if (env->ExceptionCheck()) {
			env->ExceptionClear();
			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "EXCEPTION http request responsecode = %i", responseCode);
			return HTTPResponse(0, "Server not found");
		}

		const char *errorMessage = "";
		jobject input;

		if (responseCode >= 400 && responseCode <= 599 ){
			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "request responsecode = %i", responseCode);

			jstring javaMessage = (jstring)env->CallObjectMethod(connection, getResponseMessageMethod);
			errorMessage = env->GetStringUTFChars(javaMessage, 0);

			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "errorMessage = %s", errorMessage);
			input = env->CallObjectMethod(connection, getErrorStreamMethod);

		} else {

			__android_log_print(ANDROID_LOG_INFO, "AndroidClient", "http request responsecode = %i", responseCode);

			input = env->CallObjectMethod(connection, getInputStreamMethod);
			env->ExceptionClear();
		}

		jbyteArray array = env->NewByteArray(4096);
		int g = 0;

		HTTPResponse response;
		__android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Starting to gather content");

		//Gather content
		while ((g = env->CallIntMethod(input, readMethod, array)) != -1) {

			jbyte* content_array = env->GetByteArrayElements(array, NULL);
			if (callback) {
				callback->handleChunk(g, (char*) content_array);
			} else {
				response.appendContent(std::string((char*) content_array, g));
			}
			env->ReleaseByteArrayElements(array, content_array, JNI_ABORT);
		}

		//Gather headers and values
		for (int i = 0; i < 1000; i++) {
			auto headerKey = env->GetStringUTFChars((jstring) env->CallObjectMethod(connection, getHeaderKeyMethod, i), 0);
			__android_log_print(ANDROID_LOG_INFO, "content", "header key = %s", headerKey);
			auto header = env->GetStringUTFChars((jstring) env->CallObjectMethod(connection, getHeaderMethodInt, i), 0);
			__android_log_print(ANDROID_LOG_INFO, "content", "header value = %s", header);
			if (headerKey == NULL) {
				break;
			}
			response.addHeader(headerKey, header);
		}

		response.setResultCode(responseCode);

		if (responseCode >= 300 && responseCode <= 399) {

			jstring followURL = (jstring)env->CallObjectMethod(connection, getHeaderMethod, env->NewStringUTF("location"));
			const char *followString = env->GetStringUTFChars(followURL, 0);
			response.setRedirectUrl(followString);
			env->ReleaseStringUTFChars(followURL, followString);
			__android_log_print(ANDROID_LOG_INFO, "content", "followURL = %s", followString);

		}

//		response.addHeader("", "");
		return response; // HTTPResponse(responseCode, errorMessage, followString, content);

  }

  void clearCookies() {

  	env->CallVoidMethod(cookieManagerClass, clearCookiesMethod);

  }

 protected:
  bool initialize() { return true; }

 private:
	bool initDone = false;

  JNIEnv * env;
  jclass cookieManagerClass;
  jmethodID clearCookiesMethod;

  jclass bitmapClass;
  jclass factoryClass;
  jclass httpClass;
  jclass urlClass;
  jclass bufferedReaderClass;
  jclass inputStreamReaderClass;
  jclass inputStreamClass;
  jmethodID urlConstructor;
  jmethodID openConnectionMethod;
  jmethodID setRequestProperty;
  jmethodID setRequestMethod;
  jmethodID setDoInputMethod;
  jmethodID connectMethod;
  jmethodID getResponseCodeMethod;
  jmethodID getResponseMessageMethod;
  jmethodID setRequestPropertyMethod;
  jmethodID outputStreamConstructor;
  jmethodID factoryDecodeMethod;
  jmethodID getInputStreamMethod;
  jmethodID getErrorStreamMethod;
  jmethodID bufferedReaderConstructor;
  jmethodID inputStreamReaderConstructor;
  jmethodID readLineMethod;
  jmethodID readerCloseMethod;
  jmethodID readMethod;
  jmethodID inputStreamCloseMethod;
  jmethodID setFollowMethod;
  jmethodID getHeaderMethod;
  jmethodID getHeaderMethodInt;
  jmethodID getHeaderKeyMethod;

};

std::shared_ptr<HTTPClient>
AndroidClientFactory::createClient(const std::string & _user_agent, bool _enable_cookies, bool _enable_keepalive) {
  return std::make_shared<AndroidClient>(env, _user_agent, _enable_cookies, _enable_keepalive);
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016, The Bifrost Authors. All rights reserved.
 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * * Neither the name of The Bifrost Authors nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <bifrost/unpack.h>
#include "utils.hpp"

// sign_extend == true  => output has same value as input  (slower)
// sign_extend == false => output is scaled by 2**(8-nbit) (faster)

template<int NBIT, typename K, typename T>
inline void rshift_subwords(T& val) {
	for( int k=0; k<(int)(sizeof(T)/sizeof(K)); ++k ) {
		((K*)&val)[k] >>= NBIT;
	}
}
// 2x 4-bit --> 2x 8-bit (unsigned)
inline void unpack(uint8_t   ival,
                   uint16_t& oval,
                   bool      byte_reverse,
                   bool      align_msb,
                   bool      conjugate) {
	// Note: Ignores conjugate
	if( byte_reverse ) {
		// ........ABCDEFGH
		// EFGH....ABCD....
		oval = ival;
		oval = (oval | (oval << 12)) & 0xF0F0;
	} else {
		// ....ABCDEFGH....
		// ABCD....EFGH....
		oval = ival << 4;
		oval = (oval | (oval <<  4)) & 0xF0F0;
	}
	if( !align_msb ) {
		// >>>>ABCD>>>>EFGH
		oval >>= 4;
	}
}

// 4x 2-bit --> 4x 8-bit (unsigned)
inline void unpack(uint8_t   ival,
                   uint32_t& oval,
                   bool      byte_reverse,
                   bool      align_msb,
                   bool      conjugate) {
	// Note: Ignores conjugate
	// ..................ABCDEFGH......
	// ......ABCD............EFGH......
	// AB......CD......EF......GH......
	oval = ival << 6;
	oval = (oval | (oval << 12)) & 0x03C003C0;
	oval = (oval | (oval <<  6)) & 0xC0C0C0C0;
	if( byte_reverse) {
		byteswap(oval, &oval);
	}
	if( !align_msb ) {
		// >>>>>>AB>>>>>>CD>>>>>>EF>>>>>>GH
		oval >>= 6;
	}
}

// 8x 1-bit --> 8x 8-bit (unsigned)
inline void unpack(uint8_t   ival,
                   uint64_t& oval,
                   bool      byte_reverse,
                   bool      align_msb,
                   bool      conjugate) {
	// Note: Ignores conjugate
	// .................................................ABCDEFGH.......
	// .....................ABCD............................EFGH.......
	// .......AB..............CD..............EF..............GH.......
	// A.......B.......C.......D.......E.......F.......G.......H.......
	oval = ival << 7;
	oval = (oval | (oval << 28)) & 0x0000078000000780;
	oval = (oval | (oval << 14)) & 0x0180018001800180;
	oval = (oval | (oval <<  7)) & 0x8080808080808080;
	if( byte_reverse) {
		byteswap(oval, &oval);
	}
	if( !align_msb ) {
		// >>>>>>>A>>>>>>>B>>>>>>>C>>>>>>>D
		oval >>= 7;
	}
}

template<typename K, typename T>
inline void conjugate_subwords(T& val) {
	for( int k=1; k<(int)(sizeof(T)/sizeof(K)); k+=2 ) {
		K& val_imag = ((K*)&val)[k];
		val_imag = -val_imag;
	}
}

// 2x 4-bit --> 2x 8-bit (signed)
inline void unpack(uint8_t  ival,
                   int16_t& oval,
                   bool     byte_reverse,
                   bool     align_msb,
                   bool     conjugate) {
	if( byte_reverse ) {
		// ........ABCDEFGH
		// EFGH....ABCD....
		oval = ival;
		oval = (oval | (oval << 12)) & 0xF0F0;
	} else {
		// ....ABCDEFGH....
		// ABCD....EFGH....
		oval = ival << 4;
		oval = (oval | (oval <<  4)) & 0xF0F0;
	}
	if( !align_msb ) {
		// >>>>ABCD>>>>EFGH
		rshift_subwords<4,int8_t>(oval);
	}
	if( conjugate ) {
		conjugate_subwords<int8_t>(oval);
	}
}
// 4x 2-bit --> 4x 8-bit (signed)
inline void unpack(uint8_t  ival,
                   int32_t& oval,
                   bool     byte_reverse,
                   bool     align_msb,
                   bool     conjugate) {
	// ..................ABCDEFGH......
	// ......ABCD............EFGH......
	// AB......CD......EF......GH......
	oval = ival << 6;
	oval = (oval | (oval << 12)) & 0x03C003C0;
	oval = (oval | (oval <<  6)) & 0xC0C0C0C0;
	if( byte_reverse) {
		byteswap(oval, &oval);
	}
	if( !align_msb ) {
		// >>>>>>AB>>>>>>CD>>>>>>EF>>>>>>GH
		rshift_subwords<6,int8_t>(oval);
	}
	if( conjugate ) {
		conjugate_subwords<int8_t>(oval);
	}
}
// 8x 1-bit --> 8x 8-bit (signed)
inline void unpack(uint8_t  ival,
                   int64_t& oval,
                   bool     byte_reverse,
                   bool     align_msb,
                   bool     conjugate) {
	// .................................................ABCDEFGH.......
	// .....................ABCD............................EFGH.......
	// .......AB..............CD..............EF..............GH.......
	// A.......B.......C.......D.......E.......F.......G.......H.......
	oval = ival << 7;
	oval = (oval | (oval << 28)) & 0x0000078000000780;
	oval = (oval | (oval << 14)) & 0x0180018001800180;
	oval = (oval | (oval <<  7)) & 0x8080808080808080;
	if( byte_reverse) {
		byteswap(oval, &oval);
	}
	if( !align_msb ) {
		// >>>>>>>A>>>>>>>B>>>>>>>C>>>>>>>D
		rshift_subwords<7,int8_t>(oval);
	}
	if( conjugate ) {
		conjugate_subwords<int8_t>(oval);
	}
}

template<typename IType, typename OType>
struct UnpackFunctor {
	bool byte_reverse;
	bool align_msb;
	bool conjugate;
	UnpackFunctor(bool byte_reverse_,
	              bool align_msb_,
	              bool conjugate_)
		: byte_reverse(byte_reverse_),
		  align_msb(align_msb_),
		  conjugate(conjugate_) {}
	void operator()(IType ival, OType& oval) const {
		unpack(ival, oval, byte_reverse, align_msb, conjugate);
	}
};

template<typename T, typename U, typename Func, typename Size>
void foreach_simple_cpu(T const* in,
                        U*       out,
                        Size     nelement,
                        Func     func) {
	for( Size i=0; i<nelement; ++i ) {
		func(in[i], out[i]);
		//std::cout << std::hex << (int)in[i] << " --> " << (int)out[i] << std::endl;
	}
}

BFstatus bfUnpack(BFarray const* in,
                  BFarray const* out,
                  BFbool         align_msb) {
	BF_ASSERT(in,  BF_STATUS_INVALID_POINTER);
	BF_ASSERT(out, BF_STATUS_INVALID_POINTER);
	BF_ASSERT(!out->immutable, BF_STATUS_INVALID_POINTER);
	BF_ASSERT(shapes_equal(in, out), BF_STATUS_INVALID_SHAPE);
	BF_ASSERT(BF_DTYPE_IS_COMPLEX( in->dtype) ==
	          BF_DTYPE_IS_COMPLEX(out->dtype),
	          BF_STATUS_INVALID_DTYPE);
	BF_ASSERT(BF_DTYPE_IS_COMPLEX(in->dtype) || !in->conjugated,
	          BF_STATUS_INVALID_DTYPE);
	BF_ASSERT(BF_DTYPE_IS_COMPLEX(out->dtype) || !in->conjugated,
	          BF_STATUS_INVALID_DTYPE);

	// **TODO: This does not correctly interpret strides when itemsize_nbit < 8
	//           Need to work out how to handle strides when itemsize_bits < 8
	//             Perhaps some way of specifying packed contiguous inner dims
	//             Whatever solution is chosen will need to be integrated into
	//               bf.ndarray and bf.DataType.

	// TODO: Support padded arrays
	BF_ASSERT(is_contiguous(in),  BF_STATUS_UNSUPPORTED_STRIDE);
	BF_ASSERT(is_contiguous(out), BF_STATUS_UNSUPPORTED_STRIDE);

	// TODO: Support CUDA space
	BF_ASSERT(space_accessible_from(in->space, BF_SPACE_SYSTEM),
	          BF_STATUS_UNSUPPORTED_SPACE);
	BF_ASSERT(space_accessible_from(out->space, BF_SPACE_SYSTEM),
	          BF_STATUS_UNSUPPORTED_SPACE);

	size_t nelement = num_contiguous_elements(in);
	bool byteswap    = ( in->big_endian != is_big_endian());
	bool conjugate   = (in->conjugated != out->conjugated);

#define CALL_FOREACH_SIMPLE_CPU_UNPACK(itype,otype) \
	foreach_simple_cpu((itype*)in->data, \
	                   (otype*)out->data, \
	                   nelement, \
	                   UnpackFunctor<itype,otype>(byteswap, \
	                                              align_msb, \
	                                              conjugate))
	if( out->dtype == BF_DTYPE_I8 ||
	           out->dtype == BF_DTYPE_CI8 ) {
	//case BF_DTYPE_I8: {
		switch( in->dtype ) {
		// TODO: Work out how to properly deal with 1-bit
		//case BF_DTYPE_CI1: nelement *= 2;
		//case BF_DTYPE_I1: {
		//	BF_ASSERT(nelement % 8 == 0, BF_STATUS_INVALID_SHAPE);
		//	nelement /= 8;
		//	CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,int64_t); break;
		//}
		case BF_DTYPE_CI2: nelement *= 2;
		case BF_DTYPE_I2: {
			BF_ASSERT(nelement % 4 == 0, BF_STATUS_INVALID_SHAPE);
			nelement /= 4;
			CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,int32_t);
			break;
		}
		case BF_DTYPE_CI4: nelement *= 2;
		case BF_DTYPE_I4: {
			BF_ASSERT(nelement % 2 == 0, BF_STATUS_INVALID_SHAPE);
			nelement /= 2;
			CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,int16_t);
			break;
		}
		//case BF_DTYPE_U1: {
		//	// TODO
		//}
		case BF_DTYPE_U2: {
			BF_ASSERT(nelement % 4 == 0, BF_STATUS_INVALID_SHAPE);
			nelement /= 4;
			CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,uint32_t);
			break;
		}
		case BF_DTYPE_U4: {
			BF_ASSERT(nelement % 2 == 0, BF_STATUS_INVALID_SHAPE);
			nelement /= 2;
			CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,uint16_t);
			break;
		}
		default: BF_FAIL("Supported bfQuantize input dtype", BF_STATUS_UNSUPPORTED_DTYPE);
		}
	} else {
		BF_FAIL("Supported bfQuantize output dtype", BF_STATUS_UNSUPPORTED_DTYPE);
	}
#undef CALL_FOREACH_SIMPLE_CPU_UNPACK
	return BF_STATUS_SUCCESS;
}
<commit_msg>Fix error message typos in unpack.cpp<commit_after>/*
 * Copyright (c) 2016, The Bifrost Authors. All rights reserved.
 * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * * Neither the name of The Bifrost Authors nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <bifrost/unpack.h>
#include "utils.hpp"

// sign_extend == true  => output has same value as input  (slower)
// sign_extend == false => output is scaled by 2**(8-nbit) (faster)

template<int NBIT, typename K, typename T>
inline void rshift_subwords(T& val) {
	for( int k=0; k<(int)(sizeof(T)/sizeof(K)); ++k ) {
		((K*)&val)[k] >>= NBIT;
	}
}
// 2x 4-bit --> 2x 8-bit (unsigned)
inline void unpack(uint8_t   ival,
                   uint16_t& oval,
                   bool      byte_reverse,
                   bool      align_msb,
                   bool      conjugate) {
	// Note: Ignores conjugate
	if( byte_reverse ) {
		// ........ABCDEFGH
		// EFGH....ABCD....
		oval = ival;
		oval = (oval | (oval << 12)) & 0xF0F0;
	} else {
		// ....ABCDEFGH....
		// ABCD....EFGH....
		oval = ival << 4;
		oval = (oval | (oval <<  4)) & 0xF0F0;
	}
	if( !align_msb ) {
		// >>>>ABCD>>>>EFGH
		oval >>= 4;
	}
}

// 4x 2-bit --> 4x 8-bit (unsigned)
inline void unpack(uint8_t   ival,
                   uint32_t& oval,
                   bool      byte_reverse,
                   bool      align_msb,
                   bool      conjugate) {
	// Note: Ignores conjugate
	// ..................ABCDEFGH......
	// ......ABCD............EFGH......
	// AB......CD......EF......GH......
	oval = ival << 6;
	oval = (oval | (oval << 12)) & 0x03C003C0;
	oval = (oval | (oval <<  6)) & 0xC0C0C0C0;
	if( byte_reverse) {
		byteswap(oval, &oval);
	}
	if( !align_msb ) {
		// >>>>>>AB>>>>>>CD>>>>>>EF>>>>>>GH
		oval >>= 6;
	}
}

// 8x 1-bit --> 8x 8-bit (unsigned)
inline void unpack(uint8_t   ival,
                   uint64_t& oval,
                   bool      byte_reverse,
                   bool      align_msb,
                   bool      conjugate) {
	// Note: Ignores conjugate
	// .................................................ABCDEFGH.......
	// .....................ABCD............................EFGH.......
	// .......AB..............CD..............EF..............GH.......
	// A.......B.......C.......D.......E.......F.......G.......H.......
	oval = ival << 7;
	oval = (oval | (oval << 28)) & 0x0000078000000780;
	oval = (oval | (oval << 14)) & 0x0180018001800180;
	oval = (oval | (oval <<  7)) & 0x8080808080808080;
	if( byte_reverse) {
		byteswap(oval, &oval);
	}
	if( !align_msb ) {
		// >>>>>>>A>>>>>>>B>>>>>>>C>>>>>>>D
		oval >>= 7;
	}
}

template<typename K, typename T>
inline void conjugate_subwords(T& val) {
	for( int k=1; k<(int)(sizeof(T)/sizeof(K)); k+=2 ) {
		K& val_imag = ((K*)&val)[k];
		val_imag = -val_imag;
	}
}

// 2x 4-bit --> 2x 8-bit (signed)
inline void unpack(uint8_t  ival,
                   int16_t& oval,
                   bool     byte_reverse,
                   bool     align_msb,
                   bool     conjugate) {
	if( byte_reverse ) {
		// ........ABCDEFGH
		// EFGH....ABCD....
		oval = ival;
		oval = (oval | (oval << 12)) & 0xF0F0;
	} else {
		// ....ABCDEFGH....
		// ABCD....EFGH....
		oval = ival << 4;
		oval = (oval | (oval <<  4)) & 0xF0F0;
	}
	if( !align_msb ) {
		// >>>>ABCD>>>>EFGH
		rshift_subwords<4,int8_t>(oval);
	}
	if( conjugate ) {
		conjugate_subwords<int8_t>(oval);
	}
}
// 4x 2-bit --> 4x 8-bit (signed)
inline void unpack(uint8_t  ival,
                   int32_t& oval,
                   bool     byte_reverse,
                   bool     align_msb,
                   bool     conjugate) {
	// ..................ABCDEFGH......
	// ......ABCD............EFGH......
	// AB......CD......EF......GH......
	oval = ival << 6;
	oval = (oval | (oval << 12)) & 0x03C003C0;
	oval = (oval | (oval <<  6)) & 0xC0C0C0C0;
	if( byte_reverse) {
		byteswap(oval, &oval);
	}
	if( !align_msb ) {
		// >>>>>>AB>>>>>>CD>>>>>>EF>>>>>>GH
		rshift_subwords<6,int8_t>(oval);
	}
	if( conjugate ) {
		conjugate_subwords<int8_t>(oval);
	}
}
// 8x 1-bit --> 8x 8-bit (signed)
inline void unpack(uint8_t  ival,
                   int64_t& oval,
                   bool     byte_reverse,
                   bool     align_msb,
                   bool     conjugate) {
	// .................................................ABCDEFGH.......
	// .....................ABCD............................EFGH.......
	// .......AB..............CD..............EF..............GH.......
	// A.......B.......C.......D.......E.......F.......G.......H.......
	oval = ival << 7;
	oval = (oval | (oval << 28)) & 0x0000078000000780;
	oval = (oval | (oval << 14)) & 0x0180018001800180;
	oval = (oval | (oval <<  7)) & 0x8080808080808080;
	if( byte_reverse) {
		byteswap(oval, &oval);
	}
	if( !align_msb ) {
		// >>>>>>>A>>>>>>>B>>>>>>>C>>>>>>>D
		rshift_subwords<7,int8_t>(oval);
	}
	if( conjugate ) {
		conjugate_subwords<int8_t>(oval);
	}
}

template<typename IType, typename OType>
struct UnpackFunctor {
	bool byte_reverse;
	bool align_msb;
	bool conjugate;
	UnpackFunctor(bool byte_reverse_,
	              bool align_msb_,
	              bool conjugate_)
		: byte_reverse(byte_reverse_),
		  align_msb(align_msb_),
		  conjugate(conjugate_) {}
	void operator()(IType ival, OType& oval) const {
		unpack(ival, oval, byte_reverse, align_msb, conjugate);
	}
};

template<typename T, typename U, typename Func, typename Size>
void foreach_simple_cpu(T const* in,
                        U*       out,
                        Size     nelement,
                        Func     func) {
	for( Size i=0; i<nelement; ++i ) {
		func(in[i], out[i]);
		//std::cout << std::hex << (int)in[i] << " --> " << (int)out[i] << std::endl;
	}
}

BFstatus bfUnpack(BFarray const* in,
                  BFarray const* out,
                  BFbool         align_msb) {
	BF_ASSERT(in,  BF_STATUS_INVALID_POINTER);
	BF_ASSERT(out, BF_STATUS_INVALID_POINTER);
	BF_ASSERT(!out->immutable, BF_STATUS_INVALID_POINTER);
	BF_ASSERT(shapes_equal(in, out), BF_STATUS_INVALID_SHAPE);
	BF_ASSERT(BF_DTYPE_IS_COMPLEX( in->dtype) ==
	          BF_DTYPE_IS_COMPLEX(out->dtype),
	          BF_STATUS_INVALID_DTYPE);
	BF_ASSERT(BF_DTYPE_IS_COMPLEX(in->dtype) || !in->conjugated,
	          BF_STATUS_INVALID_DTYPE);
	BF_ASSERT(BF_DTYPE_IS_COMPLEX(out->dtype) || !in->conjugated,
	          BF_STATUS_INVALID_DTYPE);

	// **TODO: This does not correctly interpret strides when itemsize_nbit < 8
	//           Need to work out how to handle strides when itemsize_bits < 8
	//             Perhaps some way of specifying packed contiguous inner dims
	//             Whatever solution is chosen will need to be integrated into
	//               bf.ndarray and bf.DataType.

	// TODO: Support padded arrays
	BF_ASSERT(is_contiguous(in),  BF_STATUS_UNSUPPORTED_STRIDE);
	BF_ASSERT(is_contiguous(out), BF_STATUS_UNSUPPORTED_STRIDE);

	// TODO: Support CUDA space
	BF_ASSERT(space_accessible_from(in->space, BF_SPACE_SYSTEM),
	          BF_STATUS_UNSUPPORTED_SPACE);
	BF_ASSERT(space_accessible_from(out->space, BF_SPACE_SYSTEM),
	          BF_STATUS_UNSUPPORTED_SPACE);

	size_t nelement = num_contiguous_elements(in);
	bool byteswap    = ( in->big_endian != is_big_endian());
	bool conjugate   = (in->conjugated != out->conjugated);

#define CALL_FOREACH_SIMPLE_CPU_UNPACK(itype,otype) \
	foreach_simple_cpu((itype*)in->data, \
	                   (otype*)out->data, \
	                   nelement, \
	                   UnpackFunctor<itype,otype>(byteswap, \
	                                              align_msb, \
	                                              conjugate))
	if( out->dtype == BF_DTYPE_I8 ||
	           out->dtype == BF_DTYPE_CI8 ) {
	//case BF_DTYPE_I8: {
		switch( in->dtype ) {
		// TODO: Work out how to properly deal with 1-bit
		//case BF_DTYPE_CI1: nelement *= 2;
		//case BF_DTYPE_I1: {
		//	BF_ASSERT(nelement % 8 == 0, BF_STATUS_INVALID_SHAPE);
		//	nelement /= 8;
		//	CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,int64_t); break;
		//}
		case BF_DTYPE_CI2: nelement *= 2;
		case BF_DTYPE_I2: {
			BF_ASSERT(nelement % 4 == 0, BF_STATUS_INVALID_SHAPE);
			nelement /= 4;
			CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,int32_t);
			break;
		}
		case BF_DTYPE_CI4: nelement *= 2;
		case BF_DTYPE_I4: {
			BF_ASSERT(nelement % 2 == 0, BF_STATUS_INVALID_SHAPE);
			nelement /= 2;
			CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,int16_t);
			break;
		}
		//case BF_DTYPE_U1: {
		//	// TODO
		//}
		case BF_DTYPE_U2: {
			BF_ASSERT(nelement % 4 == 0, BF_STATUS_INVALID_SHAPE);
			nelement /= 4;
			CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,uint32_t);
			break;
		}
		case BF_DTYPE_U4: {
			BF_ASSERT(nelement % 2 == 0, BF_STATUS_INVALID_SHAPE);
			nelement /= 2;
			CALL_FOREACH_SIMPLE_CPU_UNPACK(uint8_t,uint16_t);
			break;
		}
		default: BF_FAIL("Supported bfUnpack input dtype", BF_STATUS_UNSUPPORTED_DTYPE);
		}
	} else {
		BF_FAIL("Supported bfUnpack output dtype", BF_STATUS_UNSUPPORTED_DTYPE);
	}
#undef CALL_FOREACH_SIMPLE_CPU_UNPACK
	return BF_STATUS_SUCCESS;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 Joyent Inc.
 * All rights reserved.
 *
 * Written by: Matthew Macy <matt.macy@joyent.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/types.h>
#include <stdio.h>

#include <net/ethernet.h>
#define NETMAP_WITH_LIBS
#include <net/netmap_user.h>
#include <sys/poll.h>

#include "uvxbridge.h"
#include "uvxlan.h"

#define AE_REQUEST		0x0100040600080100UL
#define AE_REPLY		0x0200040600080100UL
#define AE_REVREQUEST		0x0300040600080100UL
#define AE_REVREPLY		0x0400040600080100UL

#define AE_REQUEST_ALL		0x0A00040600080100UL
#define AE_REVREQUEST_ALL	0x0B00040600080100UL
#define AE_VM_VXLANID_REQUEST	0x0C00040600080100UL
#define AE_VM_VXLANID_REQUEST_ALL	0x0D00040600080100UL
#define AE_VM_VXLANID_REPLY	0x0E00040600080100UL
#define AE_VM_VLANID_REQUEST	0x0F00040600080100UL
#define AE_VM_VLANID_REQUEST_ALL	0x1000040600080100UL
#define AE_VM_VLANID_REPLY	0x1100040600080100UL

#define A(val) printf("got %s\n", #val)
extern int debug;

int
cmd_dispatch_arp(char *rxbuf, char *txbuf, path_state_t *ps, vxstate_t *state)
{
	struct arphdr_ether *sah, *dah;
	struct ether_header *eh;
	int op, len;
	uint32_t hostip, targetval = 0;
	uint16_t *rmacp, *lmacp;
	uint64_t reply = 0;

	len = ps->ps_rx_len;
	if (len < ETHER_HDR_LEN + sizeof(struct arphdr_ether) && debug < 2)
		return 0;

	sah = (struct arphdr_ether *)(rxbuf + ETHER_HDR_LEN);
	dah = (struct arphdr_ether *)(txbuf + ETHER_HDR_LEN);
	op = ntohs(sah->ae_hdr.fields.ar_op);
	/* place holder */
	hostip = htobe32(0xDEADBEEF);

	switch (op) {
		case ARPOP_REQUEST:
			A(ARPOP_REQUEST);
			reply = AE_REPLY;
			break;
		case ARPOP_REPLY:
			A(ARPOP_REPLY);
			break;
		case ARPOP_REVREQUEST:
			A(ARPOP_REVREQUEST);
			reply = AE_REVREPLY;
			break;
		case ARPOP_REVREPLY:
			A(ARPOP_REVREPLY);
			break;
		case ARPOP_REQUEST_ALL:
			A(ARPOP_REQUEST_ALL);
			break;
		case ARPOP_REVREQUEST_ALL:
			A(ARPOP_REVREQUEST_ALL);
			break;
		case ARPOP_VM_VXLANID_REQUEST:
			A(ARPOP_VM_VXLANID_REQUEST);
			reply = AE_VM_VXLANID_REPLY;
			break;
		case ARPOP_VM_VXLANID_REQUEST_ALL:
			A(ARPOP_VM_VXLANID_REQUEST_ALL);
			break;
		case ARPOP_VM_VXLANID_REPLY:
			A(ARPOP_VM_VXLANID_REPLY);
			break;
		case ARPOP_VM_VLANID_REQUEST:
			A(ARPOP_VM_VLANID_REQUEST);
			reply = AE_VM_VLANID_REPLY;
			break;
		case ARPOP_VM_VLANID_REQUEST_ALL:
			A(ARPOP_VM_VLANID_REQUEST);
			break;
		case ARPOP_VM_VLANID_REPLY:
			A(ARPOP_VM_VLANID_REPLY);
			break;
		default:
			printf("unrecognized value data: 0x%016lX op: 0x%02X\n", sah->ae_hdr.data, op);
	}
	/* save potential cache stall to the end */
	if (reply) {
		eh = (struct ether_header *)txbuf;
		lmacp = (uint16_t *)&eh->ether_dhost;
		rmacp =  (uint16_t *)&state->vs_prov_mac;
		lmacp[0] = rmacp[0];
		lmacp[1] = rmacp[1];
		lmacp[2] = rmacp[2];
		rmacp =  (uint16_t *)&state->vs_ctrl_mac;
		lmacp[3] = rmacp[0];
		lmacp[4] = rmacp[1];
		lmacp[5] = rmacp[2];
		/* [6] */
		eh->ether_type = ETHERTYPE_ARP;
		/* [7-10] */
		dah->ae_hdr.data = reply;
		/* [11-13] - ar_sha */
		lmacp[11] = rmacp[0];
		lmacp[12] = rmacp[1];
		lmacp[13] = rmacp[2];
		/* [14-15] - ae_spa */
		dah->ae_spa = hostip;
		rmacp =  (uint16_t *)&state->vs_prov_mac;
		/* [16-18] - ae_tha */
		lmacp[16] = rmacp[0];
		lmacp[17] = rmacp[1];
		lmacp[18] = rmacp[2];
		/* actual value of interest */
		dah->ae_tpa = targetval;
		return (1);
	}
	return (0);
}

/*
 * If rxbuf contains a neighbor discovery request return true.
 * If it's an nd request we can handle, enqueue a response.
 *
 * dir = EGRESS => VX, dir = INGRESS => PHYS
 */
bool
nd_request(struct arphdr_ether *sae, arphdr_ether *dae, vxstate_t &state, l2tbl_t &tbl)
{
#if 0
//  XXX we assume prepopulated ARP table so ignore replies
//	if (ae->ae_req != arpopreq && ae->ae_req != arpopreply)
	if (sae->ae_req != arpopreq)
		return false;

	dae->ae_req = arpopreply;
#endif
	abort();
	return true;
}

/*
 * If valid, deencapsulate rxbuf in to txbuf
 *
 */
bool
vxlan_decap(char *rxbuf, char *txbuf, int len, vxstate_t &state __unused)
{

	nm_pkt_copy(rxbuf, txbuf, len);
	return true;
}

/*
 * If valid, encapsulate rxbuf in to txbuf
 *
 */
bool
vxlan_encap(char *rxbuf, char *txbuf, int len, vxstate_t &state __unused)
{
	struct ether_vlan_header *evh, *evhrsp;
	int hdrlen, etype;

	evh = (struct ether_vlan_header *)(rxbuf);
	if (evh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
		hdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
		etype = ntohs(evh->evl_proto);
	} else {
		hdrlen = ETHER_HDR_LEN;
		etype = ntohs(evh->evl_encap_proto);
	}
	if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6)
		return false;
	/* first map evh->evl_shost -> vxlanid / vlanid */
	/* ..... */
	/* next map evh->evl_dhost -> remote ip addr in the corresponding forwarding table */
	/* ..... */
	/* next check if remote ip is on our local subnet */
	/* .... */
	/* if yes - lookup MAC address for peer */
	/* .... */
	/* if no - lookup MAC address for corresponding router */
	/* .... */
	/* use source IP for said subnet */
	/* calculate source port */
	/* .... */

	evhrsp = (struct ether_vlan_header *)(txbuf);
    nm_pkt_copy(rxbuf, txbuf, len);
    return true;
}
<commit_msg>implement ARP request / reply<commit_after>/*
 * Copyright (C) 2017 Joyent Inc.
 * All rights reserved.
 *
 * Written by: Matthew Macy <matt.macy@joyent.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/types.h>
#include <stdio.h>

#include <net/ethernet.h>
#define NETMAP_WITH_LIBS
#include <net/netmap_user.h>
#include <sys/poll.h>

#include "uvxbridge.h"
#include "uvxlan.h"

#define AE_REQUEST		0x0100040600080100UL
#define AE_REPLY		0x0200040600080100UL
#define AE_REVREQUEST		0x0300040600080100UL
#define AE_REVREPLY		0x0400040600080100UL

#define AE_REQUEST_ALL		0x0A00040600080100UL
#define AE_REVREQUEST_ALL	0x0B00040600080100UL
#define AE_VM_VXLANID_REQUEST	0x0C00040600080100UL
#define AE_VM_VXLANID_REQUEST_ALL	0x0D00040600080100UL
#define AE_VM_VXLANID_REPLY	0x0E00040600080100UL
#define AE_VM_VLANID_REQUEST	0x0F00040600080100UL
#define AE_VM_VLANID_REQUEST_ALL	0x1000040600080100UL
#define AE_VM_VLANID_REPLY	0x1100040600080100UL

#define A(val) printf("got %s\n", #val)
extern int debug;

int
cmd_dispatch_arp(char *rxbuf, char *txbuf, path_state_t *ps, vxstate_t *state)
{
	struct arphdr_ether *sah, *dah;
	struct ether_header *eh;
	int op, len;
	uint32_t hostip, targetpa = 0;
	uint16_t *rmacp, *lmacp;
	uint64_t targetha = 0, reply = 0;
	l2tbl_t &tbl = state->vs_l2_phys;

	len = ps->ps_rx_len;
	if (len < ETHER_HDR_LEN + sizeof(struct arphdr_ether) && debug < 2)
		return 0;

	sah = (struct arphdr_ether *)(rxbuf + ETHER_HDR_LEN);
	dah = (struct arphdr_ether *)(txbuf + ETHER_HDR_LEN);
	op = ntohs(sah->ae_hdr.fields.ar_op);
	/* place holder */
	hostip = htobe32(0xDEADBEEF);

	switch (op) {
		case ARPOP_REQUEST: {
			A(ARPOP_REQUEST);
			auto it = tbl.l2t_v4.find(sah->ae_tpa);
			if (it != tbl.l2t_v4.end()) {
				reply = AE_REPLY;
				targetpa = sah->ae_tpa;
				targetha = it->second;
			}
			break;
		}
		case ARPOP_REPLY:
			A(ARPOP_REPLY);
			memcpy(&targetha, sah->ae_tha, ETHER_ADDR_LEN);
			tbl.l2t_v4.insert(pair<uint32_t, uint64_t>(sah->ae_tpa, targetha));
			break;
		case ARPOP_REVREQUEST:
			A(ARPOP_REVREQUEST);
			reply = AE_REVREPLY;
			break;
		case ARPOP_REVREPLY:
			A(ARPOP_REVREPLY);
			break;
		case ARPOP_REQUEST_ALL:
			A(ARPOP_REQUEST_ALL);
			break;
		case ARPOP_REVREQUEST_ALL:
			A(ARPOP_REVREQUEST_ALL);
			break;
		case ARPOP_VM_VXLANID_REQUEST:
			A(ARPOP_VM_VXLANID_REQUEST);
			reply = AE_VM_VXLANID_REPLY;
			break;
		case ARPOP_VM_VXLANID_REQUEST_ALL:
			A(ARPOP_VM_VXLANID_REQUEST_ALL);
			break;
		case ARPOP_VM_VXLANID_REPLY:
			A(ARPOP_VM_VXLANID_REPLY);
			break;
		case ARPOP_VM_VLANID_REQUEST:
			A(ARPOP_VM_VLANID_REQUEST);
			reply = AE_VM_VLANID_REPLY;
			break;
		case ARPOP_VM_VLANID_REQUEST_ALL:
			A(ARPOP_VM_VLANID_REQUEST);
			break;
		case ARPOP_VM_VLANID_REPLY:
			A(ARPOP_VM_VLANID_REPLY);
			break;
		default:
			printf("unrecognized value data: 0x%016lX op: 0x%02X\n", sah->ae_hdr.data, op);
	}
	/* save potential cache stall to the end */
	if (reply) {
		eh = (struct ether_header *)txbuf;
		lmacp = (uint16_t *)&eh->ether_dhost;
		rmacp =  (uint16_t *)&state->vs_prov_mac;
		lmacp[0] = rmacp[0];
		lmacp[1] = rmacp[1];
		lmacp[2] = rmacp[2];
		rmacp =  (uint16_t *)&state->vs_ctrl_mac;
		lmacp[3] = rmacp[0];
		lmacp[4] = rmacp[1];
		lmacp[5] = rmacp[2];
		/* [6] */
		eh->ether_type = ETHERTYPE_ARP;
		/* [7-10] */
		dah->ae_hdr.data = reply;
		/* [11-13] - ar_sha */
		lmacp[11] = rmacp[0];
		lmacp[12] = rmacp[1];
		lmacp[13] = rmacp[2];
		/* [14-15] - ae_spa */
		dah->ae_spa = hostip;

		rmacp = (uint16_t *)&targetha;
		/* [16-18] - ae_tha */
		lmacp[16] = rmacp[0];
		lmacp[17] = rmacp[1];
		lmacp[18] = rmacp[2];
		/* actual value of interest */
		dah->ae_tpa = targetpa;
		return (1);
	}
	return (0);
}

/*
 * If rxbuf contains a neighbor discovery request return true.
 * If it's an nd request we can handle, enqueue a response.
 *
 * dir = EGRESS => VX, dir = INGRESS => PHYS
 */
bool
nd_request(struct arphdr_ether *sae, arphdr_ether *dae, vxstate_t &state, l2tbl_t &tbl)
{
#if 0
//  XXX we assume prepopulated ARP table so ignore replies
//	if (ae->ae_req != arpopreq && ae->ae_req != arpopreply)
	if (sae->ae_req != arpopreq)
		return false;

	dae->ae_req = arpopreply;
#endif
	abort();
	return true;
}

/*
 * If valid, deencapsulate rxbuf in to txbuf
 *
 */
bool
vxlan_decap(char *rxbuf, char *txbuf, int len, vxstate_t &state __unused)
{

	nm_pkt_copy(rxbuf, txbuf, len);
	return true;
}

/*
 * If valid, encapsulate rxbuf in to txbuf
 *
 */
bool
vxlan_encap(char *rxbuf, char *txbuf, int len, vxstate_t &state __unused)
{
	struct ether_vlan_header *evh, *evhrsp;
	int hdrlen, etype;

	evh = (struct ether_vlan_header *)(rxbuf);
	if (evh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
		hdrlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
		etype = ntohs(evh->evl_proto);
	} else {
		hdrlen = ETHER_HDR_LEN;
		etype = ntohs(evh->evl_encap_proto);
	}
	if (etype != ETHERTYPE_IP && etype != ETHERTYPE_IPV6)
		return false;
	/* first map evh->evl_shost -> vxlanid / vlanid */
	/* ..... */
	/* next map evh->evl_dhost -> remote ip addr in the corresponding forwarding table */
	/* ..... */
	/* next check if remote ip is on our local subnet */
	/* .... */
	/* if yes - lookup MAC address for peer */
	/* .... */
	/* if no - lookup MAC address for corresponding router */
	/* .... */
	/* use source IP for said subnet */
	/* calculate source port */
	/* .... */

	evhrsp = (struct ether_vlan_header *)(txbuf);
    nm_pkt_copy(rxbuf, txbuf, len);
    return true;
}
<|endoftext|>


<commit_before>// Copyright (C) 2011-2012, Zeex
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	 http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <sampgdk/config.h>
#include <sampgdk/core.h>
#include <sampgdk/plugin.h>

#include "callbacks.h"

#include <cassert>
#include <cstddef>
#include <cstring>

CallbackArg::CallbackArg(cell value)
	: type_(CELL)
{
	value_.as_cell = value;
}

CallbackArg::CallbackArg(const char *string)
	: type_(STRING)
{
	std::size_t size = std::strlen(string) + 1;
	char *buf = new char[size];
	std::memcpy(buf, string, size);
	value_.as_string = buf;
}

CallbackArg::~CallbackArg() {
	if (type_ == STRING) {
		delete[] value_.as_string;
	}
}

CallbackManager::CallbackManager()
	: cache_()
{
}

CallbackManager &CallbackManager::GetInstance() {
	static CallbackManager inst;
	return inst;
}

void CallbackManager::RegisterCallbackHandler(void *handler) {
	cache_.insert(std::make_pair(handler, std::map<std::string, void*>()));
}

cell CallbackManager::HandleCallback(const char *name, CallbackRetVal badRetVal) {
	cell retVal = 0;
	if (badRetVal.IsSet()) {
		retVal = !badRetVal;
	}

	typedef std::map<std::string, void*> PluginCache;
	typedef std::map<void*, PluginCache> Cache;

	// Call each of the registered handlers until false returned
	for (Cache::iterator cIter = cache_.begin(); cIter != cache_.end(); ++cIter) {
		void *function = 0;

		PluginCache pc = cIter->second;
		PluginCache::iterator pcIter = pc.find(name);

		if (pcIter == pc.end()) {
			if ((function = sampgdk_get_plugin_symbol(cIter->first, name)) != 0) {
				pc.insert(std::make_pair(name, function));
			}
		} else {
			function = pcIter->second;
		}

		if (function != 0) {
			int i = args_.size();
			#if defined _MSC_VER
				cell arg;
				while (--i >= 0) {
					arg = args_[i]->as_cell();
					__asm push dword ptr [arg]
				}
				__asm call dword ptr [function]
				__asm mov dword ptr [retVal], eax
			#elif defined __GNUC__
				while (--i >= 0) {
					__asm__ __volatile__ (
						"pushl %0;"  :: "r"(args_[i]->as_cell()));
				}
				__asm__ __volatile__ (
					"calll *%0;" :: "r"(function));
				__asm__ __volatile__ (
					"movl %%eax, %0;" : "=r"(retVal));
				#if defined LINUX
					__asm__ __volatile__ (
						"addl %0, %%esp;" :: "r"(args_.size() * 4));
				#endif
			#else
				#error Unsupported compiler
			#endif

			if (badRetVal.IsSet() && retVal == badRetVal) {
				break;
			}
		}
	}

	ClearArgs();
	return retVal;
}

void CallbackManager::ClearArgs() {
	for (std::deque<CallbackArg*>::iterator iterator = args_.begin();
			iterator != args_.end(); ++iterator) {
		delete *iterator;
	}
	args_.clear();
}
<commit_msg>Remove misleading comment<commit_after>// Copyright (C) 2011-2012, Zeex
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	 http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <sampgdk/config.h>
#include <sampgdk/core.h>
#include <sampgdk/plugin.h>

#include "callbacks.h"

#include <cassert>
#include <cstddef>
#include <cstring>

CallbackArg::CallbackArg(cell value)
	: type_(CELL)
{
	value_.as_cell = value;
}

CallbackArg::CallbackArg(const char *string)
	: type_(STRING)
{
	std::size_t size = std::strlen(string) + 1;
	char *buf = new char[size];
	std::memcpy(buf, string, size);
	value_.as_string = buf;
}

CallbackArg::~CallbackArg() {
	if (type_ == STRING) {
		delete[] value_.as_string;
	}
}

CallbackManager::CallbackManager()
	: cache_()
{
}

CallbackManager &CallbackManager::GetInstance() {
	static CallbackManager inst;
	return inst;
}

void CallbackManager::RegisterCallbackHandler(void *handler) {
	cache_.insert(std::make_pair(handler, std::map<std::string, void*>()));
}

cell CallbackManager::HandleCallback(const char *name, CallbackRetVal badRetVal) {
	cell retVal = 0;
	if (badRetVal.IsSet()) {
		retVal = !badRetVal;
	}

	typedef std::map<std::string, void*> PluginCache;
	typedef std::map<void*, PluginCache> Cache;

	for (Cache::iterator cIter = cache_.begin(); cIter != cache_.end(); ++cIter) {
		void *function = 0;

		PluginCache pc = cIter->second;
		PluginCache::iterator pcIter = pc.find(name);

		if (pcIter == pc.end()) {
			if ((function = sampgdk_get_plugin_symbol(cIter->first, name)) != 0) {
				pc.insert(std::make_pair(name, function));
			}
		} else {
			function = pcIter->second;
		}

		if (function != 0) {
			int i = args_.size();
			#if defined _MSC_VER
				cell arg;
				while (--i >= 0) {
					arg = args_[i]->as_cell();
					__asm push dword ptr [arg]
				}
				__asm call dword ptr [function]
				__asm mov dword ptr [retVal], eax
			#elif defined __GNUC__
				while (--i >= 0) {
					__asm__ __volatile__ (
						"pushl %0;"  :: "r"(args_[i]->as_cell()));
				}
				__asm__ __volatile__ (
					"calll *%0;" :: "r"(function));
				__asm__ __volatile__ (
					"movl %%eax, %0;" : "=r"(retVal));
				#if defined LINUX
					__asm__ __volatile__ (
						"addl %0, %%esp;" :: "r"(args_.size() * 4));
				#endif
			#else
				#error Unsupported compiler
			#endif

			if (badRetVal.IsSet() && retVal == badRetVal) {
				break;
			}
		}
	}

	ClearArgs();
	return retVal;
}

void CallbackManager::ClearArgs() {
	for (std::deque<CallbackArg*>::iterator iterator = args_.begin();
			iterator != args_.end(); ++iterator) {
		delete *iterator;
	}
	args_.clear();
}
<|endoftext|>


<commit_before>#include "vision.hpp"
#include "operators.hpp"

#include <QTemporaryFile>
#include <iomanip>
#include <iostream>
#include <sstream>

vision::vision (QStatusBar& statusbar, augmentation_widget& augmentation, QObject* parent)
: QObject (parent)
, _failed_frames_counter (0)
, _debug_mode (0)
, _augmentation (augmentation)
, _cam (new QCamera (QCamera::BackFace))
, _video_player (NULL)
, _acquisition (this)
, _operators ()
, _movement3d_average (1)
, _statusbar (statusbar) {
    _cam->setViewfinder (&_acquisition);
    connect (&_acquisition, SIGNAL (frameAvailable (const QVideoFrame&)), this,
    SLOT (frame_callback (const QVideoFrame&)));
    _cam->start ();
}

void vision::set_debug_mode (const int mode) {
    _debug_mode = mode;
}
int vision::debug_mode () {
    return _debug_mode;
}

void vision::set_input (const QCameraInfo& cameraInfo) {
    if (_video_player != NULL) {
        delete _video_player;
    }
    _video_player = NULL;
    if (_cam != NULL) {
        delete _cam;
    }

    _cam = new QCamera (cameraInfo);
    _cam->setViewfinder (&_acquisition);
    _cam->start ();
    if (_cam->status () != QCamera::ActiveStatus) {
        _statusbar.showMessage (QString ("camera status %1").arg (_cam->status ()), 2000);
    }
}

void vision::set_input (const QString& resource_path) {
    QFile resource_file (resource_path);
    if (resource_file.exists ()) {
        auto temp_file  = QTemporaryFile::createNativeFile (resource_file);
        QString fs_path = temp_file->fileName ();

        if (!fs_path.isEmpty ()) {
            if (_cam != NULL) {
                delete _cam;
            }
            _cam = NULL;
            if (_video_player != NULL) {
                delete _video_player;
            }

            _video_player = new QMediaPlayer ();
            _video_player->setVideoOutput (&_acquisition);
            _video_player->setMedia (QUrl::fromLocalFile (fs_path));
            _video_player->play ();
        }
    }
}

void vision::set_paused (bool paused) {
    if (paused) {
        disconnect (&_acquisition, SIGNAL (frameAvailable (const QVideoFrame&)),
        this, SLOT (frame_callback (const QVideoFrame&)));
    } else {
        connect (&_acquisition, SIGNAL (frameAvailable (const QVideoFrame&)),
        this, SLOT (frame_callback (const QVideoFrame&)));
    }
}

void set_focus () {
    ; // TODO: add focus implementation
}

void vision::set_reference () {
    _markers_mutex.lock ();
    _reference = _markers;
    _markers_mutex.unlock ();
}

void vision::frame_callback (const QVideoFrame& const_buffer) {
    bool status = true;
    image_t image;
    if (const_buffer.isValid ()) {
        // copy image into cpu memory
        QVideoFrame frame (const_buffer);
        if (frame.map (QAbstractVideoBuffer::ReadOnly)) {
            image.data = (uint8_t*)malloc (frame.mappedBytes ());
            memcpy (image.data, frame.bits (), frame.mappedBytes ());

            if (frame.pixelFormat () == QVideoFrame::Format_RGB24) {
                image.format = RGB24;
                image.width  = frame.width ();
                image.height = frame.height ();
            } else if (frame.pixelFormat () == QVideoFrame::Format_YUV420P) {
                image.format = YUV;
                image.width  = frame.width ();
                image.height = frame.height ();
            } else {
                _statusbar.showMessage (
                QString ("unsuported format %1").arg (frame.pixelFormat ()), 2000);
            }
        } else {
            status = false;
        }
        frame.unmap ();
    }

    if (status) {
        if (_debug_mode == 0) {
            _augmentation.setBackground (image);
            _augmentation.update ();
        }
        // start image processing
        _operators.preprocessing (image);
        if (_debug_mode == 1) {
            _augmentation.setBackground (image);
            _augmentation.update ();
        }

        _operators.segmentation (image);
        if (_debug_mode == 2) {
            _augmentation.setBackground (image);
            _augmentation.update ();
        }

        _markers_mutex.lock ();
        _markers.clear ();
        _operators.extraction (image, _markers);
        if (_debug_mode == 3) {
            _augmentation.setBackground (image);
            _augmentation.update ();
        }

        movement3d movement;
        _operators.classification (_reference, _markers, movement); // classify
        _markers_mutex.unlock ();
        movement = _movement3d_average.average (movement);
        _augmentation.setScale (movement.scale ());
        translation_t translation = movement.translation ();
        movement.translation (
        { movement.translation_delta_to_absolute (translation.x, image.width, -1, 1),
        movement.translation_delta_to_absolute (translation.y, image.height, -1, 1) });
        _augmentation.setXPosition (movement.translation ().x);
        _augmentation.setYPosition (movement.translation ().y);

        _augmentation.setYRotation (movement.yaw ());
        _augmentation.setZRotation (movement.roll ());
        _augmentation.setXRotation ((movement.pitch ()) - 90);
        std::cout << movement << std::endl;

        std::stringstream stream;
        stream << std::setprecision (2);
        // stream << "T(" << movement.translation ().x << ","
        //        << movement.translation ().y << ") ";
        stream << "S: " << movement.scale () << " ";
        stream << "yaw: " << movement.yaw () << " ";
        stream << "pitch: " << movement.pitch () << " ";
        stream << "roll: " << movement.roll () << std::endl;
        _statusbar.showMessage (stream.str ().c_str ());

        QImage debug_image ((const unsigned char*)image.data, image.width,
        image.height, QImage::Format_Grayscale8);
        debug_image.save ("debug_image.png");

        delete image.data;
    }
}
<commit_msg>fix qrong order err<commit_after>#include "vision.hpp"
#include "operators.hpp"

#include <QTemporaryFile>
#include <iomanip>
#include <iostream>
#include <sstream>

vision::vision (QStatusBar& statusbar, augmentation_widget& augmentation, QObject* parent)
: QObject (parent)
, _movement3d_average (1)
, _failed_frames_counter (0)
, _debug_mode (0)
, _augmentation (augmentation)
, _cam (new QCamera (QCamera::BackFace))
, _video_player (NULL)
, _acquisition (this)
, _operators ()
, _statusbar (statusbar) {
    _cam->setViewfinder (&_acquisition);
    connect (&_acquisition, SIGNAL (frameAvailable (const QVideoFrame&)), this,
    SLOT (frame_callback (const QVideoFrame&)));
    _cam->start ();
}

void vision::set_debug_mode (const int mode) {
    _debug_mode = mode;
}
int vision::debug_mode () {
    return _debug_mode;
}

void vision::set_input (const QCameraInfo& cameraInfo) {
    if (_video_player != NULL) {
        delete _video_player;
    }
    _video_player = NULL;
    if (_cam != NULL) {
        delete _cam;
    }

    _cam = new QCamera (cameraInfo);
    _cam->setViewfinder (&_acquisition);
    _cam->start ();
    if (_cam->status () != QCamera::ActiveStatus) {
        _statusbar.showMessage (QString ("camera status %1").arg (_cam->status ()), 2000);
    }
}

void vision::set_input (const QString& resource_path) {
    QFile resource_file (resource_path);
    if (resource_file.exists ()) {
        auto temp_file  = QTemporaryFile::createNativeFile (resource_file);
        QString fs_path = temp_file->fileName ();

        if (!fs_path.isEmpty ()) {
            if (_cam != NULL) {
                delete _cam;
            }
            _cam = NULL;
            if (_video_player != NULL) {
                delete _video_player;
            }

            _video_player = new QMediaPlayer ();
            _video_player->setVideoOutput (&_acquisition);
            _video_player->setMedia (QUrl::fromLocalFile (fs_path));
            _video_player->play ();
        }
    }
}

void vision::set_paused (bool paused) {
    if (paused) {
        disconnect (&_acquisition, SIGNAL (frameAvailable (const QVideoFrame&)),
        this, SLOT (frame_callback (const QVideoFrame&)));
    } else {
        connect (&_acquisition, SIGNAL (frameAvailable (const QVideoFrame&)),
        this, SLOT (frame_callback (const QVideoFrame&)));
    }
}

void set_focus () {
    ; // TODO: add focus implementation
}

void vision::set_reference () {
    _markers_mutex.lock ();
    _reference = _markers;
    _markers_mutex.unlock ();
}

void vision::frame_callback (const QVideoFrame& const_buffer) {
    bool status = true;
    image_t image;
    if (const_buffer.isValid ()) {
        // copy image into cpu memory
        QVideoFrame frame (const_buffer);
        if (frame.map (QAbstractVideoBuffer::ReadOnly)) {
            image.data = (uint8_t*)malloc (frame.mappedBytes ());
            memcpy (image.data, frame.bits (), frame.mappedBytes ());

            if (frame.pixelFormat () == QVideoFrame::Format_RGB24) {
                image.format = RGB24;
                image.width  = frame.width ();
                image.height = frame.height ();
            } else if (frame.pixelFormat () == QVideoFrame::Format_YUV420P) {
                image.format = YUV;
                image.width  = frame.width ();
                image.height = frame.height ();
            } else {
                _statusbar.showMessage (
                QString ("unsuported format %1").arg (frame.pixelFormat ()), 2000);
            }
        } else {
            status = false;
        }
        frame.unmap ();
    }

    if (status) {
        if (_debug_mode == 0) {
            _augmentation.setBackground (image);
            _augmentation.update ();
        }
        // start image processing
        _operators.preprocessing (image);
        if (_debug_mode == 1) {
            _augmentation.setBackground (image);
            _augmentation.update ();
        }

        _operators.segmentation (image);
        if (_debug_mode == 2) {
            _augmentation.setBackground (image);
            _augmentation.update ();
        }

        _markers_mutex.lock ();
        _markers.clear ();
        _operators.extraction (image, _markers);
        if (_debug_mode == 3) {
            _augmentation.setBackground (image);
            _augmentation.update ();
        }

        movement3d movement;
        _operators.classification (_reference, _markers, movement); // classify
        _markers_mutex.unlock ();
        movement = _movement3d_average.average (movement);
        _augmentation.setScale (movement.scale ());
        translation_t translation = movement.translation ();
        movement.translation (
        { movement.translation_delta_to_absolute (translation.x, image.width, -1, 1),
        movement.translation_delta_to_absolute (translation.y, image.height, -1, 1) });
        _augmentation.setXPosition (movement.translation ().x);
        _augmentation.setYPosition (movement.translation ().y);

        _augmentation.setYRotation (movement.yaw ());
        _augmentation.setZRotation (movement.roll ());
        _augmentation.setXRotation ((movement.pitch ()) - 90);
        std::cout << movement << std::endl;

        std::stringstream stream;
        stream << std::setprecision (2);
        // stream << "T(" << movement.translation ().x << ","
        //        << movement.translation ().y << ") ";
        stream << "S: " << movement.scale () << " ";
        stream << "yaw: " << movement.yaw () << " ";
        stream << "pitch: " << movement.pitch () << " ";
        stream << "roll: " << movement.roll () << std::endl;
        _statusbar.showMessage (stream.str ().c_str ());

        QImage debug_image ((const unsigned char*)image.data, image.width,
        image.height, QImage::Format_Grayscale8);
        debug_image.save ("debug_image.png");

        delete image.data;
    }
}
<|endoftext|>