Merge pull request #1 from bytemaster/phoenix
Various updates / cleanup of fc code.
This commit is contained in:
commit
92e22c3e30
44 changed files with 1525 additions and 520 deletions
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)) );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
86
include/fc/crypto/sha224.hpp
Normal file
86
include/fc/crypto/sha224.hpp
Normal 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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())> {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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&& );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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()));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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() );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
100
src/crypto/sha224.cpp
Normal 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) );
|
||||
}
|
||||
}
|
||||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace fc {
|
|||
bool _additivity;
|
||||
log_level _level;
|
||||
|
||||
fc::vector<appender::ptr> _appenders;
|
||||
std::vector<appender::ptr> _appenders;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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() ) {
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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
50
vendor/cyoencode-1.0.2/README.TXT
vendored
Normal 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
398
vendor/cyoencode-1.0.2/src/CyoDecode.c
vendored
Normal 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
58
vendor/cyoencode-1.0.2/src/CyoDecode.h
vendored
Normal 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
283
vendor/cyoencode-1.0.2/src/CyoEncode.c
vendored
Normal 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
55
vendor/cyoencode-1.0.2/src/CyoEncode.h
vendored
Normal 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
191
vendor/cyoencode-1.0.2/src/test.c
vendored
Normal 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;
|
||||
}
|
||||
Loading…
Reference in a new issue