From 1dc6f27c9e5bb8f087312d4dc6fbb53304b9303f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=8B=D1=87=D0=BA=D0=BE=D0=B2=20=D0=90=D0=BD=D0=B4?= =?UTF-8?q?=D1=80=D0=B5=D0=B9?= Date: Tue, 28 Feb 2017 15:42:28 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/pip@315 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5 --- src/math/picrypt.cpp | 36 ++++--- src/piversion.h | 2 +- src/thread/pigrabberbase.h | 196 +++++++++++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+), 16 deletions(-) create mode 100644 src/thread/pigrabberbase.h diff --git a/src/math/picrypt.cpp b/src/math/picrypt.cpp index f52baf55..bed068e1 100644 --- a/src/math/picrypt.cpp +++ b/src/math/picrypt.cpp @@ -28,7 +28,8 @@ const char hash_def_key[] = "_picrypt_"; PICrypt::PICrypt() { #ifdef PIP_CRYPT - sodium_init(); + int ret; + ret = sodium_init(); nonce_.resize(crypto_secretbox_NONCEBYTES); key_.resize(crypto_secretbox_KEYBYTES); randombytes_buf(key_.data(), key_.size()); @@ -72,22 +73,23 @@ PIByteArray PICrypt::crypt(const PIByteArray & data) { PIByteArray PICrypt::crypt(const PIByteArray & data, PIByteArray key) { - PIByteArray ret; + PIByteArray retba; #ifdef PIP_CRYPT if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' '); //return PIByteArray(); - sodium_init(); + int ret; + ret = sodium_init(); PIByteArray n; - ret.resize(data.size() + crypto_secretbox_MACBYTES); + retba.resize(data.size() + crypto_secretbox_MACBYTES); n.resize(crypto_secretbox_NONCEBYTES); randombytes_buf(n.data(), n.size()); - crypto_secretbox_easy(ret.data(), data.data(), data.size(), n.data(), key.data()); - ret.append(n); + crypto_secretbox_easy(retba.data(), data.data(), data.size(), n.data(), key.data()); + retba.append(n); #else piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT=1"; #endif - return ret; + return retba; } @@ -112,7 +114,7 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, bool *ok) { PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bool *ok) { - PIByteArray ret; + PIByteArray retba; #ifdef PIP_CRYPT if (key.size() != crypto_secretbox_KEYBYTES) key.resize(crypto_secretbox_KEYBYTES, ' '); @@ -123,12 +125,13 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bo if (ok) *ok = false; return PIByteArray(); } - sodium_init(); + int ret; + ret = sodium_init(); PIByteArray n; n.resize(crypto_secretbox_NONCEBYTES); - ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); + retba.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size()); - if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), key.data()) != 0) { + if (crypto_secretbox_open_easy(retba.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), key.data()) != 0) { if (ok) *ok = false; // piCout << "[PICrypt]" << "bad key_"; return PIByteArray(); @@ -137,14 +140,15 @@ PIByteArray PICrypt::decrypt(const PIByteArray & crypt_data, PIByteArray key, bo piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT="; #endif if (ok) *ok = true; - return ret; + return retba; } PIByteArray PICrypt::hash(const PIString & secret) { PIByteArray hash; #ifdef PIP_CRYPT - sodium_init(); + int ret; + ret = sodium_init(); hash.resize(crypto_generichash_BYTES); PIByteArray s(secret.data(), secret.size()); crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), (const uchar*)hash_def_key, sizeof(hash_def_key) - 1); @@ -159,7 +163,8 @@ ullong PICrypt::shorthash(const PIString& s, PIByteArray key) { ullong hash = 0; #ifdef PIP_CRYPT if (crypto_shorthash_BYTES != sizeof(hash)) piCout << "[PICrypt]" << "internal error: bad hash size"; - sodium_init(); + int ret; + ret = sodium_init(); if (key.size() != crypto_shorthash_KEYBYTES) { piCout << "[PICrypt]" << "invalid key size" << key.size() << ", shoud be" << crypto_shorthash_KEYBYTES << ", filled zeros"; key.resize(crypto_shorthash_KEYBYTES, 0); @@ -176,7 +181,8 @@ ullong PICrypt::shorthash(const PIString& s, PIByteArray key) { PIByteArray PICrypt::generateKey() { PIByteArray hash; #ifdef PIP_CRYPT - sodium_init(); + int ret; + ret = sodium_init(); hash.resize(crypto_secretbox_KEYBYTES); randombytes_buf(hash.data(), hash.size()); #else diff --git a/src/piversion.h b/src/piversion.h index 5a53ef70..413d3b35 100644 --- a/src/piversion.h +++ b/src/piversion.h @@ -4,7 +4,7 @@ #define PIP_VERSION_MAJOR 0 #define PIP_VERSION_MINOR 7 -#define PIP_VERSION_REVISION 1 +#define PIP_VERSION_REVISION 2 #define PIP_VERSION_SUFFIX "" #endif // PIVERSION_H diff --git a/src/thread/pigrabberbase.h b/src/thread/pigrabberbase.h new file mode 100644 index 00000000..d0b4ba2f --- /dev/null +++ b/src/thread/pigrabberbase.h @@ -0,0 +1,196 @@ +/*! \file pigrabberbase.h + * \brief Abstract class for create grabbers +*/ +/* + PIP - Platform Independent Primitives + Abstract class for create grabbers + Copyright (C) 2017 Andrey Bychkov work.a.b@yandex.ru + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef PIGRABBERBASE_H +#define PIGRABBERBASE_H + +#include "pithread.h" +#include "pidiagnostics.h" + + +template +class PIGrabberBase: public PIThread +{ + PIOBJECT_SUBCLASS(PIGrabberBase, PIThread) +public: + PIGrabberBase() { + is_opened = false; + is_recording = false; + } + virtual ~PIGrabberBase() { + stopGrabber(false); + } + virtual bool isOpened() const {return is_opened;} + virtual bool isRecording() const {return is_recording;} + virtual void startRecord(const PIString & filename) { + if (!isOpened()) return; + if (isRecording()) return; + rec_mutex.lock(); + startRecordInternal(filename); + is_recording = true; + rec_mutex.unlock(); + } + virtual void stopRecord() { + if (!isOpened()) return; + if (!isRecording()) return; + rec_mutex.lock(); + is_recording = false; + stopRecordInternal(); + rec_mutex.unlock(); + } + T last() const { + T ret; + last_mutex.lock(); + ret = last_; + last_mutex.unlock(); + return ret; + } + bool isEmpty() { + bool ret; + que_mutex.lock(); + ret = que.isEmpty(); + que_mutex.unlock(); + return ret; + } + int queSize() { + int ret; + que_mutex.lock(); + ret = que.size(); + que_mutex.unlock(); + return ret; + } + T dequeue() { + T ret; +// piCoutObj << "start"; + que_mutex.lock(); + if (!que.isEmpty()) { +// piCoutObj << "dequeue"; + ret = que.dequeue(); + } +// piCoutObj << "end"; + que_mutex.unlock(); + return ret; + } + void stopGrabber(bool wait_forever = true) { + if (isRunning()) { + stop(); + if (wait_forever) waitForFinish(); + else { + if (!waitForFinish(100)) terminate(); + stopRecord(); + close(); + } + } + } + bool open() { + bool ret = openInternal(); + if (!is_opened && ret) + opened(); + is_opened = ret; + return ret; + } + void close() { + bool em = is_opened; + closeInternal(); + last_ = T(); + if (em) + closed(); + is_opened = false; + } + const PIDiagnostics & diag() const {return diag_;} + void clear() { + que_mutex.lock(); + que.clear(); + que_mutex.unlock(); + } + void restart() { + clear(); + close(); + } + + EVENT(dataReady) + EVENT(opened) + EVENT(closed) + +protected: + virtual void init() {} + virtual bool openInternal() = 0; + virtual void closeInternal() = 0; + virtual int get(T & val) = 0; + virtual void record(const T & val) {} + virtual void startRecordInternal(const PIString & filename) {} + virtual void stopRecordInternal() {} + + bool is_opened, is_recording; + mutable PIMutex rec_mutex; + +private: + void begin() { + init(); + } + void run() { + if (!isOpened()) { + open(); + diag_.reset(); + if (!is_opened) + piMSleep(200); + } + if (isOpened()) { + T c; + int ret = get(c); + if (ret < 0) { + close(); + return; + } + if (ret > 0) { + piMSleep(1); + return; + } + diag_.received(1); + que_mutex.lock(); + que.enqueue(c); + que_mutex.unlock(); + if (isRecording()) { + rec_mutex.lock(); + record(c); + rec_mutex.unlock(); + diag_.sended(1); + } + last_mutex.lock(); + last_ = c; + last_mutex.unlock(); + dataReady(); + } + } + + void end() { + stopRecord(); + close(); + } + + T last_; + PIQueue que; + PIDiagnostics diag_; + mutable PIMutex que_mutex, last_mutex; +}; + +#endif // PIGRABBERBASE_H