Merge pull request #1 from bytemaster/phoenix

Various updates / cleanup of fc code.
This commit is contained in:
phoenixint 2013-07-01 12:24:28 -07:00
commit 92e22c3e30
44 changed files with 1525 additions and 520 deletions

View file

@ -9,7 +9,8 @@ INCLUDE( VersionMacros )
INCLUDE( SetupTargetMacros )
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} )
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/include )
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/vendor/boost_1_51/include )
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/vendor/cyoencode-1.0.2/src )
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/vendor/boost_1.51/include )
SET( DEFAULT_HEADER_INSTALL_DIR include/\${target} )
SET( DEFAULT_LIBRARY_INSTALL_DIR lib/ )
@ -57,15 +58,10 @@ option( UNITY_BUILD OFF )
FIND_PACKAGE( OpenSSL )
include_directories( vendor/boost_1.51/include )
include_directories( ${Boost_INCLUDE_DIR} )
include_directories( ${OPENSSL_INCLUDE_DIR} )
SET( ALL_OPENSSL_LIBRARIES
${OPENSSL_LIBRARIES}
${SSL_EAY_RELEASE}
${LIB_EAY_RELEASE}
)
SET( ALL_OPENSSL_LIBRARIES ${OPENSSL_LIBRARIES} ${SSL_EAY_RELEASE} ${LIB_EAY_RELEASE})
set( fc_sources
src/variant.cpp
@ -99,12 +95,14 @@ set( fc_sources
src/log/file_appender.cpp
src/log/logger_config.cpp
src/crypto/base36.cpp
src/crypto/bigint.cpp
src/crypto/base32.cpp
src/crypto/base64.cpp
src/crypto/base58.cpp
src/crypto/bigint.cpp
src/crypto/hex.cpp
src/crypto/sha1.cpp
src/crypto/sha256.cpp
src/crypto/sha224.cpp
src/crypto/sha512.cpp
src/crypto/dh.cpp
src/crypto/blowfish.cpp
@ -116,6 +114,8 @@ set( fc_sources
src/network/ip.cpp
src/network/resolve.cpp
src/network/url.cpp
vendor/cyoencode-1.0.2/src/CyoDecode.c
vendor/cyoencode-1.0.2/src/CyoEncode.c
# src/ssh/client.cpp
# src/ssh/process.cpp
)

View file

@ -20,12 +20,12 @@ namespace fc {
template<typename T, size_t N>
void to_variant( const array<T,N>& bi, variant& v )
{
v = fc::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
v = std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
}
template<typename T, size_t N>
void from_variant( const variant& v, array<T,N>& bi )
{
fc::vector<char> ve = v.as< vector<char> >();
std::vector<char> ve = v.as< std::vector<char> >();
if( ve.size() )
{
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );

View file

@ -4,7 +4,7 @@
namespace fc
{
fc::vector<char> from_base32( const fc::string& b32 );
fc::string to_base32( const fc::vector<char>& vec );
std::vector<char> from_base32( const fc::string& b32 );
fc::string to_base32( const std::vector<char>& vec );
fc::string to_base32( const char* data, size_t len );
}

View file

@ -4,7 +4,7 @@
namespace fc
{
fc::vector<char> from_base36( const fc::string& b36 );
fc::string to_base36( const fc::vector<char>& vec );
std::vector<char> from_base36( const fc::string& b36 );
fc::string to_base36( const std::vector<char>& vec );
fc::string to_base36( const char* data, size_t len );
}

View file

@ -9,7 +9,7 @@ typedef bignum_st BIGNUM;
namespace fc {
class bigint {
public:
bigint( const fc::vector<char>& bige );
bigint( const std::vector<char>& bige );
bigint( const char* bige, uint32_t l );
bigint( unsigned long i = 0 );
bigint( const bigint& c );
@ -52,7 +52,7 @@ namespace fc {
operator fc::string()const;
// returns bignum as bigendian bytes
operator fc::vector<char>()const;
operator std::vector<char>()const;
BIGNUM* dup()const;

View file

@ -1,5 +1,5 @@
#pragma once
#include <fc/vector.hpp>
#include <vector>
#include <stdint.h>
namespace fc {
@ -9,13 +9,13 @@ namespace fc {
bool generate_params( int s, uint8_t g );
bool generate_pub_key();
bool compute_shared_key( const char* buf, uint32_t s );
bool compute_shared_key( const vector<char>& pubk);
bool compute_shared_key( const std::vector<char>& pubk);
bool validate();
vector<char> p;
vector<char> pub_key;
vector<char> priv_key;
vector<char> shared_key;
std::vector<char> p;
std::vector<char> pub_key;
std::vector<char> priv_key;
std::vector<char> shared_key;
bool valid;
uint8_t g;
};

View file

@ -31,6 +31,7 @@ namespace fc {
public_key( const compact_signature& c, const fc::sha256& digest );
bool valid()const;
public_key mult( const fc::sha256& digest );
public_key( public_key&& pk );
public_key& operator=( public_key&& pk );
@ -65,7 +66,7 @@ namespace fc {
fc::sha512 get_shared_secret( const public_key& pub );
signature sign( const fc::sha256& digest );
compact_signature sign_compact( const fc::sha256& digest );
compact_signature sign_compact( const fc::sha256& digest )const;
bool verify( const fc::sha256& digest, const signature& sig );
public_key get_public_key()const;

View file

@ -69,3 +69,17 @@ class sha1
void from_variant( const variant& v, sha1& bi );
} // namespace fc
namespace std
{
template<typename T> struct hash;
template<>
struct hash<fc::sha1>
{
size_t operator()( const fc::sha1& s )const
{
return *((size_t*)&s);
}
};
}

View file

@ -0,0 +1,86 @@
#pragma once
#include <fc/fwd.hpp>
#include <fc/string.hpp>
namespace fc
{
class sha224
{
public:
sha224();
explicit sha224( const string& hex_str );
string str()const;
operator string()const;
char* data()const;
static sha224 hash( const char* d, uint32_t dlen );
static sha224 hash( const string& );
template<typename T>
static sha224 hash( const T& t )
{
sha224::encoder e;
e << t;
return e.result();
}
class encoder
{
public:
encoder();
~encoder();
void write( const char* d, uint32_t dlen );
void put( char c ) { write( &c, 1 ); }
void reset();
sha224 result();
private:
struct impl;
fc::fwd<impl,112> my;
};
template<typename T>
inline friend T& operator<<( T& ds, const sha224& ep ) {
ds.write( ep.data(), sizeof(ep) );
return ds;
}
template<typename T>
inline friend T& operator>>( T& ds, sha224& ep ) {
ds.read( ep.data(), sizeof(ep) );
return ds;
}
friend sha224 operator << ( const sha224& h1, uint32_t i );
friend bool operator == ( const sha224& h1, const sha224& h2 );
friend bool operator != ( const sha224& h1, const sha224& h2 );
friend sha224 operator ^ ( const sha224& h1, const sha224& h2 );
friend bool operator >= ( const sha224& h1, const sha224& h2 );
friend bool operator > ( const sha224& h1, const sha224& h2 );
friend bool operator < ( const sha224& h1, const sha224& h2 );
uint64_t _hash[3];
uint32_t _hash4;
};
class variant;
void to_variant( const sha224& bi, variant& v );
void from_variant( const variant& v, sha224& bi );
} // fc
namespace std
{
template<typename T> struct hash;
template<>
struct hash<fc::sha224>
{
size_t operator()( const fc::sha224& s )const
{
return *((size_t*)&s);
}
};
}

View file

@ -1,7 +1,7 @@
#pragma once
#include <fc/thread/future.hpp>
#include <fc/io/buffered_iostream.hpp>
#include <fc/vector.hpp>
#include <vector>
#include <fc/string.hpp>
#include <fc/filesystem.hpp>
@ -22,6 +22,7 @@ namespace fc
open_stdout = 0x02,
open_stderr = 0x04,
open_all = open_stdin|open_stdout|open_stderr,
suppress_console = 0x08
};
virtual ~iprocess(){}
@ -30,7 +31,7 @@ namespace fc
*
* @return *this
*/
virtual iprocess& exec( const fc::path& exe, vector<string> args,
virtual iprocess& exec( const fc::path& exe, std::vector<std::string> args,
const fc::path& work_dir = fc::path(), exec_opts opts = open_all ) = 0;
/**

View file

@ -16,7 +16,7 @@ namespace fc {
~process();
virtual iprocess& exec( const fc::path& exe,
vector<string> args,
std::vector<std::string> args,
const fc::path& work_dir = fc::path(),
exec_opts opts = open_all );

View file

@ -1,10 +1,10 @@
#pragma once
#include <fc/shared_ptr.hpp>
#include <fc/string.hpp>
namespace fc {
class appender;
class log_message;
class string;
class variant;
class appender_factory : public fc::retainable {

View file

@ -18,7 +18,7 @@ namespace fc {
fc::string val;
};
typedef fc::vector<header> headers;
typedef std::vector<header> headers;
struct reply
{
@ -31,8 +31,8 @@ namespace fc {
};
reply( status_code c = OK):status(c){}
int status;
fc::vector<header> headers;
fc::vector<char> body;
std::vector<header> headers;
std::vector<char> body;
};
struct request
@ -41,11 +41,11 @@ namespace fc {
fc::string method;
fc::string domain;
fc::string path;
fc::vector<header> headers;
fc::vector<char> body;
std::vector<header> headers;
std::vector<char> body;
};
fc::vector<header> parse_urlencoded_params( const fc::string& f );
std::vector<header> parse_urlencoded_params( const fc::string& f );
/**
* Connections have reference semantics, all copies refer to the same

View file

@ -13,6 +13,7 @@
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <stdint.h>
#include <string.h>
#include <fc/reflect/typename.hpp>

View file

@ -1,7 +1,10 @@
#pragma once
#include <fc/vector.hpp>
#include <functional>
#include <memory>
#include <fc/vector.hpp>
#include <fc/log/logger.hpp>
#include <fc/thread/mutex.hpp>
#include <fc/thread/unique_lock.hpp>
#ifdef emit
#undef emit
#endif
@ -10,72 +13,90 @@ namespace fc {
template<typename Signature>
class signal {
private:
typedef std::function<Signature> func_type;
typedef std::vector<std::shared_ptr<func_type>> list_type;
public:
typedef int64_t connection_id_type;
typedef void* connection_id_type;
template<typename Functor>
connection_id_type connect( Functor&& f ) {
auto c = new std::function<Signature>( fc::forward<Functor>(f) );
_handlers.push_back( c );
return reinterpret_cast<connection_id_type>(c);
fc::unique_lock<fc::mutex> lock(_mutex);
//auto c = new std::function<Signature>( fc::forward<Functor>(f) );
_handlers.push_back( std::make_shared<func_type>(f) );
return reinterpret_cast<connection_id_type>(_handlers.back().get());
}
#ifdef WIN32
template<typename Arg>
void emit( Arg&& arg ) {
for( size_t i = 0; i < _handlers.size(); ++i ) {
(*_handlers[i])( fc::forward<Arg>(arg) );
list_type handlers = getHandlers();
for( size_t i = 0; i < handlers.size(); ++i ) {
(*handlers[i])( fc::forward<Arg>(arg) );
}
}
void operator()() {
list_type handlers = getHandlers();
for( size_t i = 0; i < handlers.size(); ++i ) {
(*handlers[i])();
}
}
template<typename Arg>
void operator()( Arg&& arg ) {
for( size_t i = 0; i < _handlers.size(); ++i ) {
(*_handlers[i])( fc::forward<Arg>(arg) );
list_type handlers = getHandlers();
for( size_t i = 0; i < handlers.size(); ++i ) {
(*handlers[i])( fc::forward<Arg>(arg) );
}
}
template<typename Arg,typename Arg2>
void emit( Arg&& arg, Arg2&& arg2 ) {
for( size_t i = 0; i < _handlers.size(); ++i ) {
(*_handlers[i])( fc::forward<Arg>(arg), fc::forward<Arg2>(arg2) );
list_type handlers = getHandlers();
for( size_t i = 0; i < handlers.size(); ++i ) {
(*handlers[i])( fc::forward<Arg>(arg), fc::forward<Arg2>(arg2) );
}
}
template<typename Arg, typename Arg2>
void operator()( Arg&& arg, Arg2&& arg2 ) {
for( size_t i = 0; i < _handlers.size(); ++i ) {
(*_handlers[i])( fc::forward<Arg>(arg), fc::forward<Arg2>(arg2) );
list_type handlers = getHandlers();
for( size_t i = 0; i < handlers.size(); ++i ) {
(*handlers[i])( fc::forward<Arg>(arg), fc::forward<Arg2>(arg2) );
}
}
template<typename Arg, typename Arg2, typename Arg3>
void emit( Arg&& arg, Arg2&& arg2, Arg3&& arg3 ) {
for( size_t i = 0; i < _handlers.size(); ++i ) {
(*_handlers[i])( fc::forward<Arg>(arg), fc::forward<Arg2>(arg2), fc::forward<Arg3>(arg3) );
list_type handlers = getHandlers();
for( size_t i = 0; i < handlers.size(); ++i ) {
(*handlers[i])( fc::forward<Arg>(arg), fc::forward<Arg2>(arg2), fc::forward<Arg3>(arg3) );
}
}
template<typename Arg, typename Arg2, typename Arg3>
void operator()( Arg&& arg, Arg2&& arg2, Arg3&& arg3 ) {
for( size_t i = 0; i < _handlers.size(); ++i ) {
(*_handlers[i])( fc::forward<Arg>(arg), fc::forward<Arg2>(arg2), fc::forward<Arg3>(arg3) );
list_type handlers = getHandlers();
for( size_t i = 0; i < handlers.size(); ++i ) {
(*handlers[i])( fc::forward<Arg>(arg), fc::forward<Arg2>(arg2), fc::forward<Arg3>(arg3) );
}
}
#else
template<typename... Args>
void emit( Args&&... args ) {
for( size_t i = 0; i < _handlers.size(); ++i ) {
(*_handlers[i])( fc::forward<Args>(args)... );
list_type handlers = getHandlers();
for( size_t i = 0; i < handlers.size(); ++i ) {
(*handlers[i])( fc::forward<Args>(args)... );
}
}
template<typename... Args>
void operator()( Args&&... args ) {
for( size_t i = 0; i < _handlers.size(); ++i ) {
(*_handlers[i])( fc::forward<Args>(args)... );
list_type handlers = getHandlers();
for( size_t i = 0; i < handlers.size(); ++i ) {
(*handlers[i])( fc::forward<Args>(args)... );
}
}
#endif
void disconnect( connection_id_type cid ) {
fc::unique_lock<fc::mutex> lock(_mutex);
auto itr = _handlers.begin();
while( itr != _handlers.end() ) {
if( reinterpret_cast<connection_id_type>(*itr) == cid ) {
delete *itr;
if( reinterpret_cast<connection_id_type>(itr->get()) == cid ) {
_handlers.erase(itr);
}
++itr;
@ -85,17 +106,25 @@ namespace fc {
{
_handlers.reserve(4);
}
~signal()
{
for( auto itr = _handlers.begin(); itr != _handlers.end(); ++itr )
{
delete *itr;
}
_handlers.clear();
}
//~signal()
//{
// for( auto itr = _handlers.begin(); itr != _handlers.end(); ++itr )
// {
// delete *itr;
// }
// _handlers.clear();
//}
private:
fc::vector< std::function<Signature>* > _handlers;
fc::mutex _mutex;
list_type _handlers;
list_type getHandlers()
{
fc::unique_lock<fc::mutex> lock(_mutex);
list_type handlers(_handlers);
return handlers;
}
};
}

View file

@ -19,7 +19,7 @@ namespace fc { namespace ssh
class process : public iprocess
{
public:
virtual iprocess& exec( const fc::path& exe, vector<string> args,
virtual iprocess& exec( const fc::path& exe, std::vector<std::string> args,
const fc::path& work_dir = fc::path(), exec_opts opts = open_all );
/**

View file

@ -3,6 +3,25 @@
#include <fc/fwd.hpp>
#include <fc/optional.hpp>
#ifndef USE_FC_STRING
#include <string>
namespace fc
{
typedef std::string string;
int64_t to_int64( const fc::string& );
uint64_t to_uint64( const fc::string& );
double to_double( const fc::string& );
fc::string to_string( double );
fc::string to_string( uint64_t );
fc::string to_string( int64_t );
typedef fc::optional<fc::string> ostring;
class variant_object;
fc::string format_string( const fc::string&, const variant_object& );
}
#else
/**
* There is debate about whether doing this is 'standard conforming', but
@ -120,3 +139,4 @@ namespace fc {
} // namespace fc
#endif

View file

@ -109,7 +109,7 @@ namespace fc {
template<typename T1, typename T2>
int wait_any( const fc::future<T1>& f1, const fc::future<T2>& f2, const microseconds& timeout_us = microseconds::maximum()) {
fc::vector<fc::promise_base::ptr> proms(2);
std::vector<fc::promise_base::ptr> proms(2);
proms[0] = fc::static_pointer_cast<fc::promise_base>(f1.m_prom);
proms[1] = fc::static_pointer_cast<fc::promise_base>(f2.m_prom);
return wait_any_until(fc::move(proms), fc::time_point::now()+timeout_us );
@ -123,15 +123,15 @@ namespace fc {
friend void usleep(const microseconds&);
friend void sleep_until(const time_point&);
friend void exec();
friend int wait_any( fc::vector<promise_base::ptr>&& v, const microseconds& );
friend int wait_any_until( fc::vector<promise_base::ptr>&& v, const time_point& tp );
friend int wait_any( std::vector<promise_base::ptr>&& v, const microseconds& );
friend int wait_any_until( std::vector<promise_base::ptr>&& v, const time_point& tp );
void wait_until( promise_base::ptr && v, const time_point& tp );
void notify( const promise_base::ptr& v );
void yield(bool reschedule=true);
void sleep_until( const time_point& t );
void exec();
int wait_any_until( fc::vector<promise_base::ptr>&& v, const time_point& );
int wait_any_until( std::vector<promise_base::ptr>&& v, const time_point& );
void async_task( task_base* t, const priority& p, const char* desc );
void async_task( task_base* t, const priority& p, const time_point& tp, const char* desc );
@ -168,8 +168,8 @@ namespace fc {
int wait_any( const fc::future<T1>& f1, const fc::future<T2>& f2, const microseconds timeout_us = microseconds::maximum()) {
return fc::thread::current().wait_any(f1,f2,timeout_us);
}
int wait_any( fc::vector<promise_base::ptr>&& v, const microseconds& timeout_us = microseconds::maximum() );
int wait_any_until( fc::vector<promise_base::ptr>&& v, const time_point& tp );
int wait_any( std::vector<promise_base::ptr>&& v, const microseconds& timeout_us = microseconds::maximum() );
int wait_any_until( std::vector<promise_base::ptr>&& v, const time_point& tp );
template<typename Functor>
auto async( Functor&& f, const char* desc ="", priority prio = priority()) -> fc::future<decltype(f())> {

View file

@ -15,9 +15,11 @@ namespace fc
class wait_condition
{
public:
wait_condition(const char* name) : _name(name) {}
void wait( const microseconds& timeout = microseconds::maximum() )
{
typename fc::promise<T>::ptr p = new fc::promise<T>();
typename fc::promise<T>::ptr p = new fc::promise<T>(_name);
{ synchronized( _prom_lock )
_promises.push_back( p );
}
@ -27,11 +29,16 @@ namespace fc
template<typename LockType>
T wait( LockType& l, const microseconds& timeout = microseconds::maximum() )
{
typename fc::promise<T>::ptr p( new fc::promise<T>());
typename fc::promise<T>::ptr p( new fc::promise<T>(_name));
{ synchronized( _prom_lock )
_promises.push_back( p );
}
l.unlock();
struct relocker {
LockType& _lock;
relocker(LockType& l) : _lock(l) {}
~relocker() { _lock.lock(); }
} lock_on_exit(l);
return p->wait(timeout);
}
@ -53,7 +60,7 @@ namespace fc
{
std::deque<typename fc::promise<T>::ptr> all;
{ synchronized( _prom_lock )
all = fc::move(_promises);
std::swap(all, _promises);
}
for( auto itr = all.begin(); itr != all.end(); ++itr )
{
@ -64,5 +71,6 @@ namespace fc
private:
fc::spin_yield_lock _prom_lock;
std::deque<typename fc::promise<T>::ptr> _promises;
const char *const _name;
};
}

View file

@ -4,6 +4,7 @@
#include <fc/string.hpp>
#include <memory>
#include <string.h> // memset
#include <unordered_set>
namespace fc
{
@ -38,6 +39,12 @@ namespace fc
void from_variant( const variant& var, mutable_variant_object& vo );
void to_variant( const std::vector<char>& var, variant& vo );
void from_variant( const variant& var, std::vector<char>& vo );
template<typename T>
void to_variant( const std::unordered_set<T>& var, variant& vo );
template<typename T>
void from_variant( const variant& var, std::unordered_set<T>& vo );
void to_variant( const time_point& var, variant& vo );
void from_variant( const variant& var, time_point& vo );
#ifdef __APPLE__
@ -54,7 +61,7 @@ namespace fc
typedef std::vector<variant> variants;
/**
* @brief stores null, int64, uint64, double, bool, string, vector<variant>,
* @brief stores null, int64, uint64, double, bool, string, std::vector<variant>,
* and variant_object's.
*
* variant's allocate everything but strings, arrays, and objects on the
@ -244,6 +251,24 @@ namespace fc
from_variant( var, *vo );
}
}
template<typename T>
void to_variant( const std::unordered_set<T>& var, variant& vo )
{
std::vector<variant> vars(var.size());
size_t i = 0;
for( auto itr = var.begin(); itr != var.end(); ++itr )
vars[i] = variant(*itr);
vo = vars;
}
template<typename T>
void from_variant( const variant& var, std::unordered_set<T>& vo )
{
const variants& vars = var.get_array();
vo.clear();
vo.reserve( vars.size() );
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
vo.insert( itr->as<T>() );
}
/** @ingroup Serializable */
template<typename T>

View file

@ -71,7 +71,7 @@ namespace fc
variant_object( string key, T&& val )
:_key_value( std::make_shared<std::vector<entry> >() )
{
*this = variant_object( move(key), variant(forward<T>(val)) );
*this = variant_object( std::move(key), variant(forward<T>(val)) );
}
variant_object( const variant_object& );
variant_object( variant_object&& );
@ -173,7 +173,7 @@ namespace fc
template<typename T>
mutable_variant_object& operator()( string key, T&& var )
{
set(move(key), variant( forward<T>(var) ) );
set(std::move(key), variant( forward<T>(var) ) );
return *this;
}
///@}
@ -194,7 +194,7 @@ namespace fc
mutable_variant_object( string key, T&& val )
:_key_value( new std::vector<entry>() )
{
set( move(key), variant(forward<T>(val)) );
set( std::move(key), variant(forward<T>(val)) );
}
mutable_variant_object( mutable_variant_object&& );

View file

@ -1,411 +1,2 @@
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <fc/utility.hpp>
#include <vector>
namespace fc
{
template<typename T>
using vector = std::vector<T>;
}
#if 0
namespace fc {
namespace detail {
template<typename T>
struct data {
size_t size;
size_t capacity;
T first;
static data* allocate( size_t cap ) {
data* d = nullptr;
if( cap ){
d = (data*)malloc(sizeof(data) + sizeof(T)*(static_cast<size_t>(cap)-1));
d->capacity = static_cast<size_t>(cap);
} else {
d = (data*)malloc(sizeof(data));
d->capacity = 1;
}
d->size = 0;
return d;
}
static data* reallocate( data* d, size_t cap ) {
if( cap ){
d = (data*)realloc(d,sizeof(data) + sizeof(T)*(static_cast<size_t>(cap)-1));
d->capacity = static_cast<size_t>(cap);
} else {
d = (data*)realloc(d,sizeof(data));
d->capacity = 1;
}
if( d->size > d->capacity )
d->size = d->capacity;
return d;
}
private:
data(){};
};
template<typename T, typename IsClass=fc::false_type>
struct vector_impl {
public:
typedef T* iterator;
typedef const T* const_iterator;
vector_impl():_data(nullptr){}
vector_impl( vector_impl&& c):_data(c._data){c._data =nullptr; }
vector_impl( const vector_impl& c):_data(nullptr) {
if( c.size() ) {
_data = detail::data<T>::allocate( c.size() );
_data->size = c.size();
memcpy(begin(),c.begin(), static_cast<size_t>(c.size()) );
}
}
vector_impl(const_iterator b, const_iterator e ):_data(nullptr) {
resize(e-b);
if( size() ) memcpy( data(), b, static_cast<size_t>(size()) );
}
vector_impl(size_t s):_data(nullptr){
resize(s);
}
~vector_impl() {
clear();
}
size_t size()const { return _data ? _data->size : 0; }
size_t capacity()const { return _data ? _data->capacity : 0; }
T& back() { return (&_data->first)[-1+_data->size]; }
const T& back()const { return (&_data->first)[-1+_data->size]; }
T& front() { return (&_data->first)[0]; }
const T& front()const { return (&_data->first)[0]; }
const T* data()const { return (&_data->first); }
T* data() { return (&_data->first); }
iterator begin() { return _data ? &front() : 0;}
const_iterator begin()const { return _data ? &front() : 0;}
iterator end() { return _data ? (&back())+1: 0;}
const_iterator end()const { return _data ? (&back())+1: 0;}
T& operator[]( size_t i ) { return (&_data->first)[i]; }
const T& operator[]( size_t i )const { return (&_data->first)[i]; }
T& at( size_t i ) { return (&_data->first)[i]; }
const T& at( size_t i )const { return (&_data->first)[i]; }
void pop_back() { erase( &back() ); }
void clear() {
if( _data != nullptr ) {
free(_data);
}
_data = nullptr;
}
void reserve( size_t i ) {
if( nullptr == _data )
{
_data = detail::data<T>::allocate( i );
_data->size = 0;
_data->capacity = i;
}
else
{
_data = detail::data<T>::reallocate( _data, i );
}
}
void resize( size_t i ) {
if( capacity() < i ) {
if( _data )
_data = detail::data<T>::reallocate( _data, i );
else
_data = detail::data<T>::allocate( i );
}
if( _data ) _data->size = i;
}
template<typename U>
void push_back( U&& v ) {
resize( size()+1 );
back() = fc::forward<U>(v);
}
template<typename U>
void emplace_back( U&& v ) {
resize( size()+1 );
back() = fc::forward<U>(v);
}
template<typename U>
iterator insert( const_iterator loc, U&& t ) {
size_t pos = loc - begin();
resize( size()+1 );
char* src = &at(pos);
if( src != &back() )
memmove( src+1, src, (&back() - src) );
&back = fc::forward<U>(t);
return &at(pos);
}
iterator insert( iterator pos, const_iterator first, const_iterator last ) {
if( first >= last ) return pos;
size_t loc = pos - begin();
size_t right_size = size() - loc;
resize( size() + (last-first) );
char* src = &at(loc);
size_t s = last-first;
memmove( src + s, src, right_size );
memcpy( src, first, s );
_data->size += (last-first);
return src;
}
iterator erase( iterator pos ) {
memmove( pos, pos+1, (&back() - pos) );
_data->size--;
return pos;
}
iterator erase( iterator first, iterator last ) {
if( first != last ) {
memmove( first, first + (last-first), (&back() - last) );
_data->size -= last-first;
}
return first;
}
vector_impl& operator=( vector_impl&& v ) {
fc_swap(_data,v._data);
return *this;
}
vector_impl& operator=( const vector_impl& v ) {
vector_impl tmp(v);
fc_swap(tmp._data,_data);
return *this;
}
protected:
detail::data<T>* _data;
};
template<typename T>
struct vector_impl<T,fc::true_type> {
public:
typedef T* iterator;
typedef const T* const_iterator;
vector_impl():_data(nullptr){}
vector_impl( vector_impl&& c):_data(c._data){c._data =nullptr; }
vector_impl( const vector_impl& c):_data(nullptr) {
if( c.size() ) {
_data = detail::data<T>::allocate( c.size() );
auto i = begin();
auto ci = c.begin();
auto ce = c.end();
while( ci != ce ) {
new (i) T(*ci);
++i;
++_data->size;
++ci;
}
}
}
vector_impl(const_iterator b, const_iterator e ):_data(nullptr) {
resize(e-b);
for( auto i = begin(); i != end(); ++i ) {
*i = *b;
++b;
}
}
vector_impl(size_t s):_data(nullptr){
resize(s);
}
~vector_impl() {
clear();
}
size_t size()const { return _data ? _data->size : 0; }
size_t capacity()const { return _data ? _data->capacity : 0; }
T& back() { return (&_data->first)[-1+_data->size]; }
const T& back()const { return (&_data->first)[-1+_data->size]; }
T& front() { return (&_data->first)[0]; }
const T& front()const { return (&_data->first)[0]; }
const T* data()const { return (&_data->first); }
T* data() { return (&_data->first); }
iterator begin() { return _data ? &front() : 0;}
const_iterator begin()const { return _data ? &front() : 0;}
const_iterator end()const { return _data ? (&back())+1: 0;}
iterator end(){ return _data ? (&back())+1: 0;}
T& operator[]( size_t i ) { return (&_data->first)[i]; }
const T& operator[]( size_t i )const { return (&_data->first)[i]; }
T& at( size_t i ) { return (&_data->first)[i]; }
const T& at( size_t i )const { return (&_data->first)[i]; }
void pop_back() { erase( &back() ); }
void clear() {
if( this->_data != nullptr ) {
auto c = this->begin();
auto e = this->end();
while( c != e ) {
(*c).~T();
++c;
}
free(this->_data);
}
this->_data = nullptr;
}
void reserve( size_t i ) {
if( nullptr != this->_data && i <= this->_data->capacity )
return;
auto _ndata = detail::data<T>::allocate( i );
auto nc = &_ndata->first;
auto c = this->begin();
auto e = this->end();
while( c != e ) {
new (nc) T(fc::move( *c ));
(*c).~T();
++_ndata->size;
++c;
++nc;
}
fc_swap( _ndata, this->_data );
if( _ndata ) free(_ndata);
}
void resize( size_t i ) {
this->reserve(i);
while( i < this->_data->size ) {
this->back().~T();
--this->_data->size;
}
while( this->_data->size < i ) {
new (&this->back()+1) T();
++this->_data->size;
}
}
template<typename U>
void push_back( U&& v ) {
this->reserve( this->size()+1 );
new (&back()+1) T(fc::forward<U>(v));
++this->_data->size;
}
template<typename U>
void emplace_back( U&& v ) {
this->reserve( this->size()+1 );
new (&back()+1) T(fc::forward<U>(v));
++this->_data->size;
}
template<typename U>
iterator insert( const_iterator loc, U&& t ) {
size_t pos = loc - this->begin();
this->reserve( this->size()+1 );
loc = this->begin() + pos;
if( this->size() != 0 ) {
new ((void*)this->end()) T( fc::move(this->back()) );
auto cur = this->back();
++this->_data->size;
while( cur != loc ) {
*cur = fc::move( *(cur-1) );
}
*cur = fc::forward<U>(t);
} else {
new (this->end()) T( fc::forward<U>(t) );
++this->_data->size;
}
return &this->at(pos);
}
iterator insert( iterator pos, const_iterator first, const_iterator last ) {
//static_assert( false, "Not Implemented" );
return 0;
}
iterator erase( iterator pos ) {
if( pos == this->end() ) { return pos; }
auto next = pos + 1;
while( next != this->end() ) {
*pos = fc::move(*next);
++pos; ++next;
}
pos->~T();
this->_data->size--;
return pos;
}
iterator erase( iterator first, iterator last ) {
iterator c = first;
iterator m = last;
iterator e = this->end();
while( c != e ) {
if( m != e ) *c = fc::move( *m );
else c->~T();
++c;
++m;
}
this->_data->size -= last-first;
return last;
}
vector_impl& operator=( vector_impl&& v ) {
fc_swap(_data,v._data);
return *this;
}
vector_impl& operator=( const vector_impl& v ) {
vector_impl tmp(v);
fc_swap(tmp._data,_data);
return *this;
}
private:
detail::data<T>* _data;
};
}
/**
* @brief provides a light-weight vector similar to std::vector except that
* it prevents needing to include <vector> which requires many more headers
* and increases compile times.
*
* This class should have the same API as std::vector and can be expanded as
* additional features of std::vector are required.
*
*/
template<typename T>
class vector : public detail::vector_impl<T, typename fc::is_class<T>::type> {
public:
vector(){}
vector( size_t s ):detail::vector_impl<T, typename fc::is_class<T>::type>(s){}
vector( const vector& v ):detail::vector_impl<T, typename fc::is_class<T>::type>(v){}
vector( vector&& v ):detail::vector_impl<T, typename fc::is_class<T>::type>(fc::move(v)){}
vector( const T* b, const T* e ):detail::vector_impl<T, typename fc::is_class<T>::type>(b,e){}
vector& operator=( vector&& v ) {
*((base*)this) = fc::move(v);
return *this;
}
vector& operator=( const vector& v ) {
*((base*)this) = v;
return *this;
}
private:
typedef detail::vector_impl<T, typename fc::is_class<T>::type> base;
};
};
#endif

View file

@ -3,25 +3,25 @@
#include <CyoEncode.h>
namespace fc
{
fc::vector<char> from_base32( const fc::string& b32 )
std::vector<char> from_base32( const std::string& b32 )
{
auto len = cyoBase32DecodeGetLength( b32.size() );
fc::vector<char> v(len);
std::vector<char> v(len);
cyoBase32Decode( v.data(), b32.c_str(), b32.size() );
return v;
}
fc::string to_base32( const char* data, size_t len )
std::string to_base32( const char* data, size_t len )
{
auto s = cyoBase16EncodeGetLength(len);
fc::string b32;
std::vector<char> b32;
b32.resize(s);
cyoBase16Encode( b32.data(), data, len );
b32.resize( b32.size()-1); // strip the nullterm
return b32;
return std::string(b32.begin(),b32.end());
}
fc::string to_base32( const fc::vector<char>& vec )
std::string to_base32( const std::vector<char>& vec )
{
return to_base32( vec.data(), vec.size() );
}

View file

@ -9,7 +9,7 @@ namespace fc
if( len == 0 ) return fc::string();
fc::bigint value( data, len );
auto base36 = "0123456789abcdefghijklmnopqrstuvwxyz";
fc::vector<char> out( static_cast<size_t>(len * 1.6) + 1 );
std::vector<char> out( static_cast<size_t>(len * 1.6) + 1 );
int pos = out.size() - 1;
out[pos] = '\0';
fc::bigint _36(36);
@ -23,12 +23,12 @@ namespace fc
return &out[pos]; //fc::string( &out[pos], out.size() - pos);
}
fc::string to_base36( const fc::vector<char>& vec )
fc::string to_base36( const std::vector<char>& vec )
{
return to_base36( (const char*)vec.data(), vec.size() );
}
fc::vector<char> from_base36( const fc::string& b36 )
std::vector<char> from_base36( const fc::string& b36 )
{
fc::bigint value;

View file

@ -8,7 +8,7 @@ namespace fc {
bigint::bigint( const char* bige, uint32_t l ) {
n = BN_bin2bn( (const unsigned char*)bige, l, NULL );
}
bigint::bigint( const fc::vector<char>& bige ) {
bigint::bigint( const std::vector<char>& bige ) {
n = BN_bin2bn( (const unsigned char*)bige.data(), bige.size(), NULL );
}
bigint::bigint( BIGNUM* in )
@ -149,8 +149,8 @@ namespace fc {
return BN_bn2dec(n);
}
bigint::operator fc::vector<char>()const {
fc::vector<char> to(BN_num_bytes(n));
bigint::operator std::vector<char>()const {
std::vector<char> to(BN_num_bytes(n));
BN_bn2bin(n,(unsigned char*)to.data());
return to;
}
@ -158,7 +158,7 @@ namespace fc {
/** encodes the big int as base64 string, or a number */
void to_variant( const bigint& bi, variant& v )
{
fc::vector<char> ve = bi;
std::vector<char> ve = bi;
v = fc::variant(base64_encode((unsigned char*)ve.data(),ve.size()));
}

View file

@ -84,7 +84,7 @@ namespace fc {
DH_free(dh);
return valid = true;
}
bool diffie_hellman::compute_shared_key( const vector<char>& pubk ) {
bool diffie_hellman::compute_shared_key( const std::vector<char>& pubk ) {
return compute_shared_key( &pubk.front(), pubk.size() );
}

View file

@ -11,6 +11,50 @@
#include <assert.h>
namespace fc { namespace ecc {
template <typename ssl_type>
struct ssl_wrapper
{
ssl_wrapper(ssl_type* obj)
: obj(obj) {}
virtual ~ssl_wrapper()
{
}
operator ssl_type*()
{
return obj;
}
ssl_type* obj;
};
struct ssl_bignum
: public ssl_wrapper<BIGNUM>
{
ssl_bignum()
: ssl_wrapper(BN_new()) {}
~ssl_bignum()
{
BN_free(obj);
}
};
#define SSL_TYPE(name, ssl_type, free_func) \
struct name \
: public ssl_wrapper<ssl_type> \
{ \
name(ssl_type* obj) \
: ssl_wrapper(obj) {} \
~name() \
{ \
free_func(obj); \
} \
};
SSL_TYPE(ec_group, EC_GROUP, EC_GROUP_free)
SSL_TYPE(ec_point, EC_POINT, EC_POINT_free)
SSL_TYPE(bn_ctx, BN_CTX, BN_CTX_free)
namespace detail
{
class public_key_impl
@ -188,6 +232,30 @@ namespace fc { namespace ecc {
}
*/
public_key public_key::mult( const fc::sha256& digest )
{
// get point from this public key
const EC_POINT* master_pub = EC_KEY_get0_public_key( my->_key );
ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1));
ssl_bignum z;
BN_bin2bn((unsigned char*)&digest, sizeof(digest), z);
// multiply by digest
ssl_bignum one;
bn_ctx ctx(BN_CTX_new());
BN_one(one);
ec_point result(EC_POINT_new(group));
EC_POINT_mul(group, result, z, master_pub, one, ctx);
public_key rtn;
rtn.my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 );
EC_KEY_set_public_key(rtn.my->_key,result);
return rtn;
}
private_key::private_key()
{}
@ -275,8 +343,8 @@ namespace fc { namespace ecc {
public_key_data public_key::serialize()const
{
EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
size_t nbytes = i2o_ECPublicKey( my->_key, nullptr );
assert( nbytes == 33 );
/*size_t nbytes = */i2o_ECPublicKey( my->_key, nullptr );
/*assert( nbytes == 33 )*/
public_key_data dat;
char* front = &dat.data[0];
i2o_ECPublicKey( my->_key, (unsigned char**)&front );
@ -384,7 +452,7 @@ namespace fc { namespace ecc {
FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" );
}
compact_signature private_key::sign_compact( const fc::sha256& digest )
compact_signature private_key::sign_compact( const fc::sha256& digest )const
{
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&digest, sizeof(digest), my->_key);

100
src/crypto/sha224.cpp Normal file
View file

@ -0,0 +1,100 @@
#include <fc/crypto/hex.hpp>
#include <fc/fwd_impl.hpp>
#include <openssl/sha.h>
#include <string.h>
#include <fc/crypto/sha224.hpp>
#include <fc/variant.hpp>
namespace fc {
sha224::sha224() { memset( _hash, 0, sizeof(_hash) ); }
sha224::sha224( const string& hex_str ) {
fc::from_hex( hex_str, (char*)_hash, sizeof(_hash) );
}
string sha224::str()const {
return fc::to_hex( (char*)_hash, sizeof(_hash) );
}
sha224::operator string()const { return str(); }
char* sha224::data()const { return (char*)&_hash[0]; }
struct sha224::encoder::impl {
SHA256_CTX ctx;
};
sha224::encoder::~encoder() {}
sha224::encoder::encoder() {
reset();
}
sha224 sha224::hash( const char* d, uint32_t dlen ) {
encoder e;
e.write(d,dlen);
return e.result();
}
sha224 sha224::hash( const string& s ) {
return hash( s.c_str(), s.size() );
}
void sha224::encoder::write( const char* d, uint32_t dlen ) {
SHA224_Update( &my->ctx, d, dlen);
}
sha224 sha224::encoder::result() {
sha224 h;
SHA224_Final((uint8_t*)h.data(), &my->ctx );
return h;
}
void sha224::encoder::reset() {
SHA224_Init( &my->ctx);
}
sha224 operator << ( const sha224& h1, uint32_t i ) {
sha224 result;
uint8_t* r = (uint8_t*)&result;//result._hash;
uint8_t* s = (uint8_t*)&h1;//h1._hash;
for( uint32_t p = 0; p < sizeof(sha224)-1; ++p )
r[p] = s[p] << i | (s[p+1]>>(8-i));
r[sizeof(sha224)-1] = s[sizeof(sha224)-1] << i;
return result;
}
sha224 operator ^ ( const sha224& h1, const sha224& h2 ) {
sha224 result;
result._hash[0] = h1._hash[0] ^ h2._hash[0];
result._hash[1] = h1._hash[1] ^ h2._hash[1];
result._hash[2] = h1._hash[2] ^ h2._hash[2];
result._hash4 = h1._hash4 ^ h2._hash4;
return result;
}
bool operator >= ( const sha224& h1, const sha224& h2 ) {
return memcmp( h1._hash, h2._hash, sizeof(sha224) ) >= 0;
}
bool operator > ( const sha224& h1, const sha224& h2 ) {
return memcmp( h1._hash, h2._hash, sizeof(sha224) ) > 0;
}
bool operator < ( const sha224& h1, const sha224& h2 ) {
return memcmp( h1._hash, h2._hash, sizeof(sha224) ) < 0;
}
bool operator != ( const sha224& h1, const sha224& h2 ) {
return memcmp( h1._hash, h2._hash, sizeof(sha224) ) != 0;
}
bool operator == ( const sha224& h1, const sha224& h2 ) {
return memcmp( h1._hash, h2._hash, sizeof(sha224) ) == 0;
}
void to_variant( const sha224& bi, variant& v )
{
v = std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
}
void from_variant( const variant& v, sha224& bi )
{
std::vector<char> ve = v.as< std::vector<char> >();
if( ve.size() )
{
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
}
else
memset( &bi, char(0), sizeof(bi) );
}
}

View file

@ -3,7 +3,6 @@
#include <fc/io/buffered_iostream.hpp>
#include <fc/asio.hpp>
#include <fc/filesystem.hpp>
#include <fc/vector.hpp>
#include <fc/log/logger.hpp>
#include <boost/process/all.hpp>
#include <boost/iostreams/stream.hpp>
@ -74,11 +73,12 @@ process::process()
process::~process(){}
iprocess& process::exec( const fc::path& exe,
fc::vector<fc::string> args,
std::vector<std::string> args,
const fc::path& work_dir, exec_opts opt )
{
my->pctx.work_dir = work_dir.string();
my->pctx.suppress_console = (opt & suppress_console) != 0;
if( opt&open_stdout)
my->pctx.streams[boost::process::stdout_id] = bp::behavior::async_pipe();
@ -96,12 +96,14 @@ iprocess& process::exec( const fc::path& exe,
else
my->pctx.streams[boost::process::stdin_id] = bp::behavior::close();
/*
std::vector<std::string> a;
a.reserve(size_t(args.size()));
for( uint32_t i = 0; i < args.size(); ++i ) {
a.push_back( fc::move(args[i]) );
}
my->child.reset( new bp::child( bp::create_child( exe.string(), fc::move(a), my->pctx ) ) );
*/
my->child.reset( new bp::child( bp::create_child( exe.string(), fc::move(args), my->pctx ) ) );
if( opt & open_stdout ) {
bp::handle outh = my->child->get_handle( bp::stdout_id );

View file

@ -196,12 +196,13 @@ namespace fc {
o.write( v.c_str(), v.size() );
return o;
}
#ifdef USE_FC_STRING
ostream& operator<<( ostream& o, const fc::string& v )
{
o.write( v.c_str(), v.size() );
return o;
}
#endif
ostream& operator<<( ostream& o, const double& v )
{
@ -266,10 +267,12 @@ namespace fc {
return o;
}
#ifdef USE_FC_STRING
istream& operator>>( istream& o, fc::string& v )
{
return o;
}
#endif
istream& operator>>( istream& o, char& v )
{

View file

@ -20,7 +20,7 @@ namespace fc {
bool _additivity;
log_level _level;
fc::vector<appender::ptr> _appenders;
std::vector<appender::ptr> _appenders;
};

View file

@ -37,7 +37,7 @@ class fc::http::connection::impl
fc::http::reply parse_reply() {
fc::http::reply rep;
try {
fc::vector<char> line(1024*8);
std::vector<char> line(1024*8);
int s = read_until( line.data(), line.data()+line.size(), ' ' ); // HTTP/1.1
s = read_until( line.data(), line.data()+line.size(), ' ' ); // CODE
rep.status = static_cast<int>(to_int64(fc::string(line.data())));
@ -131,7 +131,7 @@ fc::tcp_socket& connection::get_socket()const {
http::request connection::read_request()const {
http::request req;
fc::vector<char> line(1024*8);
std::vector<char> line(1024*8);
int s = my->read_until( line.data(), line.data()+line.size(), ' ' ); // METHOD
req.method = line.data();
s = my->read_until( line.data(), line.data()+line.size(), ' ' ); // PATH
@ -171,12 +171,12 @@ fc::string request::get_header( const fc::string& key )const {
}
return fc::string();
}
fc::vector<header> parse_urlencoded_params( const fc::string& f ) {
std::vector<header> parse_urlencoded_params( const fc::string& f ) {
int num_args = 0;
for( size_t i = 0; i < f.size(); ++i ) {
if( f[i] == '=' ) ++num_args;
}
fc::vector<header> h(num_args);
std::vector<header> h(num_args);
int arg = 0;
for( size_t i = 0; i < f.size(); ++i ) {
while( f[i] != '=' && i < f.size() ) {

View file

@ -10,6 +10,7 @@
*/
namespace fc {
#ifdef USE_FC_STRING
string::string(const char* s, int l) :my(s,l){ }
string::string(){}
string::string( const fc::string& c ):my(*c.my) { }
@ -64,6 +65,7 @@ namespace fc {
bool operator < ( const string& a, const string& b ) { return *a.my < *b.my; }
string operator + ( const string& s, const string& c ) { return string(s) += c; }
string operator + ( const string& s, char c ) { return string(s) += c; }
#endif // USE_FC_STRING
int64_t to_int64( const fc::string& i )

View file

@ -196,7 +196,7 @@ namespace fc {
my->check_fiber_exceptions();
}
int thread::wait_any_until( fc::vector<promise_base::ptr>&& p, const time_point& timeout) {
int thread::wait_any_until( std::vector<promise_base::ptr>&& p, const time_point& timeout) {
for( size_t i = 0; i < p.size(); ++i ) {
if( p[i]->ready() ) return i;
}
@ -282,10 +282,10 @@ namespace fc {
return thread::current().exec();
}
int wait_any( fc::vector<promise_base::ptr>&& v, const microseconds& timeout_us ) {
int wait_any( std::vector<promise_base::ptr>&& v, const microseconds& timeout_us ) {
return thread::current().wait_any_until( fc::move(v), time_point::now() + timeout_us );
}
int wait_any_until( fc::vector<promise_base::ptr>&& v, const time_point& tp ) {
int wait_any_until( std::vector<promise_base::ptr>&& v, const time_point& tp ) {
return thread::current().wait_any_until( fc::move(v), tp );
}
void thread::wait_until( promise_base::ptr&& p, const time_point& timeout ) {

View file

@ -79,6 +79,14 @@ public:
return (it != handles_.end()) ? it->second : handle();
}
#if defined(BOOST_WINDOWS_API)
handle::native_type get_os_handle() const
{
return handle_.native();
}
#endif
private:
/**
* Handles providing access to streams attached to the child process.

View file

@ -82,6 +82,11 @@ struct context
*/
environment env;
/**
* Suppress creation of a console window on win32 (nop on other platforms)
*/
bool suppress_console;
/**
* Constructs a process context.
*
@ -91,7 +96,8 @@ struct context
*/
context()
: work_dir(self::get_work_dir()),
env(self::get_environment())
env(self::get_environment()),
suppress_console(false)
{
#if 0 // this default behavior will throw in non-console apps
#if defined(BOOST_POSIX_API)

View file

@ -346,7 +346,11 @@ inline child create_child(const std::string &executable, Arguments args,
boost::shared_array<char> envstrs =
detail::environment_to_windows_strings(ctx.env);
if (CreateProcessA(exe.get(), cmdline.get(), NULL, NULL, TRUE, 0,
DWORD creation_flags = 0;
if (ctx.suppress_console)
creation_flags |= CREATE_NO_WINDOW;
if (CreateProcessA(exe.get(), cmdline.get(), NULL, NULL, TRUE, creation_flags,
envstrs.get(), workdir.get(), &startup_info, &pi) == 0)
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("CreateProcess() failed");

View file

@ -198,11 +198,12 @@ private:
BOOST_PROCESS_THROW_LAST_SYSTEM_ERROR("OpenProcess() failed");
return h;
}
protected:
/**
* The process handle.
*/
handle handle_;
private:
#endif
};

50
vendor/cyoencode-1.0.2/README.TXT vendored Normal file
View file

@ -0,0 +1,50 @@
===============================================================================
CyoEncode
http://cyoencode.sourceforge.net/
Copyright (c) 2009-2012, Graham Bull. All rights reserved.
===============================================================================
Version 1.0.2
Release Date 5th January 2012
-------------------------------------------------------------------------------
1. License
-------------------------------------------------------------------------------
CyoEncode is made available under the terms of the Berkeley Software
Distribution (BSD) licence, as detailed in LICENSE.TXT. This allows you
complete freedom to use and distribute the code in source and/or binary form,
as long as you respect the original copyright.
-------------------------------------------------------------------------------
2. Instructions
-------------------------------------------------------------------------------
Simply copy the required source files (CyoEncode.h/cpp and CyoDecode.h/cpp)
into your C/C++ project.
Examples of usage can be found in the test.c file.
For Unix/Linux developers, there's a shell script that will build the test
using GCC.
For Windows developers, Visual Studio projects are included.
-------------------------------------------------------------------------------
3. Release Notes
-------------------------------------------------------------------------------
1.0.2 - 5th January 2012
- A little refactoring, added some shared functions.
- Added VS42010 project file.
- Added x64 build configurations.
1.0.1 - 25th September 2009
- Added the cyoBase??Validate() functions.
- Added detection of invalid encodings in the cyoBase??Decode() functions,
rather than relying on assertions.
1.0.0 - 19th August 2009
- First release.

398
vendor/cyoencode-1.0.2/src/CyoDecode.c vendored Normal file
View file

@ -0,0 +1,398 @@
/*
* CyoDecode.c - part of the CyoEncode library
*
* Copyright (c) 2009-2012, Graham Bull.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 "CyoDecode.h"
#include <assert.h>
#include <stdio.h> //TEMP
/********************************** Shared ***********************************/
static int cyoBaseXXValidate( const char* src, size_t size, size_t inputBytes, size_t maxPadding,
unsigned char maxValue, const unsigned char table[] )
{
/*
* returns 0 if the source is a valid baseXX encoding
*/
if (!src)
return -1; /*ERROR - NULL pointer*/
if (size % inputBytes != 0)
return -1; /*ERROR - extra characters*/
/* check the bytes */
for (; size >= 1; --size, ++src)
{
unsigned char ch = *src;
if ((ch >= 0x80) || (table[ ch ] > maxValue))
break;
}
/* check any padding */
for (; 1 <= size && size <= maxPadding; --size, ++src)
{
unsigned char ch = *src;
if ((ch >= 0x80) || (table[ ch ] != maxValue + 1))
break;
}
/* if size isn't zero then the encoded string isn't valid */
if (size != 0)
return -2; /*ERROR - invalid baseXX character*/
/* OK */
return 0;
}
static size_t cyoBaseXXDecodeGetLength( size_t size, size_t inputBytes, size_t outputBytes )
{
if (size % inputBytes != 0)
return 0; /*ERROR - extra characters*/
/* OK */
return (((size + inputBytes - 1) / inputBytes) * outputBytes) + 1; /*plus terminator*/
}
/****************************** Base16 Decoding ******************************/
static const size_t BASE16_INPUT = 2;
static const size_t BASE16_OUTPUT = 1;
static const size_t BASE16_MAX_PADDING = 0;
static const unsigned char BASE16_MAX_VALUE = 15;
static const unsigned char BASE16_TABLE[ 0x80 ] = {
/*00-07*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*08-0f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*10-17*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*18-1f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*20-27*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*28-2f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*30-37*/ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /*8 = '0'-'7'*/
/*38-3f*/ 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*2 = '8'-'9'*/
/*40-47*/ 0xFF, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xFF, /*6 = 'A'-'F'*/
/*48-4f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*50-57*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*58-5f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*60-67*/ 0xFF, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xFF, /*6 = 'a'-'f' (same as 'A'-'F')*/
/*68-6f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*70-77*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*78-7f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
int cyoBase16Validate( const char* src, size_t size )
{
return cyoBaseXXValidate( src, size, BASE16_INPUT, BASE16_MAX_PADDING, BASE16_MAX_VALUE, BASE16_TABLE );
}
size_t cyoBase16DecodeGetLength( size_t size )
{
return cyoBaseXXDecodeGetLength( size, BASE16_INPUT, BASE16_OUTPUT );
}
size_t cyoBase16Decode( void* dest, const char* src, size_t size )
{
/*
* output 1 byte for every 2 input:
*
* outputs: 1
* inputs: 1 = ----1111 = 1111----
* 2 = ----2222 = ----2222
*/
if (dest && src && (size % BASE16_INPUT == 0))
{
unsigned char* pDest = (unsigned char*)dest;
size_t dwSrcSize = size;
size_t dwDestSize = 0;
unsigned char in1, in2;
while (dwSrcSize >= 1)
{
/* 2 inputs */
in1 = *src++;
in2 = *src++;
dwSrcSize -= BASE16_INPUT;
/* Validate ascii */
if (in1 >= 0x80 || in2 >= 0x80)
return 0; /*ERROR - invalid base16 character*/
/* Convert ascii to base16 */
in1 = BASE16_TABLE[ in1 ];
in2 = BASE16_TABLE[ in2 ];
/* Validate base16 */
if (in1 > BASE16_MAX_VALUE || in2 > BASE16_MAX_VALUE)
return 0; /*ERROR - invalid base16 character*/
/* 1 output */
*pDest++ = ((in1 << 4) | in2);
dwDestSize += BASE16_OUTPUT;
}
*pDest++ = '\x0'; /*append terminator*/
return dwDestSize;
}
else
return 0; /*ERROR - null pointer, or size isn't a multiple of 2*/
}
/****************************** Base32 Decoding ******************************/
static const size_t BASE32_INPUT = 8;
static const size_t BASE32_OUTPUT = 5;
static const size_t BASE32_MAX_PADDING = 6;
static const unsigned char BASE32_MAX_VALUE = 31;
static const unsigned char BASE32_TABLE[ 0x80 ] = {
/*00-07*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*08-0f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*10-17*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*18-1f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*20-27*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*28-2f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*30-37*/ 0xFF, 0xFF, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /*6 = '2'-'7'*/
/*38-3f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0xFF, 0xFF, /*1 = '='*/
/*40-47*/ 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /*7 = 'A'-'G'*/
/*48-4f*/ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, /*8 = 'H'-'O'*/
/*50-57*/ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, /*8 = 'P'-'W'*/
/*58-5f*/ 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*3 = 'X'-'Z'*/
/*60-67*/ 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /*7 = 'a'-'g' (same as 'A'-'G')*/
/*68-6f*/ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, /*8 = 'h'-'o' (same as 'H'-'O')*/
/*70-77*/ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, /*8 = 'p'-'w' (same as 'P'-'W')*/
/*78-7f*/ 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF /*3 = 'x'-'z' (same as 'X'-'Z')*/
};
int cyoBase32Validate( const char* src, size_t size )
{
return cyoBaseXXValidate( src, size, BASE32_INPUT, BASE32_MAX_PADDING, BASE32_MAX_VALUE, BASE32_TABLE );
}
size_t cyoBase32DecodeGetLength( size_t size )
{
return cyoBaseXXDecodeGetLength( size, BASE32_INPUT, BASE32_OUTPUT );
}
size_t cyoBase32Decode( void* dest, const char* src, size_t size )
{
/*
* output 5 bytes for every 8 input:
*
* outputs: 1 2 3 4 5
* inputs: 1 = ---11111 = 11111---
* 2 = ---222XX = -----222 XX------
* 3 = ---33333 = --33333-
* 4 = ---4XXXX = -------4 XXXX----
* 5 = ---5555X = ----5555 X-------
* 6 = ---66666 = -66666--
* 7 = ---77XXX = ------77 XXX-----
* 8 = ---88888 = ---88888
*/
if (dest && src && (size % BASE32_INPUT == 0))
{
unsigned char* pDest = (unsigned char*)dest;
size_t dwSrcSize = size;
size_t dwDestSize = 0;
unsigned char in1, in2, in3, in4, in5, in6, in7, in8;
while (dwSrcSize >= 1)
{
/* 8 inputs */
in1 = *src++;
in2 = *src++;
in3 = *src++;
in4 = *src++;
in5 = *src++;
in6 = *src++;
in7 = *src++;
in8 = *src++;
dwSrcSize -= BASE32_INPUT;
/* Validate ascii */
if ( in1 >= 0x80 || in2 >= 0x80 || in3 >= 0x80 || in4 >= 0x80
|| in5 >= 0x80 || in6 >= 0x80 || in7 >= 0x80 || in8 >= 0x80)
return 0; /*ERROR - invalid base32 character*/
/* Convert ascii to base16 */
in1 = BASE32_TABLE[ in1 ];
in2 = BASE32_TABLE[ in2 ];
in3 = BASE32_TABLE[ in3 ];
in4 = BASE32_TABLE[ in4 ];
in5 = BASE32_TABLE[ in5 ];
in6 = BASE32_TABLE[ in6 ];
in7 = BASE32_TABLE[ in7 ];
in8 = BASE32_TABLE[ in8 ];
/* Validate base32 */
if (in1 > BASE32_MAX_VALUE || in2 > BASE32_MAX_VALUE)
return 0; /*ERROR - invalid base32 character*/
/*the following can be padding*/
if ( in3 > BASE32_MAX_VALUE + 1 || in4 > BASE32_MAX_VALUE + 1 || in5 > BASE32_MAX_VALUE + 1
|| in6 > BASE32_MAX_VALUE + 1 || in7 > BASE32_MAX_VALUE + 1 || in8 > BASE32_MAX_VALUE + 1)
return 0; /*ERROR - invalid base32 character*/
/* 5 outputs */
*pDest++ = ((in1 & 0x1f) << 3) | ((in2 & 0x1c) >> 2);
*pDest++ = ((in2 & 0x03) << 6) | ((in3 & 0x1f) << 1) | ((in4 & 0x10) >> 4);
*pDest++ = ((in4 & 0x0f) << 4) | ((in5 & 0x1e) >> 1);
*pDest++ = ((in5 & 0x01) << 7) | ((in6 & 0x1f) << 2) | ((in7 & 0x18) >> 3);
*pDest++ = ((in7 & 0x07) << 5) | (in8 & 0x1f);
dwDestSize += BASE32_OUTPUT;
/* Padding */
if (in8 == BASE32_MAX_VALUE + 1)
{
--dwDestSize;
assert( (in7 == BASE32_MAX_VALUE + 1 && in6 == BASE32_MAX_VALUE + 1) || (in7 != BASE32_MAX_VALUE + 1) );
if (in6 == BASE32_MAX_VALUE + 1)
{
--dwDestSize;
if (in5 == BASE32_MAX_VALUE + 1)
{
--dwDestSize;
assert( (in4 == BASE32_MAX_VALUE + 1 && in3 == BASE32_MAX_VALUE + 1) || (in4 != BASE32_MAX_VALUE + 1) );
if (in3 == BASE32_MAX_VALUE + 1)
{
--dwDestSize;
}
}
}
}
}
*pDest++ = '\x0'; /*append terminator*/
return dwDestSize;
}
else
return 0; /*ERROR - null pointer, or size isn't a multiple of 8*/
}
/****************************** Base64 Decoding ******************************/
static const size_t BASE64_INPUT = 4;
static const size_t BASE64_OUTPUT = 3;
static const size_t BASE64_MAX_PADDING = 2;
static const unsigned char BASE64_MAX_VALUE = 63;
static const unsigned char BASE64_TABLE[ 0x80 ] = {
/*00-07*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*08-0f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*10-17*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*18-1f*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*20-27*/ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
/*28-2f*/ 0xFF, 0xFF, 0xFF, 0x3e, 0xFF, 0xFF, 0xFF, 0x3f, /*2 = '+' and '/'*/
/*30-37*/ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, /*8 = '0'-'7'*/
/*38-3f*/ 0x3c, 0x3d, 0xFF, 0xFF, 0xFF, 0x40, 0xFF, 0xFF, /*2 = '8'-'9' and '='*/
/*40-47*/ 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /*7 = 'A'-'G'*/
/*48-4f*/ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, /*8 = 'H'-'O'*/
/*50-57*/ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, /*8 = 'P'-'W'*/
/*58-5f*/ 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*3 = 'X'-'Z'*/
/*60-67*/ 0xFF, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, /*7 = 'a'-'g'*/
/*68-6f*/ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, /*8 = 'h'-'o'*/
/*70-77*/ 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, /*8 = 'p'-'w'*/
/*78-7f*/ 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF /*3 = 'x'-'z'*/
};
int cyoBase64Validate( const char* src, size_t size )
{
return cyoBaseXXValidate( src, size, BASE64_INPUT, BASE64_MAX_PADDING, BASE64_MAX_VALUE, BASE64_TABLE );
}
size_t cyoBase64DecodeGetLength( size_t size )
{
return cyoBaseXXDecodeGetLength( size, BASE64_INPUT, BASE64_OUTPUT );
}
size_t cyoBase64Decode( void* dest, const char* src, size_t size )
{
/*
* output 3 bytes for every 4 input:
*
* outputs: 1 2 3
* inputs: 1 = --111111 = 111111--
* 2 = --22XXXX = ------22 XXXX----
* 3 = --3333XX = ----3333 XX------
* 4 = --444444 = --444444
*/
if (dest && src && (size % BASE64_INPUT == 0))
{
unsigned char* pDest = (unsigned char*)dest;
size_t dwSrcSize = size;
size_t dwDestSize = 0;
unsigned char in1, in2, in3, in4;
while (dwSrcSize >= 1)
{
/* 4 inputs */
in1 = *src++;
in2 = *src++;
in3 = *src++;
in4 = *src++;
dwSrcSize -= BASE64_INPUT;
/* Validate ascii */
if (in1 >= 0x80 || in2 >= 0x80 || in3 >= 0x80 || in4 >= 0x80)
return 0; /*ERROR - invalid base64 character*/
/* Convert ascii to base64 */
in1 = BASE64_TABLE[ in1 ];
in2 = BASE64_TABLE[ in2 ];
in3 = BASE64_TABLE[ in3 ];
in4 = BASE64_TABLE[ in4 ];
/* Validate base64 */
if (in1 > BASE64_MAX_VALUE || in2 > BASE64_MAX_VALUE)
return 0; /*ERROR - invalid base64 character*/
/*the following can be padding*/
if (in3 > BASE64_MAX_VALUE + 1 || in4 > BASE64_MAX_VALUE + 1)
return 0; /*ERROR - invalid base64 character*/
/* 3 outputs */
*pDest++ = ((in1 & 0x3f) << 2) | ((in2 & 0x30) >> 4);
*pDest++ = ((in2 & 0x0f) << 4) | ((in3 & 0x3c) >> 2);
*pDest++ = ((in3 & 0x03) << 6) | (in4 & 0x3f);
dwDestSize += BASE64_OUTPUT;
/* Padding */
if (in4 == BASE64_MAX_VALUE + 1)
{
--dwDestSize;
if (in3 == BASE64_MAX_VALUE + 1)
{
--dwDestSize;
}
}
}
*pDest++ = '\x0'; /*append terminator*/
return dwDestSize;
}
else
return 0; /*ERROR - null pointer, or size isn't a multiple of 4*/
}

58
vendor/cyoencode-1.0.2/src/CyoDecode.h vendored Normal file
View file

@ -0,0 +1,58 @@
/*
* CyoDecode.h - part of the CyoEncode library
*
* Copyright (c) 2009-2012, Graham Bull.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
*/
#ifndef __CYODECODE_H
#define __CYODECODE_H
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Base16 Decoding */
int cyoBase16Validate( const char* src, size_t size );
size_t cyoBase16DecodeGetLength( size_t size );
size_t cyoBase16Decode( void* dest, const char* src, size_t size );
/* Base32 Decoding */
int cyoBase32Validate( const char* src, size_t size );
size_t cyoBase32DecodeGetLength( size_t size );
size_t cyoBase32Decode( void* dest, const char* src, size_t size );
/* Base64 Decoding */
int cyoBase64Validate( const char* src, size_t size );
size_t cyoBase64DecodeGetLength( size_t size );
size_t cyoBase64Decode( void* dest, const char* src, size_t size );
#ifdef __cplusplus
}
#endif
#endif /*__CYODECODE_H*/

283
vendor/cyoencode-1.0.2/src/CyoEncode.c vendored Normal file
View file

@ -0,0 +1,283 @@
/*
* CyoEncode.c - part of the CyoEncode library
*
* Copyright (c) 2009-2012, Graham Bull.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 "CyoEncode.h"
#include <assert.h>
/********************************** Shared ***********************************/
static size_t cyoBaseXXEncodeGetLength( size_t size, size_t inputBytes, size_t outputBytes )
{
return (((size + inputBytes - 1) / inputBytes) * outputBytes) + 1; /*plus terminator*/
}
/****************************** Base16 Encoding ******************************/
static const size_t BASE16_INPUT = 1;
static const size_t BASE16_OUTPUT = 2;
static const char* const BASE16_TABLE = "0123456789ABCDEF";
size_t cyoBase16EncodeGetLength( size_t size )
{
return cyoBaseXXEncodeGetLength( size, BASE16_INPUT, BASE16_OUTPUT );
}
size_t cyoBase16Encode( char* dest, const void* src, size_t size )
{
/*
* output 2 bytes for every 1 input:
*
* inputs: 1
* outputs: 1 = ----1111 = 1111----
* 2 = ----2222 = ----2222
*/
if (dest && src)
{
unsigned char* pSrc = (unsigned char*)src;
size_t dwSrcSize = size;
size_t dwDestSize = 0;
unsigned char ch;
while (dwSrcSize >= 1)
{
/* 1 input */
ch = *pSrc++;
dwSrcSize -= BASE16_INPUT;
/* 2 outputs */
*dest++ = BASE16_TABLE[ (ch & 0xf0) >> 4 ];
*dest++ = BASE16_TABLE[ (ch & 0x0f) ];
dwDestSize += BASE16_OUTPUT;
}
*dest++ = '\x0'; /*append terminator*/
return dwDestSize;
}
else
return 0; /*ERROR - null pointer*/
}
/****************************** Base32 Encoding ******************************/
static const size_t BASE32_INPUT = 5;
static const size_t BASE32_OUTPUT = 8;
static const char* const BASE32_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=";
size_t cyoBase32EncodeGetLength( size_t size )
{
return cyoBaseXXEncodeGetLength( size, BASE32_INPUT, BASE32_OUTPUT );
}
size_t cyoBase32Encode( char* dest, const void* src, size_t size )
{
/*
* output 8 bytes for every 5 input:
*
* inputs: 1 2 3 4 5
* outputs: 1 = ---11111 = 11111---
* 2 = ---222XX = -----222 XX------
* 3 = ---33333 = --33333-
* 4 = ---4XXXX = -------4 XXXX----
* 5 = ---5555X = ----5555 X-------
* 6 = ---66666 = -66666--
* 7 = ---77XXX = ------77 XXX-----
* 8 = ---88888 = ---88888
*/
if (dest && src)
{
unsigned char* pSrc = (unsigned char*)src;
size_t dwSrcSize = size;
size_t dwDestSize = 0;
size_t dwBlockSize;
unsigned char n1, n2, n3, n4, n5, n6, n7, n8;
while (dwSrcSize >= 1)
{
/* Encode inputs */
dwBlockSize = (dwSrcSize < BASE32_INPUT ? dwSrcSize : BASE32_INPUT);
n1 = n2 = n3 = n4 = n5 = n6 = n7 = n8 = 0;
switch (dwBlockSize)
{
case 5:
n8 = (pSrc[ 4 ] & 0x1f);
n7 = ((pSrc[ 4 ] & 0xe0) >> 5);
case 4:
n7 |= ((pSrc[ 3 ] & 0x03) << 3);
n6 = ((pSrc[ 3 ] & 0x7c) >> 2);
n5 = ((pSrc[ 3 ] & 0x80) >> 7);
case 3:
n5 |= ((pSrc[ 2 ] & 0x0f) << 1);
n4 = ((pSrc[ 2 ] & 0xf0) >> 4);
case 2:
n4 |= ((pSrc[ 1 ] & 0x01) << 4);
n3 = ((pSrc[ 1 ] & 0x3e) >> 1);
n2 = ((pSrc[ 1 ] & 0xc0) >> 6);
case 1:
n2 |= ((pSrc[ 0 ] & 0x07) << 2);
n1 = ((pSrc[ 0 ] & 0xf8) >> 3);
break;
default:
assert( 0 );
}
pSrc += dwBlockSize;
dwSrcSize -= dwBlockSize;
/* Validate */
assert( n1 <= 31 );
assert( n2 <= 31 );
assert( n3 <= 31 );
assert( n4 <= 31 );
assert( n5 <= 31 );
assert( n6 <= 31 );
assert( n7 <= 31 );
assert( n8 <= 31 );
/* Padding */
switch (dwBlockSize)
{
case 1: n3 = n4 = 32;
case 2: n5 = 32;
case 3: n6 = n7 = 32;
case 4: n8 = 32;
case 5:
break;
default:
assert( 0 );
}
/* 8 outputs */
*dest++ = BASE32_TABLE[ n1 ];
*dest++ = BASE32_TABLE[ n2 ];
*dest++ = BASE32_TABLE[ n3 ];
*dest++ = BASE32_TABLE[ n4 ];
*dest++ = BASE32_TABLE[ n5 ];
*dest++ = BASE32_TABLE[ n6 ];
*dest++ = BASE32_TABLE[ n7 ];
*dest++ = BASE32_TABLE[ n8 ];
dwDestSize += BASE32_OUTPUT;
}
*dest++ = '\x0'; /*append terminator*/
return dwDestSize;
}
else
return 0; /*ERROR - null pointer*/
}
/****************************** Base64 Encoding ******************************/
static const size_t BASE64_INPUT = 3;
static const size_t BASE64_OUTPUT = 4;
static const char* const BASE64_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
size_t cyoBase64EncodeGetLength( size_t size )
{
return cyoBaseXXEncodeGetLength( size, BASE64_INPUT, BASE64_OUTPUT );
}
size_t cyoBase64Encode( char* dest, const void* src, size_t size )
{
/*
* output 4 bytes for every 3 input:
*
* inputs: 1 2 3
* outputs: 1 = --111111 = 111111--
* 2 = --22XXXX = ------22 XXXX----
* 3 = --3333XX = ----3333 XX------
* 4 = --444444 = --444444
*/
if (dest && src)
{
unsigned char* pSrc = (unsigned char*)src;
size_t dwSrcSize = size;
size_t dwDestSize = 0;
size_t dwBlockSize = 0;
unsigned char n1, n2, n3, n4;
while (dwSrcSize >= 1)
{
/* Encode inputs */
dwBlockSize = (dwSrcSize < BASE64_INPUT ? dwSrcSize : BASE64_INPUT);
n1 = n2 = n3 = n4 = 0;
switch (dwBlockSize)
{
case 3:
n4 = (pSrc[ 2 ] & 0x3f);
n3 = ((pSrc[ 2 ] & 0xc0) >> 6);
case 2:
n3 |= ((pSrc[ 1 ] & 0x0f) << 2);
n2 = ((pSrc[ 1 ] & 0xf0) >> 4);
case 1:
n2 |= ((pSrc[ 0 ] & 0x03) << 4);
n1 = ((pSrc[ 0 ] & 0xfc) >> 2);
break;
default:
assert( 0 );
}
pSrc += dwBlockSize;
dwSrcSize -= dwBlockSize;
/* Validate */
assert( n1 <= 63 );
assert( n2 <= 63 );
assert( n3 <= 63 );
assert( n4 <= 63 );
/* Padding */
switch (dwBlockSize)
{
case 1: n3 = 64;
case 2: n4 = 64;
case 3:
break;
default:
assert( 0 );
}
/* 4 outputs */
*dest++ = BASE64_TABLE[ n1 ];
*dest++ = BASE64_TABLE[ n2 ];
*dest++ = BASE64_TABLE[ n3 ];
*dest++ = BASE64_TABLE[ n4 ];
dwDestSize += BASE64_OUTPUT;
}
*dest++ = '\x0'; /*append terminator*/
return dwDestSize;
}
else
return 0; /*ERROR - null pointer*/
}

55
vendor/cyoencode-1.0.2/src/CyoEncode.h vendored Normal file
View file

@ -0,0 +1,55 @@
/*
* CyoEncode.h - part of the CyoEncode library
*
* Copyright (c) 2009-2012, Graham Bull.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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.
*/
#ifndef __CYOENCODE_H
#define __CYOENCODE_H
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Base16 Encoding */
size_t cyoBase16EncodeGetLength( size_t size );
size_t cyoBase16Encode( char* dest, const void* src, size_t size );
/* Base32 Encoding */
size_t cyoBase32EncodeGetLength( size_t size );
size_t cyoBase32Encode( char* dest, const void* src, size_t size );
/* Base64 Encoding */
size_t cyoBase64EncodeGetLength( size_t size );
size_t cyoBase64Encode( char* dest, const void* src, size_t size );
#ifdef __cplusplus
}
#endif
#endif /*__CYOENCODE_H*/

191
vendor/cyoencode-1.0.2/src/test.c vendored Normal file
View file

@ -0,0 +1,191 @@
/*
* test.c - part of the CyoEncode library
*
* Copyright (c) 2009-2012, Graham Bull.
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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 "CyoEncode.h"
#include "CyoDecode.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define TEST_BASExx(base,str,expected) \
printf( "TEST_BASE%s('%s')='%s'", #base, str, expected ); \
required = cyoBase##base##EncodeGetLength( strlen( str )); \
encoded = (char*)malloc( required ); \
if (encoded == NULL) { \
printf( "\n*** ERROR: Unable to allocate buffer for encoding ***\n" ); \
goto exit; \
} \
cyoBase##base##Encode( encoded, str, strlen( str )); \
if (strcmp( encoded, expected ) != 0) { \
printf( "\n*** ERROR: Encoding failure ***\n" ); \
goto exit; \
} \
valid = cyoBase##base##Validate( encoded, strlen( encoded )); \
if (valid < 0) \
{ \
printf( "\n*** ERROR: Unable to validate encoding (error %d) ***\n", valid ); \
goto exit; \
} \
printf( " [passed]\n" ); \
free( encoded ); encoded = NULL;
#define TEST_BASE64(str,expected) TEST_BASExx(64,str,expected)
#define TEST_BASE32(str,expected) TEST_BASExx(32,str,expected)
#define TEST_BASE16(str,expected) TEST_BASExx(16,str,expected)
#define CHECK_INVALID_BASExx(base,str,res) \
printf( "CHECK_INVALID_BASE%s('%s')=%d", #base, str, res ); \
valid = cyoBase##base##Validate( str, strlen( str )); \
if (valid == 0) \
{ \
printf( "\n*** ERROR: This is a valid encoding! ***\n" ); \
goto exit; \
} \
if (valid != res) \
{ \
printf( "\n*** ERROR: Expected a different return code! (%d) ***\n", valid ); \
goto exit; \
} \
printf( " [passed]\n", #base, str ); \
#define CHECK_INVALID_BASE16(enc,res) CHECK_INVALID_BASExx(16,enc,res)
#define CHECK_INVALID_BASE32(enc,res) CHECK_INVALID_BASExx(32,enc,res)
#define CHECK_INVALID_BASE64(enc,res) CHECK_INVALID_BASExx(64,enc,res)
int main( void )
{
const char* const original = "A wise man speaks when he has something to say";
size_t required = 0;
char* encoded = NULL;
char* decoded = NULL;
int valid = 0;
int retcode = 1;
printf( "Running CyoEncode tests...\n" );
/* Encode using Base64 */
printf( "Original = '%s'\n", original );
required = cyoBase64EncodeGetLength( strlen( original ));
encoded = (char*)malloc( required );
if (encoded == NULL)
{
printf( "*** ERROR: Unable to allocate buffer for encoding ***\n" );
goto exit;
}
cyoBase64Encode( encoded, original, strlen( original ));
printf( "Encoded = '%s'\n", encoded );
/* Validate encoding */
valid = cyoBase64Validate( encoded, strlen( encoded ));
if (valid < 0)
{
printf( "*** ERROR: Encoding failure (error %d) ***\n", valid );
goto exit;
}
/* Decode using Base64 */
required = cyoBase64DecodeGetLength( strlen( encoded ));
decoded = (char*)malloc( required );
if (decoded == NULL)
{
printf( "*** ERROR: Unable to allocate buffer for decoding ***\n" );
goto exit;
}
cyoBase64Decode( decoded, encoded, strlen( encoded ));
printf( "Decoded = '%s'\n", decoded );
/* Validate */
if (strcmp( original, decoded ) != 0)
{
printf( "*** ERROR: Encoding/decoding failure ***\n" );
goto exit;
}
free( encoded );
encoded = NULL;
free( decoded );
decoded = NULL;
/* Test vectors from RFC 4648 */
TEST_BASE16( "", "" );
TEST_BASE16( "f", "66" );
TEST_BASE16( "fo", "666F" );
TEST_BASE16( "foo", "666F6F" );
TEST_BASE16( "foob", "666F6F62" );
TEST_BASE16( "fooba", "666F6F6261" );
TEST_BASE16( "foobar", "666F6F626172" );
TEST_BASE32( "", "" );
TEST_BASE32( "f", "MY======" );
TEST_BASE32( "fo", "MZXQ====" );
TEST_BASE32( "foo", "MZXW6===" );
TEST_BASE32( "foob", "MZXW6YQ=" );
TEST_BASE32( "fooba", "MZXW6YTB" );
TEST_BASE32( "foobar", "MZXW6YTBOI======" );
TEST_BASE64( "", "" );
TEST_BASE64( "f", "Zg==" );
TEST_BASE64( "fo", "Zm8=" );
TEST_BASE64( "foo", "Zm9v" );
TEST_BASE64( "foob", "Zm9vYg==" );
TEST_BASE64( "fooba", "Zm9vYmE=" );
TEST_BASE64( "foobar", "Zm9vYmFy" );
/* Other tests */
CHECK_INVALID_BASE16( "1", -1 );
CHECK_INVALID_BASE16( "123", -1 );
CHECK_INVALID_BASE16( "1G", -2 );
CHECK_INVALID_BASE32( "A", -1 );
CHECK_INVALID_BASE32( "ABCDEFG", -1 );
CHECK_INVALID_BASE32( "ABCDEFG1", -2 );
CHECK_INVALID_BASE32( "A=======", -2 );
CHECK_INVALID_BASE64( "A", -1 );
CHECK_INVALID_BASE64( "ABCDE", -1 );
CHECK_INVALID_BASE64( "A&B=", -2 );
CHECK_INVALID_BASE64( "A===", -2 );
printf( "*** All tests passed ***\n" );
retcode = 0;
exit:
if (encoded != NULL)
free( encoded );
if (decoded != NULL)
free( decoded );
return retcode;
}