Updating FC with changes from phoenix-int
This commit is contained in:
parent
9909ef83b5
commit
59a121d64b
370 changed files with 13676 additions and 66345 deletions
228
CMakeLists.txt
228
CMakeLists.txt
|
|
@ -3,31 +3,47 @@ PROJECT( fc )
|
|||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8.0 )
|
||||
|
||||
SET( CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}" )
|
||||
SET( CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}" )
|
||||
|
||||
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 )
|
||||
|
||||
SET( DEFAULT_HEADER_INSTALL_DIR include/\${target} )
|
||||
SET( DEFAULT_LIBRARY_INSTALL_DIR lib/ )
|
||||
SET( DEFAULT_EXECUTABLE_INSTALL_DIR bin/ )
|
||||
SET( CMAKE_DEBUG_POSTFIX _debug )
|
||||
#SET( BUILD_SHARED_LIBS NO )
|
||||
|
||||
SET( BUILD_SHARED_LIBS NO )
|
||||
SET(Boost_USE_STATIC_LIBS ON)
|
||||
FIND_PACKAGE(Boost 1.51 COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework context )
|
||||
|
||||
if( WIN32 )
|
||||
set( RPCRT4 Rpcrt4 )
|
||||
set( OPENSSL_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/openssl" )
|
||||
if ( NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vendor/openssl/lib" )
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/vendor/openssl/out32dll" DESTINATION "${CMAKE_CURRENT_SOURCE_DIR}/vendor/openssl/cmakefun")
|
||||
file(RENAME "${CMAKE_CURRENT_SOURCE_DIR}/vendor/openssl/cmakefun/out32dll" "${CMAKE_CURRENT_SOURCE_DIR}/vendor/openssl/lib")
|
||||
endif( NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vendor/openssl/lib" )
|
||||
endif( WIN32 )
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR} )
|
||||
LINK_DIRECTORIES( ${Boost_LIBRARY_DIRS} )
|
||||
|
||||
IF( WIN32 )
|
||||
ADD_DEFINITIONS( -DWIN32 )
|
||||
ADD_DEFINITIONS( -DBOOST_CONTEXT_NO_LIB )
|
||||
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
|
||||
ADD_DEFINITIONS( -D_WIN32_WINNT=0x0501 )
|
||||
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
|
||||
ADD_DEFINITIONS( -DBOOST_ALL_NO_LIB -DBOOST_THREAD_BUILD_LIB)
|
||||
ADD_DEFINITIONS( -DWIN32)
|
||||
# Activate C++ exception handling
|
||||
IF (NOT CMAKE_CXX_FLAGS MATCHES "/EHsc")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
|
||||
ENDIF()
|
||||
ELSE(WIN32)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall -Wno-unused-local-typedefs -fmax-errors=3" )
|
||||
ENDIF(WIN32)
|
||||
|
||||
if( UNIX )
|
||||
|
|
@ -40,82 +56,144 @@ endif()
|
|||
option( UNITY_BUILD OFF )
|
||||
|
||||
FIND_PACKAGE( OpenSSL )
|
||||
FIND_PACKAGE( ZLIB )
|
||||
|
||||
include_directories( vendor/zlib-1.2.7/)
|
||||
include_directories( vendor/libssh2-1.4.2/include )
|
||||
include_directories( vendor/boost_1.51/include )
|
||||
include_directories( ${Boost_INCLUDE_DIR} )
|
||||
include_directories( ${OPENSSL_INCLUDE_DIR} )
|
||||
include_directories( include )
|
||||
|
||||
SET( ALL_OPENSSL_LIBRARIES
|
||||
${OPENSSL_LIBRARIES}
|
||||
${SSL_EAY_RELEASE}
|
||||
${LIB_EAY_RELEASE}
|
||||
)
|
||||
|
||||
set( fc_sources
|
||||
src/variant.cpp
|
||||
src/exception.cpp
|
||||
src/variant_object.cpp
|
||||
src/thread/thread.cpp
|
||||
src/thread/future.cpp
|
||||
src/thread/task.cpp
|
||||
src/thread/spin_lock.cpp
|
||||
src/thread/spin_yield_lock.cpp
|
||||
src/thread/mutex.cpp
|
||||
src/asio.cpp
|
||||
src/string.cpp
|
||||
src/shared_ptr.cpp
|
||||
src/time.cpp
|
||||
src/io/iostream.cpp
|
||||
src/io/datastream.cpp
|
||||
src/io/buffered_iostream.cpp
|
||||
src/io/fstream.cpp
|
||||
src/io/sstream.cpp
|
||||
src/io/json.cpp
|
||||
src/io/varint.cpp
|
||||
src/filesystem.cpp
|
||||
src/interprocess/process.cpp
|
||||
src/interprocess/file_mapping.cpp
|
||||
src/rpc/json_connection.cpp
|
||||
src/log/log_message.cpp
|
||||
src/log/logger.cpp
|
||||
src/log/appender.cpp
|
||||
src/log/console_appender.cpp
|
||||
src/log/file_appender.cpp
|
||||
src/log/logger_config.cpp
|
||||
src/crypto/base36.cpp
|
||||
src/crypto/bigint.cpp
|
||||
src/crypto/base64.cpp
|
||||
src/crypto/base58.cpp
|
||||
src/crypto/hex.cpp
|
||||
src/crypto/sha1.cpp
|
||||
src/crypto/sha256.cpp
|
||||
src/crypto/dh.cpp
|
||||
src/crypto/blowfish.cpp
|
||||
src/network/tcp_socket.cpp
|
||||
src/network/udp_socket.cpp
|
||||
src/network/http/http_connection.cpp
|
||||
src/network/http/http_server.cpp
|
||||
src/network/ip.cpp
|
||||
src/network/resolve.cpp
|
||||
src/network/url.cpp
|
||||
# src/ssh/client.cpp
|
||||
# src/ssh/process.cpp
|
||||
)
|
||||
|
||||
IF( UNIX )
|
||||
IF( ENABLE_ARM )
|
||||
SET_PROPERTY( SOURCE
|
||||
vendor/boost_1.51/libs/context/asm/fcontext_arm_aapcs_elf_gas.S
|
||||
PROPERTY LANGUAGE C)
|
||||
SET( boost_context_sources vendor/boost_1.51/libs/context/protected_stack_posix.cpp
|
||||
vendor/boost_1.51/libs/context/stack_helper_posix.cpp
|
||||
vendor/boost_1.51/libs/context/asm/fcontext_arm_aapcs_elf_gas.S
|
||||
)
|
||||
ELSE()
|
||||
|
||||
IF( APPLE )
|
||||
SET_PROPERTY( SOURCE
|
||||
vendor/boost_1.51/libs/context/asm/fcontext_x86_64_sysv_macho_gas.S
|
||||
PROPERTY LANGUAGE C)
|
||||
SET( boost_context_sources vendor/boost_1.51/libs/context/stack_utils_posix.cpp
|
||||
vendor/boost_1.51/libs/context/stack_allocator_posix.cpp
|
||||
vendor/boost_1.51/libs/context/fcontext.cpp
|
||||
vendor/boost_1.51/libs/context/asm/fcontext_x86_64_sysv_macho_gas.S
|
||||
)
|
||||
ELSE (APPLE)
|
||||
IF( CMAKE_SIZEOF_VOID_P EQUAL 4 )
|
||||
SET_PROPERTY( SOURCE
|
||||
vendor/boost_1.51/libs/context/asm/fcontext_i386_sysv_elf_gas.S
|
||||
PROPERTY LANGUAGE C)
|
||||
SET( fcontext_asm vendor/boost_1.51/libs/context/asm/fcontext_i386_sysv_elf_gas.S )
|
||||
ELSE( )
|
||||
SET( fcontext_asm vendor/boost_1.51/libs/context/asm/fcontext_x86_64_sysv_elf_gas.S )
|
||||
SET_PROPERTY( SOURCE
|
||||
vendor/boost_1.51/libs/context/asm/fcontext_x86_64_sysv_elf_gas.S
|
||||
PROPERTY LANGUAGE C)
|
||||
ENDIF( )
|
||||
|
||||
SET( boost_context_sources vendor/boost_1.51/libs/context/stack_utils_posix.cpp
|
||||
vendor/boost_1.51/libs/context/stack_allocator_posix.cpp
|
||||
vendor/boost_1.51/libs/context/fcontext.cpp
|
||||
${fcontext_asm}
|
||||
)
|
||||
ENDIF(APPLE)
|
||||
|
||||
ENDIF()
|
||||
ENDIF( UNIX )
|
||||
|
||||
IF( WIN32 )
|
||||
ENABLE_LANGUAGE(ASM_MASM)
|
||||
# SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHa" )
|
||||
|
||||
SET( boost_context_sources vendor/boost_1.51/libs/context/fcontext.cpp
|
||||
vendor/boost_1.51/libs/context/seh.cpp
|
||||
vendor/boost_1.51/libs/context/stack_allocator_windows.cpp
|
||||
vendor/boost_1.51/libs/context/stack_utils_windows.cpp
|
||||
vendor/boost_1.51/libs/context/seh.cpp
|
||||
)
|
||||
IF( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
SET( boost_context_sources ${boost_context_sources}
|
||||
vendor/boost_1.51/libs/context/asm/fcontext_x86_64_ms_pe_masm.asm )
|
||||
ELSE() # 32bit
|
||||
SET( boost_context_sources ${boost_context_sources}
|
||||
vendor/boost_1.51/libs/context/asm/fcontext_i386_ms_pe_masm.asm )
|
||||
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO" )
|
||||
message(STATUS "")
|
||||
message(STATUS "Note for Visual Studio 2012 projects:")
|
||||
message(STATUS " Each time CMake regenerates your projects, you will need to:")
|
||||
message(STATUS " Right-click on the 'fc' project and select 'Build Customizations', and")
|
||||
message(STATUS " check the 'masm' customization.")
|
||||
message(STATUS " then, go to the 'Properties' for the fcontext*.asm file, and change its ")
|
||||
message(STATUS " item type from 'Does not participate in build' to 'Microsoft Macro Assembler'")
|
||||
ENDIF()
|
||||
|
||||
ENDIF(WIN32)
|
||||
|
||||
set( sources
|
||||
src/logger.cpp
|
||||
src/console_appender.cpp
|
||||
src/file_appender.cpp
|
||||
src/appender.cpp
|
||||
src/logger_config.cpp
|
||||
src/ssh.cpp
|
||||
src/url.cpp
|
||||
src/process.cpp
|
||||
src/http_connection.cpp
|
||||
src/http_server.cpp
|
||||
src/json_rpc_connection.cpp
|
||||
src/json_rpc_stream_connection.cpp
|
||||
src/json_rpc_tcp_connection.cpp
|
||||
src/json_rpc_tcp_server.cpp
|
||||
src/json_rpc_error_object.cpp
|
||||
src/error_report.cpp
|
||||
src/value.cpp
|
||||
src/lexical_cast.cpp
|
||||
src/spin_lock.cpp
|
||||
src/spin_yield_lock.cpp
|
||||
src/task.cpp
|
||||
src/future.cpp
|
||||
src/shared_ptr.cpp
|
||||
src/string.cpp
|
||||
src/json.cpp
|
||||
src/log.cpp
|
||||
src/time.cpp
|
||||
src/iostream.cpp
|
||||
src/fstream.cpp
|
||||
src/sstream.cpp
|
||||
src/exception.cpp
|
||||
src/thread.cpp
|
||||
src/hex.cpp
|
||||
src/sha1.cpp
|
||||
src/sha256.cpp
|
||||
src/filesystem.cpp
|
||||
src/ip.cpp
|
||||
src/bigint.cpp
|
||||
src/mutex.cpp
|
||||
src/pke.cpp
|
||||
src/base64.cpp
|
||||
src/base58.cpp
|
||||
src/blowfish.cpp
|
||||
src/dh.cpp
|
||||
src/udp_socket.cpp
|
||||
src/tcp_socket.cpp
|
||||
src/asio.cpp
|
||||
src/super_fast_hash.cpp
|
||||
src/file_mapping.cpp
|
||||
src/reflect.cpp
|
||||
# src/program_options.cpp
|
||||
${fc_sources}
|
||||
${boost_context_sources}
|
||||
)
|
||||
|
||||
add_subdirectory(vendor)
|
||||
setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC )
|
||||
|
||||
#add_executable( date t.cpp )
|
||||
#target_link_libraries( date fc ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${rt_library} ${Boost_DATE_TIME_LIBRARY})
|
||||
|
||||
setup_library( fc SOURCES ${sources} )
|
||||
|
||||
#setup_executable( json_rpc_test SOURCES tests/json_rpc_test.cpp LIBRARIES fc ${ZLIB_LIBRARY} ${pthread_library} ${rt_library} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${rt_library} ${Boost_DATE_TIME_LIBRARY})
|
||||
setup_executable( ssh_test SOURCES tests/ssh.cpp LIBRARIES fc ${pthread_library} ${rt_library} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${rt_library} ssh2 ${OPENSSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} ${ZLIB_LIBRARY} ${ALL_OPENSSL_LIBRARIES} ${Boost_DATE_TIME_LIBRARY})
|
||||
|
||||
setup_executable( logger_test SOURCES tests/logger.cpp LIBRARIES fc ${pthread_library} ${rt_library} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${rt_library} ssh2 ${OPENSSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} ${ZLIB_LIBRARY} ${ALL_OPENSSL_LIBRARIES} ${Boost_DATE_TIME_LIBRARY})
|
||||
|
||||
#add_executable( test_vec tests/vector_test.cpp )
|
||||
#target_link_libraries( test_vec fc ${Boost_SYSTEM_LIBRARY} ${Boost_CHRONO_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY} )
|
||||
|
||||
#add_executable( unit_tests tests/unit.cpp )
|
||||
#target_link_libraries( unit_tests fc ${Boost_CHRONO_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} )
|
||||
|
|
|
|||
123
CMakeModules/FindVLD.cmake
Normal file
123
CMakeModules/FindVLD.cmake
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
# Module for locating Visual Leak Detector.
|
||||
#
|
||||
# Customizable variables:
|
||||
# VLD_ROOT_DIR
|
||||
# This variable points to the Visual Leak Detector root directory. By
|
||||
# default, the module looks for the installation directory by examining the
|
||||
# Program Files/Program Files (x86) folders and the VLDROOT environment
|
||||
# variable.
|
||||
#
|
||||
# Read-only variables:
|
||||
# VLD_FOUND
|
||||
# Indicates that the library has been found.
|
||||
#
|
||||
# VLD_INCLUDE_DIRS
|
||||
# Points to the Visual Leak Detector include directory.
|
||||
#
|
||||
# VLD_LIBRARY_DIRS
|
||||
# Points to the Visual Leak Detector directory that contains the libraries.
|
||||
# The content of this variable can be passed to link_directories.
|
||||
#
|
||||
# VLD_LIBRARIES
|
||||
# Points to the Visual Leak Detector libraries that can be passed to
|
||||
# target_link_libararies.
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2012 Sergiu Dotenco
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
INCLUDE (FindPackageHandleStandardArgs)
|
||||
|
||||
SET (_VLD_POSSIBLE_LIB_SUFFIXES lib)
|
||||
|
||||
# Version 2.0 uses vld_x86 and vld_x64 instead of simply vld as library names
|
||||
IF (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
LIST (APPEND _VLD_POSSIBLE_LIB_SUFFIXES lib/Win32)
|
||||
ELSEIF (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
LIST (APPEND _VLD_POSSIBLE_LIB_SUFFIXES lib/Win64)
|
||||
ENDIF (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
|
||||
FIND_PATH (VLD_ROOT_DIR
|
||||
NAMES include/vld.h
|
||||
PATHS ENV VLDROOT
|
||||
"$ENV{PROGRAMFILES}/Visual Leak Detector"
|
||||
"$ENV{PROGRAMFILES(X86)}/Visual Leak Detector"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Visual Leak Detector;InstallLocation]"
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Visual Leak Detector;InstallLocation]"
|
||||
DOC "VLD root directory")
|
||||
|
||||
FIND_PATH (VLD_INCLUDE_DIR
|
||||
NAMES vld.h
|
||||
HINTS ${VLD_ROOT_DIR}
|
||||
PATH_SUFFIXES include
|
||||
DOC "VLD include directory")
|
||||
|
||||
FIND_LIBRARY (VLD_LIBRARY_DEBUG
|
||||
NAMES vld
|
||||
HINTS ${VLD_ROOT_DIR}
|
||||
PATH_SUFFIXES ${_VLD_POSSIBLE_LIB_SUFFIXES}
|
||||
DOC "VLD debug library")
|
||||
|
||||
IF (VLD_ROOT_DIR)
|
||||
SET (_VLD_VERSION_FILE ${VLD_ROOT_DIR}/CHANGES.txt)
|
||||
|
||||
IF (EXISTS ${_VLD_VERSION_FILE})
|
||||
SET (_VLD_VERSION_REGEX
|
||||
"Visual Leak Detector \\(VLD\\) Version (([0-9]+)\\.([0-9]+)([a-z]|(.([0-9]+)))?)")
|
||||
FILE (STRINGS ${_VLD_VERSION_FILE} _VLD_VERSION_TMP REGEX
|
||||
${_VLD_VERSION_REGEX})
|
||||
|
||||
STRING (REGEX REPLACE ${_VLD_VERSION_REGEX} "\\1" _VLD_VERSION_TMP
|
||||
"${_VLD_VERSION_TMP}")
|
||||
|
||||
STRING (REGEX REPLACE "([0-9]+).([0-9]+).*" "\\1" VLD_VERSION_MAJOR
|
||||
"${_VLD_VERSION_TMP}")
|
||||
STRING (REGEX REPLACE "([0-9]+).([0-9]+).*" "\\2" VLD_VERSION_MINOR
|
||||
"${_VLD_VERSION_TMP}")
|
||||
|
||||
SET (VLD_VERSION ${VLD_VERSION_MAJOR}.${VLD_VERSION_MINOR})
|
||||
|
||||
IF ("${_VLD_VERSION_TMP}" MATCHES "^([0-9]+).([0-9]+).([0-9]+)$")
|
||||
# major.minor.patch version numbering scheme
|
||||
STRING (REGEX REPLACE "([0-9]+).([0-9]+).([0-9]+)" "\\3"
|
||||
VLD_VERSION_PATCH "${_VLD_VERSION_TMP}")
|
||||
SET (VLD_VERSION "${VLD_VERSION}.${VLD_VERSION_PATCH}")
|
||||
SET (VLD_VERSION_COUNT 3)
|
||||
ELSE ("${_VLD_VERSION_TMP}" MATCHES "^([0-9]+).([0-9]+).([0-9]+)$")
|
||||
# major.minor version numbering scheme. The trailing letter is ignored.
|
||||
SET (VLD_VERSION_COUNT 2)
|
||||
ENDIF ("${_VLD_VERSION_TMP}" MATCHES "^([0-9]+).([0-9]+).([0-9]+)$")
|
||||
ENDIF (EXISTS ${_VLD_VERSION_FILE})
|
||||
ENDIF (VLD_ROOT_DIR)
|
||||
|
||||
IF (VLD_LIBRARY_DEBUG)
|
||||
SET (VLD_LIBRARY debug ${VLD_LIBRARY_DEBUG} CACHE DOC "VLD library")
|
||||
GET_FILENAME_COMPONENT (_VLD_LIBRARY_DIR ${VLD_LIBRARY_DEBUG} PATH)
|
||||
SET (VLD_LIBRARY_DIR ${_VLD_LIBRARY_DIR} CACHE PATH "VLD library directory")
|
||||
ENDIF (VLD_LIBRARY_DEBUG)
|
||||
|
||||
SET (VLD_INCLUDE_DIRS ${VLD_INCLUDE_DIR})
|
||||
SET (VLD_LIBRARY_DIRS ${VLD_LIBRARY_DIR})
|
||||
SET (VLD_LIBRARIES ${VLD_LIBRARY})
|
||||
|
||||
MARK_AS_ADVANCED (VLD_INCLUDE_DIR VLD_LIBRARY_DIR VLD_LIBRARY_DEBUG VLD_LIBRARY)
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS (VLD REQUIRED_VARS VLD_ROOT_DIR
|
||||
VLD_INCLUDE_DIR VLD_LIBRARY VERSION_VAR VLD_VERSION)
|
||||
25
README.md
25
README.md
|
|
@ -1,25 +0,0 @@
|
|||
# Fast Compiliing C++ Library
|
||||
-----------------------------------------
|
||||
|
||||
In my prior attempts at developing MACE what I discovered is that compile times
|
||||
would explode to unreasonable levels that hinder the rate of development more
|
||||
than what can be saved by reduced typing. So I began a quest to get C++ to compile
|
||||
as quickly as Java or C# and the result is this library.
|
||||
|
||||
One of the major drawbacks to templates is that they place everything in header and
|
||||
must be compiled with every run and generate a lot of object code. With Link Time Optimization,
|
||||
the benefit of inline methods mostly disapears, leaving only static vs dynamic polymorphism.
|
||||
|
||||
For the vast majority of applications, a virtual method call is not the bottleneck and the
|
||||
increased compile times costs more than is otherwise justified; therefore, the Fast Compiling C++
|
||||
library opts for virtual interfaces to handle reflection instead of template interfaces. One could
|
||||
argue that both types of reflection could be useful.
|
||||
|
||||
Another source of slowness was the standard template library itself. Most standard template library
|
||||
classes cannot be forward declared and import thousands of lines of code into every compilation unit.
|
||||
|
||||
Another source of slowness is the need to include headers simply because the 'size' of the object must
|
||||
be known. A new utility class allows you to 'forward declare' the size required for certain types which
|
||||
allows you to remove their inclusion from the header file.
|
||||
|
||||
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
#ifndef _FC_ABSTRACT_TYPES_HPP_
|
||||
#define _FC_ABSTRACT_TYPES_HPP_
|
||||
#include <fc/utility.hpp>
|
||||
#include <fc/log.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
struct abstract_type {
|
||||
virtual ~abstract_type(){}
|
||||
virtual size_t size_of()const = 0;
|
||||
/*
|
||||
* @brief Inplace destructor (does not free memory) ((T*)dst)->~T();
|
||||
*/
|
||||
virtual void destructor( void* dst )const = 0;
|
||||
|
||||
/** @brief 'delete T' */
|
||||
virtual void destroy( void* dst )const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct type : virtual abstract_type {
|
||||
virtual size_t size_of()const { return sizeof(T); }
|
||||
virtual void destructor( void* dst )const { ((T*)dst)->~T(); }
|
||||
virtual void destroy( void* dst )const { delete ((T*)dst); }
|
||||
};
|
||||
|
||||
struct abstract_moveable_type : virtual abstract_type {
|
||||
virtual void move_construct( void* dst, void* src )const = 0;
|
||||
virtual void move( void* dst, void* src )const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct moveable_type : virtual type<T>, virtual abstract_moveable_type {
|
||||
static abstract_moveable_type& instance() { static moveable_type<T> inst; return inst; }
|
||||
virtual void destruct( void* dst )const { ((T*)dst)->~T(); }
|
||||
virtual void move_construct( void* dst, void* src )const { slog( "move construct" ); new ((char*)dst) T( fc::move(*((T*)src)) ); }
|
||||
virtual void move( void* dst, void* src )const { *((T*)dst) = fc::move(*((T*)src)); }
|
||||
};
|
||||
|
||||
struct abstract_value_type : virtual abstract_moveable_type {
|
||||
virtual void construct( void* dst )const = 0;
|
||||
virtual void copy_construct( void* dst, const void* src )const = 0;
|
||||
virtual void assign( void* dst, const void* src )const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Default constructable, moveable, copyable, assignable.
|
||||
*/
|
||||
template<typename T>
|
||||
struct value_type : virtual moveable_type<T>, virtual abstract_value_type {
|
||||
static abstract_value_type& instance() { static value_type<T> inst; return inst; }
|
||||
|
||||
virtual void construct( void* dst )const { new ((char*)dst) T(); }
|
||||
virtual void copy_construct( void* dst, const void* src )const { new ((char*)dst) T( *((const T*)src) ); }
|
||||
virtual void assign( void* dst, const void* src )const { *((T*)dst) = *((const T*)src); }
|
||||
};
|
||||
|
||||
struct abstract_less_than_comparable_type {
|
||||
virtual bool less_than( const void* left, const void* right )const = 0;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct less_than_comparable_type : abstract_less_than_comparable_type {
|
||||
virtual bool less_than( const void* left, const void* right )const {
|
||||
return *((const T*)left) < *((const T*)right);
|
||||
}
|
||||
};
|
||||
|
||||
struct abstract_equal_comparable_type {
|
||||
virtual bool equal( const void* left, const void* right )const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct equal_comparable_type : abstract_equal_comparable_type {
|
||||
virtual bool equal( const void* left, const void* right )const {
|
||||
return *((const T*)left) == *((const T*)right);
|
||||
}
|
||||
};
|
||||
|
||||
struct abstract_callable_type {
|
||||
virtual void call( const void* self )const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct callable_type : virtual abstract_callable_type, virtual value_type<T> {
|
||||
virtual void call( const void* self )const { (*((const T*)self))(); }
|
||||
};
|
||||
|
||||
} // namespace fc
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <fc/ptr.hpp>
|
||||
#include <fc/thread.hpp>
|
||||
#include <fc/thread/thread.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef _FC_ALIGNED_HPP_
|
||||
#define _FC_ALIGNED_HPP_
|
||||
#pragma once
|
||||
namespace fc {
|
||||
|
||||
template<unsigned int S, typename T=double>
|
||||
|
|
@ -13,4 +12,3 @@ namespace fc {
|
|||
};
|
||||
|
||||
}
|
||||
#endif // _FC_ALIGNED_HPP_
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
#ifndef _FC_ANY_HPP_
|
||||
#define _FC_ANY_HPP_
|
||||
#pragma once
|
||||
#include <boost/any.hpp>
|
||||
|
||||
namespace fc {
|
||||
// TODO: define this without using boost
|
||||
typedef boost::any any;
|
||||
}
|
||||
|
||||
#endif // _FC_ANY_HPP_
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef _FC_ARRAY_HPP_
|
||||
#define _FC_ARRAY_HPP_
|
||||
#pragma once
|
||||
#include <fc/crypto/base64.hpp>
|
||||
#include <fc/variant.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
|
|
@ -9,6 +10,27 @@ namespace fc {
|
|||
T data[N];
|
||||
};
|
||||
|
||||
}
|
||||
template<typename T, size_t N>
|
||||
bool operator == ( const array<T,N>& a, const array<T,N>& b )
|
||||
{ return 0 == memcmp( a.data, b.data, N ); }
|
||||
template<typename T, size_t N>
|
||||
bool operator != ( const array<T,N>& a, const array<T,N>& b )
|
||||
{ return 0 != memcmp( a.data, b.data, N ); }
|
||||
|
||||
#endif // _FC_ARRAY_HPP_
|
||||
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) );
|
||||
}
|
||||
template<typename T, size_t N>
|
||||
void from_variant( const variant& v, array<T,N>& bi )
|
||||
{
|
||||
fc::vector<char> ve = v.as< vector<char> >();
|
||||
if( ve.size() )
|
||||
{
|
||||
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
else
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,8 @@
|
|||
#pragma once
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <fc/future.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/iostreams/combine.hpp>
|
||||
#include <fc/thread/future.hpp>
|
||||
#include <fc/io/iostream.hpp>
|
||||
|
||||
namespace fc {
|
||||
/**
|
||||
|
|
@ -53,7 +52,7 @@ namespace asio {
|
|||
* This IO service is automatically running in its own thread to service asynchronous
|
||||
* requests without blocking any other threads.
|
||||
*/
|
||||
boost::asio::io_service& default_io_service();
|
||||
boost::asio::io_service& default_io_service(bool cleanup = false);
|
||||
|
||||
/**
|
||||
* @brief wraps boost::asio::async_read
|
||||
|
|
@ -62,18 +61,6 @@ namespace asio {
|
|||
*/
|
||||
template<typename AsyncReadStream, typename MutableBufferSequence>
|
||||
size_t read( AsyncReadStream& s, const MutableBufferSequence& buf ) {
|
||||
detail::non_blocking<AsyncReadStream> non_blocking;
|
||||
|
||||
// TODO: determine if non_blocking query results in a system call that
|
||||
// will slow down every read...
|
||||
if( non_blocking(s) || non_blocking(s,true) ) {
|
||||
boost::system::error_code ec;
|
||||
size_t r = boost::asio::read( s, buf, ec );
|
||||
if( !ec ) return r;
|
||||
if( ec != boost::asio::error::would_block )
|
||||
BOOST_THROW_EXCEPTION( boost::system::system_error(ec) );
|
||||
}
|
||||
|
||||
promise<size_t>::ptr p(new promise<size_t>("fc::asio::read"));
|
||||
boost::asio::async_read( s, buf, boost::bind( detail::read_write_handler, p, _1, _2 ) );
|
||||
return p->wait();
|
||||
|
|
@ -92,39 +79,27 @@ namespace asio {
|
|||
* @return the number of bytes read.
|
||||
*/
|
||||
template<typename AsyncReadStream, typename MutableBufferSequence>
|
||||
size_t read_some( AsyncReadStream& s, const MutableBufferSequence& buf ) {
|
||||
detail::non_blocking<AsyncReadStream> non_blocking;
|
||||
|
||||
// TODO: determine if non_blocking query results in a system call that
|
||||
// will slow down every read...
|
||||
if( non_blocking(s) || non_blocking(s,true) ) {
|
||||
boost::system::error_code ec;
|
||||
size_t r = s.read_some( buf, ec );
|
||||
if( !ec ) return r;
|
||||
if( ec != boost::asio::error::would_block )
|
||||
BOOST_THROW_EXCEPTION( boost::system::system_error(ec) );
|
||||
}
|
||||
|
||||
promise<size_t>::ptr p(new promise<size_t>("fc::asio::read_some"));
|
||||
size_t read_some( AsyncReadStream& s, const MutableBufferSequence& buf )
|
||||
{
|
||||
promise<size_t>::ptr p(new promise<size_t>("fc::asio::async_read_some"));
|
||||
s.async_read_some( buf, boost::bind( detail::read_write_handler, p, _1, _2 ) );
|
||||
return p->wait();
|
||||
}
|
||||
|
||||
template<typename AsyncReadStream>
|
||||
size_t read_some( AsyncReadStream& s, boost::asio::streambuf& buf )
|
||||
{
|
||||
char buffer[1024];
|
||||
size_t bytes_read = read_some( s, boost::asio::buffer( buffer, sizeof(buffer) ) );
|
||||
buf.sputn( buffer, bytes_read );
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
/** @brief wraps boost::asio::async_write
|
||||
* @return the number of bytes written
|
||||
*/
|
||||
template<typename AsyncWriteStream, typename ConstBufferSequence>
|
||||
size_t write( AsyncWriteStream& s, const ConstBufferSequence& buf ) {
|
||||
detail::non_blocking<AsyncWriteStream> non_blocking;
|
||||
|
||||
if( non_blocking(s) || non_blocking(s,true) ) {
|
||||
boost::system::error_code ec;
|
||||
size_t r = boost::asio::write( s, buf, ec );
|
||||
if( !ec ) return r;
|
||||
if( ec != boost::asio::error::would_block) {
|
||||
BOOST_THROW_EXCEPTION( boost::system::system_error(ec) );
|
||||
}
|
||||
}
|
||||
promise<size_t>::ptr p(new promise<size_t>("fc::asio::write"));
|
||||
boost::asio::async_write(s, buf, boost::bind( detail::read_write_handler, p, _1, _2 ) );
|
||||
return p->wait();
|
||||
|
|
@ -137,81 +112,11 @@ namespace asio {
|
|||
*/
|
||||
template<typename AsyncWriteStream, typename ConstBufferSequence>
|
||||
size_t write_some( AsyncWriteStream& s, const ConstBufferSequence& buf ) {
|
||||
detail::non_blocking<AsyncWriteStream> non_blocking;
|
||||
|
||||
if( non_blocking(s) || non_blocking(s,true) ) {
|
||||
boost::system::error_code ec;
|
||||
size_t r = s.write_some( buf, ec );
|
||||
if( !ec ) return r;
|
||||
if( ec != boost::asio::error::would_block) {
|
||||
BOOST_THROW_EXCEPTION( boost::system::system_error(ec) );
|
||||
}
|
||||
}
|
||||
promise<size_t>::ptr p(new promise<size_t>("fc::asio::write_some"));
|
||||
s.async_write_some( buf, boost::bind( detail::read_write_handler, p, _1, _2 ) );
|
||||
return p->wait();
|
||||
}
|
||||
|
||||
template<typename AsyncWriteStream>
|
||||
class sink : public boost::iostreams::sink {
|
||||
public:
|
||||
// struct category : boost::iostreams::sink::category {};
|
||||
typedef char type;
|
||||
|
||||
sink( AsyncWriteStream& p ):m_stream(p){}
|
||||
|
||||
std::streamsize write( const char* s, std::streamsize n ) {
|
||||
return fc::asio::write( m_stream, boost::asio::const_buffers_1(s,n) );
|
||||
}
|
||||
void close() { m_stream.close(); }
|
||||
|
||||
private:
|
||||
AsyncWriteStream& m_stream;
|
||||
};
|
||||
|
||||
template<typename AsyncReadStream>
|
||||
class source : public boost::iostreams::source {
|
||||
public:
|
||||
// struct category : boost::iostreams::sink::category {};
|
||||
typedef char type;
|
||||
|
||||
source( AsyncReadStream& p ):m_stream(p){}
|
||||
|
||||
std::streamsize read( char* s, std::streamsize n ) {
|
||||
return fc::asio::read_some( m_stream, boost::asio::buffer(s,n) );
|
||||
}
|
||||
void close() { m_stream.close(); }
|
||||
|
||||
private:
|
||||
AsyncReadStream& m_stream;
|
||||
};
|
||||
template<typename AsyncStream>
|
||||
class io_device {
|
||||
public:
|
||||
typedef boost::iostreams::bidirectional_device_tag category;
|
||||
typedef char char_type;
|
||||
|
||||
io_device( AsyncStream& p ):m_stream(p){}
|
||||
|
||||
std::streamsize write( const char* s, std::streamsize n ) {
|
||||
return fc::asio::write( m_stream, boost::asio::const_buffers_1(s,static_cast<size_t>(n)) );
|
||||
}
|
||||
std::streamsize read( char* s, std::streamsize n ) {
|
||||
try {
|
||||
return fc::asio::read_some( m_stream, boost::asio::buffer(s,n) );
|
||||
} catch ( const boost::system::system_error& e ) {
|
||||
if( e.code() == boost::asio::error::eof )
|
||||
return -1;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
void close() { m_stream.close(); }
|
||||
|
||||
private:
|
||||
AsyncStream& m_stream;
|
||||
};
|
||||
|
||||
|
||||
namespace tcp {
|
||||
typedef boost::asio::ip::tcp::endpoint endpoint;
|
||||
typedef boost::asio::ip::tcp::resolver::iterator resolver_iterator;
|
||||
|
|
@ -228,7 +133,6 @@ namespace asio {
|
|||
promise<boost::system::error_code>::ptr p( new promise<boost::system::error_code>("fc::asio::tcp::accept") );
|
||||
acc.async_accept( sock, boost::bind( fc::asio::detail::error_handler, p, _1 ) );
|
||||
auto ec = p->wait();
|
||||
if( !ec ) sock.non_blocking(true);
|
||||
if( ec ) BOOST_THROW_EXCEPTION( boost::system::system_error(ec) );
|
||||
}
|
||||
|
||||
|
|
@ -241,23 +145,53 @@ namespace asio {
|
|||
promise<boost::system::error_code>::ptr p(new promise<boost::system::error_code>("fc::asio::tcp::connect"));
|
||||
sock.async_connect( ep, boost::bind( fc::asio::detail::error_handler, p, _1 ) );
|
||||
auto ec = p->wait();
|
||||
if( !ec ) sock.non_blocking(true);
|
||||
if( ec ) BOOST_THROW_EXCEPTION( boost::system::system_error(ec) );
|
||||
}
|
||||
|
||||
typedef boost::iostreams::stream<fc::asio::sink<boost::asio::ip::tcp::socket> > ostream;
|
||||
typedef boost::iostreams::stream<fc::asio::source<boost::asio::ip::tcp::socket> > istream;
|
||||
typedef boost::iostreams::stream<fc::asio::io_device<boost::asio::ip::tcp::socket> > iostream;
|
||||
|
||||
}
|
||||
namespace udp {
|
||||
typedef boost::asio::ip::udp::endpoint endpoint;
|
||||
typedef boost::asio::ip::udp::resolver::iterator resolver_iterator;
|
||||
typedef boost::asio::ip::udp::resolver resolver;
|
||||
/// @brief resolve all udp::endpoints for hostname:port
|
||||
std::vector<endpoint> resolve( resolver& r, const std::string& hostname, const std::string& port );
|
||||
std::vector<endpoint> resolve( resolver& r, const std::string& hostname,
|
||||
const std::string& port );
|
||||
}
|
||||
|
||||
template<typename AsyncReadStream>
|
||||
class istream : public virtual fc::istream
|
||||
{
|
||||
public:
|
||||
istream( std::shared_ptr<AsyncReadStream> str )
|
||||
:_stream( fc::move(str) ){}
|
||||
|
||||
virtual size_t readsome( char* buf, size_t len )
|
||||
{
|
||||
auto r = fc::asio::read_some(*_stream, boost::asio::buffer(buf, len) );
|
||||
return r;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<AsyncReadStream> _stream;
|
||||
};
|
||||
|
||||
template<typename AsyncWriteStream>
|
||||
class ostream : public virtual fc::ostream
|
||||
{
|
||||
public:
|
||||
ostream( std::shared_ptr<AsyncWriteStream> str )
|
||||
:_stream( fc::move(str) ){}
|
||||
|
||||
virtual size_t writesome( const char* buf, size_t len )
|
||||
{
|
||||
return fc::asio::write_some(*_stream, boost::asio::const_buffers_1(buf, len) );
|
||||
}
|
||||
|
||||
virtual void close(){ _stream->close(); }
|
||||
virtual void flush() {}
|
||||
private:
|
||||
std::shared_ptr<AsyncWriteStream> _stream;
|
||||
};
|
||||
|
||||
|
||||
} } // namespace fc::asio
|
||||
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef _FC_BIGINT_HPP
|
||||
#define _FC_BIGINT_HPP
|
||||
#include <stdint.h>
|
||||
#include <fc/string.hpp>
|
||||
|
||||
struct bignum_st;
|
||||
typedef bignum_st BIGNUM;
|
||||
|
||||
namespace fc {
|
||||
class bigint {
|
||||
public:
|
||||
bigint( const char* bige, uint32_t l );
|
||||
bigint( unsigned long i = 0 );
|
||||
bigint( const bigint& c );
|
||||
bigint( bigint&& c );
|
||||
~bigint();
|
||||
|
||||
bool is_negative()const;
|
||||
int64_t to_int64()const;
|
||||
|
||||
int64_t log2()const;
|
||||
bool operator < ( const bigint& c )const;
|
||||
bool operator > ( const bigint& c )const;
|
||||
bool operator >= ( const bigint& c )const;
|
||||
bool operator == ( const bigint& c )const;
|
||||
|
||||
bigint operator + ( const bigint& a )const;
|
||||
bigint operator * ( const bigint& a )const;
|
||||
bigint operator / ( const bigint& a )const;
|
||||
bigint operator - ( const bigint& a )const;
|
||||
|
||||
bigint& operator = ( const bigint& a );
|
||||
bigint& operator = ( bigint&& a );
|
||||
|
||||
operator fc::string()const;
|
||||
|
||||
private:
|
||||
BIGNUM* n;
|
||||
};
|
||||
} // namespace fc
|
||||
|
||||
#endif
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef _FC_BUFFER_HPP_
|
||||
#define _FC_BUFFER_HPP_
|
||||
namespace fc {
|
||||
|
||||
struct const_buffer {
|
||||
const_buffer( const char* const c = 0, size_t l = 0 )
|
||||
:data(c),size(l){}
|
||||
const char* const data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct mutable_buffer {
|
||||
mutable_buffer( char* c = 0, size_t l = 0 )
|
||||
:data(c),size(l){}
|
||||
char* data;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _FC_BUFFER_HPP_
|
||||
10
include/fc/crypto/base32.hpp
Normal file
10
include/fc/crypto/base32.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
fc::vector<char> from_base32( const fc::string& b32 );
|
||||
fc::string to_base32( const fc::vector<char>& vec );
|
||||
fc::string to_base32( const char* data, size_t len );
|
||||
}
|
||||
10
include/fc/crypto/base36.hpp
Normal file
10
include/fc/crypto/base36.hpp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
fc::vector<char> from_base36( const fc::string& b36 );
|
||||
fc::string to_base36( const fc::vector<char>& vec );
|
||||
fc::string to_base36( const char* data, size_t len );
|
||||
}
|
||||
8
include/fc/crypto/base64.hpp
Normal file
8
include/fc/crypto/base64.hpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace fc {
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len);
|
||||
std::string base64_encode( const std::string& enc );
|
||||
std::string base64_decode( const std::string& encoded_string);
|
||||
} // namespace fc
|
||||
70
include/fc/crypto/bigint.hpp
Normal file
70
include/fc/crypto/bigint.hpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/vector.hpp>
|
||||
|
||||
struct bignum_st;
|
||||
typedef bignum_st BIGNUM;
|
||||
|
||||
namespace fc {
|
||||
class bigint {
|
||||
public:
|
||||
bigint( const fc::vector<char>& bige );
|
||||
bigint( const char* bige, uint32_t l );
|
||||
bigint( unsigned long i = 0 );
|
||||
bigint( const bigint& c );
|
||||
bigint( bigint&& c );
|
||||
explicit bigint( BIGNUM* n );
|
||||
~bigint();
|
||||
|
||||
bigint& operator = ( const bigint& a );
|
||||
bigint& operator = ( bigint&& a );
|
||||
|
||||
operator bool()const;
|
||||
|
||||
bool is_negative()const;
|
||||
int64_t to_int64()const;
|
||||
|
||||
int64_t log2()const;
|
||||
bigint exp( const bigint& c )const;
|
||||
|
||||
static bigint random( uint32_t bits, int t, int );
|
||||
|
||||
bool operator < ( const bigint& c )const;
|
||||
bool operator > ( const bigint& c )const;
|
||||
bool operator >= ( const bigint& c )const;
|
||||
bool operator == ( const bigint& c )const;
|
||||
bool operator != ( const bigint& c )const;
|
||||
|
||||
bigint operator + ( const bigint& a )const;
|
||||
bigint operator * ( const bigint& a )const;
|
||||
bigint operator / ( const bigint& a )const;
|
||||
bigint operator % ( const bigint& a )const;
|
||||
bigint operator /= ( const bigint& a );
|
||||
bigint operator - ( const bigint& a )const;
|
||||
|
||||
|
||||
bigint operator++(int);
|
||||
bigint& operator++();
|
||||
bigint operator--(int);
|
||||
bigint& operator--();
|
||||
|
||||
operator fc::string()const;
|
||||
|
||||
// returns bignum as bigendian bytes
|
||||
operator fc::vector<char>()const;
|
||||
|
||||
BIGNUM* dup()const;
|
||||
|
||||
BIGNUM* get()const { return n; }
|
||||
private:
|
||||
BIGNUM* n;
|
||||
};
|
||||
|
||||
class variant;
|
||||
/** encodes the big int as base64 string, or a number */
|
||||
void to_variant( const bigint& bi, variant& v );
|
||||
/** decodes the big int as base64 string, or a number */
|
||||
void from_variant( const variant& v, bigint& bi );
|
||||
} // namespace fc
|
||||
|
||||
|
|
@ -120,8 +120,7 @@ E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA
|
|||
|
||||
*/
|
||||
|
||||
#ifndef __FC_BLOWFISH_HPP__
|
||||
#define __FC_BLOWFISH_HPP__
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace fc {
|
||||
|
|
@ -150,12 +149,12 @@ public:
|
|||
void reset_chain() { m_oChain = m_oChain0; }
|
||||
|
||||
// encrypt/decrypt Buffer in Place
|
||||
void encrypt(unsigned char* buf, uint64_t n, int iMode=ECB);
|
||||
void decrypt(unsigned char* buf, uint64_t n, int iMode=ECB);
|
||||
void encrypt(unsigned char* buf, uint64_t n, int iMode=CBC);
|
||||
void decrypt(unsigned char* buf, uint64_t n, int iMode=CBC);
|
||||
|
||||
// encrypt/decrypt from Input Buffer to Output Buffer
|
||||
void encrypt(const unsigned char* in, unsigned char* out, uint64_t n, int iMode=ECB);
|
||||
void decrypt(const unsigned char* in, unsigned char* out, uint64_t n, int iMode=ECB);
|
||||
void encrypt(const unsigned char* in, unsigned char* out, uint64_t n, int iMode=CBC);
|
||||
void decrypt(const unsigned char* in, unsigned char* out, uint64_t n, int iMode=CBC);
|
||||
|
||||
//Private Functions
|
||||
private:
|
||||
|
|
@ -176,5 +175,4 @@ private:
|
|||
|
||||
} // namespace fc
|
||||
|
||||
#endif // __BLOWFISH_H__
|
||||
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
#ifndef _FC_DH_HPP_
|
||||
#define _FC_DH_HPP_
|
||||
//#include <fc/vector.hpp>
|
||||
#include <vector>
|
||||
#pragma once
|
||||
#include <fc/vector.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace fc {
|
||||
|
|
@ -11,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 std::vector<char>& pubk);
|
||||
bool compute_shared_key( const vector<char>& pubk);
|
||||
bool validate();
|
||||
|
||||
std::vector<char> p;
|
||||
std::vector<char> pub_key;
|
||||
std::vector<char> priv_key;
|
||||
std::vector<char> shared_key;
|
||||
vector<char> p;
|
||||
vector<char> pub_key;
|
||||
vector<char> priv_key;
|
||||
vector<char> shared_key;
|
||||
bool valid;
|
||||
uint8_t g;
|
||||
};
|
||||
|
|
@ -25,4 +23,3 @@ namespace fc {
|
|||
} // namespace fc
|
||||
|
||||
|
||||
#endif
|
||||
61
include/fc/crypto/elliptic.hpp
Normal file
61
include/fc/crypto/elliptic.hpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
#include <fc/crypto/bigint.hpp>
|
||||
#include <fc/crypto/sha256.hpp>
|
||||
#include <fc/crypto/sha512.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/array.hpp>
|
||||
|
||||
namespace fc { namespace ecc {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class public_key_impl;
|
||||
class private_key_impl;
|
||||
}
|
||||
|
||||
typedef fc::array<char,72> signature;
|
||||
typedef fc::array<unsigned char,65> compact_signature;
|
||||
|
||||
class public_key
|
||||
{
|
||||
public:
|
||||
public_key();
|
||||
~public_key();
|
||||
bool verify( const fc::sha256& digest, const signature& sig );
|
||||
|
||||
std::vector<char> serialize();
|
||||
public_key( const std::vector<char>& v );
|
||||
public_key( const compact_signature& c, const fc::sha256& digest );
|
||||
private:
|
||||
friend class private_key;
|
||||
fc::fwd<detail::public_key_impl,8> my;
|
||||
};
|
||||
|
||||
|
||||
class private_key
|
||||
{
|
||||
public:
|
||||
private_key();
|
||||
private_key( std::vector<char> k );
|
||||
~private_key();
|
||||
|
||||
static private_key generate();
|
||||
static private_key regenerate( const fc::sha256& secret );
|
||||
|
||||
fc::sha256 get_secret()const; // get the private key secret
|
||||
|
||||
/**
|
||||
* Given a public key, calculatse a 512 bit shared secret between that
|
||||
* key and this private key.
|
||||
*/
|
||||
fc::sha512 get_shared_secret( const public_key& pub );
|
||||
|
||||
signature sign( const fc::sha256& digest );
|
||||
compact_signature sign_compact( const fc::sha256& digest );
|
||||
bool verify( const fc::sha256& digest, const signature& sig );
|
||||
|
||||
public_key get_public_key()const;
|
||||
private:
|
||||
fc::fwd<detail::private_key_impl,8> my;
|
||||
};
|
||||
} } // fc::ecc
|
||||
113
include/fc/crypto/pke.hpp
Normal file
113
include/fc/crypto/pke.hpp
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#pragma once
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <fc/crypto/sha1.hpp>
|
||||
#include <fc/crypto/sha256.hpp>
|
||||
#include <fc/io/raw_fwd.hpp>
|
||||
#include <fc/array.hpp>
|
||||
|
||||
namespace fc {
|
||||
namespace detail { class pke_impl; }
|
||||
|
||||
class private_key;
|
||||
class public_key;
|
||||
void generate_key_pair( public_key&, private_key& );
|
||||
|
||||
typedef std::vector<char> bytes;
|
||||
typedef bytes signature;
|
||||
|
||||
class public_key
|
||||
{
|
||||
public:
|
||||
public_key();
|
||||
explicit public_key( const bytes& d );
|
||||
public_key( const public_key& k );
|
||||
public_key( public_key&& k );
|
||||
~public_key();
|
||||
|
||||
operator bool()const;
|
||||
|
||||
public_key& operator=(const public_key& p );
|
||||
public_key& operator=(public_key&& p );
|
||||
|
||||
bool verify( const sha1& digest, const array<char,2048/8>& sig )const;
|
||||
bool verify( const sha1& digest, const signature& sig )const;
|
||||
bool verify( const sha256& digest, const signature& sig )const;
|
||||
bytes encrypt( const char* data, size_t len )const;
|
||||
bytes encrypt( const bytes& )const;
|
||||
bytes decrypt( const bytes& )const;
|
||||
|
||||
bytes serialize()const;
|
||||
friend void generate_key_pair( public_key&, private_key& );
|
||||
private:
|
||||
std::shared_ptr<detail::pke_impl> my;
|
||||
};
|
||||
|
||||
class private_key
|
||||
{
|
||||
public:
|
||||
private_key();
|
||||
explicit private_key( const bytes& d );
|
||||
private_key( const private_key& k );
|
||||
private_key( private_key&& k );
|
||||
~private_key();
|
||||
|
||||
operator bool()const;
|
||||
|
||||
private_key& operator=(const private_key& p );
|
||||
private_key& operator=(private_key&& p );
|
||||
|
||||
void sign( const sha1& digest, array<char,2048/8>& sig )const;
|
||||
signature sign( const sha1& digest )const;
|
||||
signature sign( const sha256& digest )const;
|
||||
|
||||
bytes decrypt( const char* bytes, size_t len )const;
|
||||
bytes decrypt( const bytes& )const;
|
||||
bytes encrypt( const bytes& )const;
|
||||
|
||||
bytes serialize()const;
|
||||
friend void generate_key_pair( public_key&, private_key& );
|
||||
|
||||
private:
|
||||
std::shared_ptr<detail::pke_impl> my;
|
||||
};
|
||||
bool operator==( const private_key& a, const private_key& b );
|
||||
|
||||
namespace raw
|
||||
{
|
||||
template<typename Stream>
|
||||
void unpack( Stream& s, fc::public_key& pk)
|
||||
{
|
||||
bytes ser;
|
||||
fc::raw::unpack(s,ser);
|
||||
pk = fc::public_key( ser );
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void pack( Stream& s, const fc::public_key& pk)
|
||||
{
|
||||
fc::raw::pack( s, pk.serialize() );
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void unpack( Stream& s, fc::private_key& pk)
|
||||
{
|
||||
bytes ser;
|
||||
fc::raw::unpack(s,ser);
|
||||
pk = fc::private_key( ser );
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void pack( Stream& s, const fc::private_key& pk)
|
||||
{
|
||||
fc::raw::pack( s, pk.serialize() );
|
||||
}
|
||||
}
|
||||
class variant;
|
||||
void to_variant( const public_key& bi, variant& v );
|
||||
void from_variant( const variant& v, public_key& bi );
|
||||
void to_variant( const private_key& bi, variant& v );
|
||||
void from_variant( const variant& v, private_key& bi );
|
||||
|
||||
} // fc
|
||||
|
||||
67
include/fc/crypto/sha1.hpp
Normal file
67
include/fc/crypto/sha1.hpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#pragma once
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc{
|
||||
|
||||
class sha1
|
||||
{
|
||||
public:
|
||||
sha1();
|
||||
explicit sha1( const string& hex_str );
|
||||
|
||||
string str()const;
|
||||
operator string()const;
|
||||
|
||||
char* data()const;
|
||||
|
||||
static sha1 hash( const char* d, uint32_t dlen );
|
||||
static sha1 hash( const string& );
|
||||
|
||||
template<typename T>
|
||||
static sha1 hash( const T& t )
|
||||
{
|
||||
sha1::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();
|
||||
sha1 result();
|
||||
|
||||
private:
|
||||
struct impl;
|
||||
fc::fwd<impl,96> my;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator<<( T& ds, const sha1& ep ) {
|
||||
ds.write( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator>>( T& ds, sha1& ep ) {
|
||||
ds.read( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
friend sha1 operator << ( const sha1& h1, uint32_t i );
|
||||
friend bool operator == ( const sha1& h1, const sha1& h2 );
|
||||
friend bool operator != ( const sha1& h1, const sha1& h2 );
|
||||
friend sha1 operator ^ ( const sha1& h1, const sha1& h2 );
|
||||
friend bool operator >= ( const sha1& h1, const sha1& h2 );
|
||||
friend bool operator > ( const sha1& h1, const sha1& h2 );
|
||||
friend bool operator < ( const sha1& h1, const sha1& h2 );
|
||||
|
||||
uint32_t _hash[5];
|
||||
};
|
||||
|
||||
} // namespace fc
|
||||
72
include/fc/crypto/sha256.hpp
Normal file
72
include/fc/crypto/sha256.hpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#pragma once
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
|
||||
class sha256
|
||||
{
|
||||
public:
|
||||
sha256();
|
||||
explicit sha256( const string& hex_str );
|
||||
|
||||
string str()const;
|
||||
operator string()const;
|
||||
|
||||
char* data()const;
|
||||
|
||||
static sha256 hash( const char* d, uint32_t dlen );
|
||||
static sha256 hash( const string& );
|
||||
|
||||
template<typename T>
|
||||
static sha256 hash( const T& t )
|
||||
{
|
||||
sha256::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();
|
||||
sha256 result();
|
||||
|
||||
private:
|
||||
struct impl;
|
||||
fc::fwd<impl,112> my;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator<<( T& ds, const sha256& ep ) {
|
||||
ds.write( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator>>( T& ds, sha256& ep ) {
|
||||
ds.read( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
friend sha256 operator << ( const sha256& h1, uint32_t i );
|
||||
friend bool operator == ( const sha256& h1, const sha256& h2 );
|
||||
friend bool operator != ( const sha256& h1, const sha256& h2 );
|
||||
friend sha256 operator ^ ( const sha256& h1, const sha256& h2 );
|
||||
friend bool operator >= ( const sha256& h1, const sha256& h2 );
|
||||
friend bool operator > ( const sha256& h1, const sha256& h2 );
|
||||
friend bool operator < ( const sha256& h1, const sha256& h2 );
|
||||
|
||||
uint64_t _hash[4];
|
||||
};
|
||||
|
||||
class variant;
|
||||
void to_variant( const sha256& bi, variant& v );
|
||||
void from_variant( const variant& v, sha256& bi );
|
||||
|
||||
} // fc
|
||||
72
include/fc/crypto/sha512.hpp
Normal file
72
include/fc/crypto/sha512.hpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#pragma once
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
|
||||
class sha512
|
||||
{
|
||||
public:
|
||||
sha512();
|
||||
explicit sha512( const string& hex_str );
|
||||
|
||||
string str()const;
|
||||
operator string()const;
|
||||
|
||||
char* data()const;
|
||||
|
||||
static sha512 hash( const char* d, uint32_t dlen );
|
||||
static sha512 hash( const string& );
|
||||
|
||||
template<typename T>
|
||||
static sha512 hash( const T& t )
|
||||
{
|
||||
sha512::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();
|
||||
sha512 result();
|
||||
|
||||
private:
|
||||
struct impl;
|
||||
fc::fwd<impl,216> my;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator<<( T& ds, const sha512& ep ) {
|
||||
ds.write( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator>>( T& ds, sha512& ep ) {
|
||||
ds.read( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
friend sha512 operator << ( const sha512& h1, uint32_t i );
|
||||
friend bool operator == ( const sha512& h1, const sha512& h2 );
|
||||
friend bool operator != ( const sha512& h1, const sha512& h2 );
|
||||
friend sha512 operator ^ ( const sha512& h1, const sha512& h2 );
|
||||
friend bool operator >= ( const sha512& h1, const sha512& h2 );
|
||||
friend bool operator > ( const sha512& h1, const sha512& h2 );
|
||||
friend bool operator < ( const sha512& h1, const sha512& h2 );
|
||||
|
||||
uint64_t _hash[8];
|
||||
};
|
||||
|
||||
class variant;
|
||||
void to_variant( const sha512& bi, variant& v );
|
||||
void from_variant( const variant& v, sha512& bi );
|
||||
|
||||
} // fc
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc {
|
||||
struct future_wait_timeout: public std::exception{
|
||||
future_wait_timeout( const fc::string& msg = "" ):m_msg(msg){}
|
||||
~future_wait_timeout()throw() {}
|
||||
const char* what()const throw() { return m_msg.c_str(); }
|
||||
private:
|
||||
fc::string m_msg;
|
||||
};
|
||||
struct task_canceled: public std::exception{};
|
||||
struct thread_quit: public std::exception{};
|
||||
struct wait_any_error: public std::exception{};
|
||||
|
||||
struct pke_exception : public std::exception {};
|
||||
struct invalid_buffer_length : public pke_exception {};
|
||||
struct invalid_key_length : public pke_exception {};
|
||||
|
||||
struct generic_exception : public std::exception {
|
||||
generic_exception( const fc::string& msg = "" ):m_msg(msg){}
|
||||
~generic_exception()throw() {}
|
||||
const char* what()const throw() { return m_msg.c_str(); }
|
||||
private:
|
||||
fc::string m_msg;
|
||||
};
|
||||
|
||||
|
||||
struct bad_cast: public std::exception{
|
||||
const char* what()const throw(){ return "bad cast"; }
|
||||
};
|
||||
struct range_error: public std::exception{
|
||||
const char* what()const throw(){ return "range error"; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/value.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <fc/exception.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
/**
|
||||
* Represents one stack frame within an error_report.
|
||||
*/
|
||||
class error_frame {
|
||||
public:
|
||||
error_frame( const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value m );
|
||||
error_frame( bool detail, const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value m );
|
||||
error_frame():file("unknown-file"),line(0){}
|
||||
error_frame(const error_frame& );
|
||||
error_frame(error_frame&& );
|
||||
|
||||
error_frame& operator=(const error_frame& );
|
||||
error_frame& operator=(error_frame&& );
|
||||
|
||||
fc::string to_string()const;
|
||||
fc::string to_detail_string()const;
|
||||
|
||||
fc::string desc;
|
||||
fc::string file;
|
||||
int64_t line;
|
||||
fc::string method;
|
||||
fc::optional<fc::value> meta;
|
||||
fc::string time;
|
||||
bool detail;
|
||||
};
|
||||
typedef fc::vector<error_frame> error_context;
|
||||
|
||||
/**
|
||||
* This class is used for rich error reporting that captures relevant errors the
|
||||
* whole way up the stack. By using FC_THROW_REPORT(...) and FC_REPORT_PUSH( e, ...)
|
||||
* you can capture the file, line, and method where the error was caught / rethrown.
|
||||
*/
|
||||
class error_report {
|
||||
public:
|
||||
error_report();
|
||||
error_report( const fc::string& desc, fc::value meta = fc::value() );
|
||||
error_report( const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value meta = fc::value() );
|
||||
|
||||
error_frame& current();
|
||||
error_report& pop_frame();
|
||||
error_report& push_frame( const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value meta = fc::value() );
|
||||
error_report& push_frame( bool detail, const fc::string& file, uint64_t line, const fc::string& method, const fc::string& desc, fc::value meta = fc::value() );
|
||||
error_report& append( const error_report& e );
|
||||
|
||||
fc::string to_string()const;
|
||||
fc::string to_detail_string()const;
|
||||
error_context stack; ///< Human readable stack of what we were atempting to do.
|
||||
|
||||
fc::exception_ptr copy_exception();
|
||||
};
|
||||
|
||||
fc::string substitute( const fc::string& format, const fc::value& keys );
|
||||
fc::value recursive_substitute( const value& in, const fc::value& keys );
|
||||
|
||||
} // namespace fc
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
FC_REFLECT( fc::error_frame, (desc)(file)(line)(method)(time)(meta)(detail) )
|
||||
FC_REFLECT( fc::error_report, (stack) )
|
||||
|
||||
#define FC_IDENT(...) __VA_ARGS__
|
||||
#define FC_REPORT( X, ... ) fc::error_report X( __FILE__, __LINE__, __func__, __VA_ARGS__ )
|
||||
#define FC_THROW_REPORT( ... ) FC_THROW( fc::error_report( __FILE__, __LINE__, __func__, __VA_ARGS__ ))
|
||||
#define FC_REPORT_CURRENT(ER, ... ) (ER).pop_frame().push_frame( __FILE__, __LINE__, __func__, __VA_ARGS__ )
|
||||
#define FC_REPORT_PUSH( ER, ... ) (ER).push_frame( __FILE__, __LINE__, __func__, __VA_ARGS__ );
|
||||
#define FC_REPORT_PUSH_DETAIL( ER, ... ) (ER).push_frame( true, __FILE__, __LINE__, __func__, __VA_ARGS__ )
|
||||
#define FC_REPORT_POP(ER) (ER).pop_frame()
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef _EXAMPLE_HPP_
|
||||
#define _EXAMPLE_HPP_
|
||||
#include <fc/reflect_fwd.hpp>
|
||||
|
||||
struct example {
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
|
||||
FC_REFLECTABLE( example )
|
||||
|
||||
#endif // _EXAMPLE_HPP_
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
#ifndef _FC_EXCEPTION_HPP_
|
||||
#define _FC_EXCEPTION_HPP_
|
||||
#include <fc/shared_ptr.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <boost/current_function.hpp>
|
||||
|
||||
// TODO: Remove boost exception dependency here!!
|
||||
// TODO: Remove boost format dependency here!!
|
||||
|
||||
// provided for easy integration with boost.
|
||||
namespace boost { class exception_ptr; }
|
||||
|
||||
namespace fc {
|
||||
/**
|
||||
* Simply including boost/exception_ptr.hpp is enough to significantly
|
||||
* lengthen compile times. This header defines an 'opaque' exception
|
||||
* type that provides the most 'general' exception handling needs without
|
||||
* requiring a significant amount of code to be included.
|
||||
*/
|
||||
class exception_ptr {
|
||||
public:
|
||||
exception_ptr();
|
||||
exception_ptr( const boost::exception_ptr& c );
|
||||
exception_ptr( boost::exception_ptr&& c );
|
||||
exception_ptr( const exception_ptr& c );
|
||||
exception_ptr( exception_ptr&& c );
|
||||
~exception_ptr();
|
||||
|
||||
exception_ptr& operator=(const boost::exception_ptr& c);
|
||||
exception_ptr& operator=(boost::exception_ptr&& c);
|
||||
|
||||
exception_ptr& operator=(const exception_ptr& c);
|
||||
exception_ptr& operator=(exception_ptr&& c);
|
||||
|
||||
fc::string diagnostic_information()const;
|
||||
|
||||
operator bool()const;
|
||||
|
||||
operator const boost::exception_ptr& ()const;
|
||||
operator boost::exception_ptr& ();
|
||||
private:
|
||||
char my[sizeof(void*)*2];
|
||||
};
|
||||
|
||||
exception_ptr current_exception();
|
||||
template<typename T>
|
||||
inline exception_ptr copy_exception( T&& e ) {
|
||||
try { throw e; } catch (...) { return current_exception(); }
|
||||
return exception_ptr();
|
||||
}
|
||||
void rethrow_exception( const exception_ptr& e );
|
||||
|
||||
void throw_exception( const char* func, const char* file, int line, const char* msg );
|
||||
void throw_exception_( const char* func, const char* file, int line, const char* msg,
|
||||
const fc::string& a1 );
|
||||
void throw_exception_( const char* func, const char* file, int line, const char* msg,
|
||||
const fc::string& a1, const fc::string& a2 );
|
||||
void throw_exception_( const char* func, const char* file, int line, const char* msg,
|
||||
const fc::string& a1, const fc::string& a2, const fc::string& a3 );
|
||||
void throw_exception_( const char* func, const char* file, int line, const char* msg,
|
||||
const fc::string& a1, const fc::string& a2, const fc::string& a3, const fc::string& a4 );
|
||||
|
||||
template<typename T>
|
||||
fc::string to_string( T&& v ) { return fc::string(fc::forward<T>(v)); }
|
||||
fc::string to_string( char v ); // { return fc::string(&v,1); }
|
||||
fc::string to_string( uint64_t v );
|
||||
fc::string to_string( int64_t v );
|
||||
fc::string to_string( double v );
|
||||
fc::string to_string( float v );
|
||||
fc::string to_string( int8_t v );
|
||||
fc::string to_string( uint8_t v );
|
||||
fc::string to_string( int32_t v );
|
||||
fc::string to_string( uint32_t v );
|
||||
fc::string to_string( int16_t v );
|
||||
fc::string to_string( uint16_t v );
|
||||
// fc::string to_string( size_t v );
|
||||
// fc::string to_string( long int v );
|
||||
|
||||
template<typename T>
|
||||
void throw_exception( const char* func, const char* file, int line, const char* msg, T&& a1 ) {
|
||||
throw_exception_( func, file, line, msg, to_string(fc::forward<T>(a1) ) );
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
void throw_exception( const char* func, const char* file, int line, const char* msg, T1&& a1, T2&& a2 ) {
|
||||
throw_exception_( func, file, line, msg, to_string(fc::forward<T1>(a1) ), to_string( fc::forward<T2>(a2) ) );
|
||||
}
|
||||
template<typename T1, typename T2, typename T3>
|
||||
void throw_exception( const char* func, const char* file, int line, const char* msg, T1&& a1, T2&& a2, T3&& a3 ) {
|
||||
throw_exception_( func, file, line, msg, to_string(fc::forward<T1>(a1) ), to_string( fc::forward<T2>(a2) ), to_string( fc::forward<T3>(a3) ) );
|
||||
}
|
||||
template<typename T1, typename T2, typename T3, typename T4>
|
||||
void throw_exception( const char* func, const char* file, int line, const char* msg, T1&& a1, T2&& a2, T3&& a3, T4&& a4 ) {
|
||||
throw_exception_( func, file, line, msg, to_string(fc::forward<T1>(a1) ), to_string( fc::forward<T2>(a2) ), to_string( fc::forward<T3>(a3) ), to_string( fc::forward<T4>(a4) ) );
|
||||
}
|
||||
|
||||
fc::string except_str();
|
||||
|
||||
} // namespace fc
|
||||
#define FC_THROW(X) throw X
|
||||
#define FC_THROW_MSG( ... ) \
|
||||
do { \
|
||||
fc::throw_exception( BOOST_CURRENT_FUNCTION, __FILE__, __LINE__, __VA_ARGS__ ); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#endif // _FC_EXCEPTION_HPP_
|
||||
238
include/fc/exception/exception.hpp
Normal file
238
include/fc/exception/exception.hpp
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#pragma once
|
||||
/**
|
||||
* @file exception.hpp
|
||||
* @brief Defines exception's used by fc
|
||||
*/
|
||||
#include <fc/log/log_message.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <exception>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
namespace detail { class exception_impl; }
|
||||
|
||||
/**
|
||||
* @brief Used to generate a useful error report when an exception is thrown.
|
||||
* @ingroup serializable
|
||||
*
|
||||
* At each level in the stack where the exception is caught and rethrown a
|
||||
* new log_message is added to the exception.
|
||||
*
|
||||
* exception's are designed to be serialized to a variant and
|
||||
* deserialized from an variant.
|
||||
*
|
||||
* @see FC_THROW_EXCEPTION
|
||||
* @see FC_RETHROW_EXCEPTION
|
||||
* @see FC_RETHROW_EXCEPTIONS
|
||||
*/
|
||||
class exception
|
||||
{
|
||||
public:
|
||||
exception();
|
||||
exception( log_message&& );
|
||||
exception( const exception& e );
|
||||
exception( exception&& e );
|
||||
~exception();
|
||||
|
||||
virtual const char* what()const throw() { return "exception"; }
|
||||
|
||||
/**
|
||||
* @return a reference to log messages that have
|
||||
* been added to this log.
|
||||
*/
|
||||
const log_messages& get_log()const;
|
||||
void append_log( log_message m );
|
||||
|
||||
/**
|
||||
* Generates a detailed string including file, line, method,
|
||||
* and other information that is generally only useful for
|
||||
* developers.
|
||||
*/
|
||||
string to_detail_string( log_level ll = log_level::all )const;
|
||||
|
||||
/**
|
||||
* Generates a user-friendly error report.
|
||||
*/
|
||||
string to_string( log_level ll = log_level::info )const;
|
||||
|
||||
/**
|
||||
* Throw this exception as its most derived type.
|
||||
*
|
||||
* @note does not return.
|
||||
*/
|
||||
virtual NO_RETURN void dynamic_rethrow_exception()const;
|
||||
|
||||
/**
|
||||
* This is equivalent to:
|
||||
* @code
|
||||
* try { throwAsDynamic_exception(); }
|
||||
* catch( ... ) { return std::current_exception(); }
|
||||
* @endcode
|
||||
*/
|
||||
virtual std::shared_ptr<exception> dynamic_copy_exception()const;
|
||||
|
||||
protected:
|
||||
friend void to_variant( const exception& e, variant& v );
|
||||
friend void from_variant( const variant& e, exception& ll );
|
||||
virtual void from_variant( const variant& ){}
|
||||
virtual void to_variant( variant& ){}
|
||||
|
||||
std::unique_ptr<detail::exception_impl> my;
|
||||
};
|
||||
void to_variant( const exception& e, variant& v );
|
||||
void from_variant( const variant& e, exception& ll );
|
||||
typedef std::shared_ptr<exception> exception_ptr;
|
||||
|
||||
typedef optional<exception> oexception;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief re-thrown whenever an unhandled exception is caught.
|
||||
* @ingroup serializable
|
||||
* Any exceptions thrown by 3rd party libraries that are not
|
||||
* caught get wrapped in an unhandled_exception exception.
|
||||
*
|
||||
* The original exception is captured as a std::exception_ptr
|
||||
* which may be rethrown. The std::exception_ptr does not
|
||||
* propgate across process boundaries.
|
||||
*/
|
||||
class unhandled_exception : public exception
|
||||
{
|
||||
public:
|
||||
unhandled_exception( log_message&& m, std::exception_ptr e = std::current_exception() );
|
||||
unhandled_exception( log_messages );
|
||||
unhandled_exception( const exception& );
|
||||
virtual const char* what()const throw() { return "Unhandled _exception"; }
|
||||
std::exception_ptr get_inner_exception()const;
|
||||
|
||||
virtual NO_RETURN void dynamic_rethrow_exception()const;
|
||||
virtual std::shared_ptr<exception> dynamic_copy_exception()const;
|
||||
private:
|
||||
std::exception_ptr _inner;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
fc::exception_ptr copy_exception( T&& e )
|
||||
{
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1700)
|
||||
return std::make_shared<unhandled_exception>( log_message(), std::copy_exception(fc::forward<T>(e)) );
|
||||
#else
|
||||
return std::make_shared<unhandled_exception>( log_message(), std::make_exception_ptr(fc::forward<T>(e)) );
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief wraps unhanlded std::exception's
|
||||
* @ingroup serializable
|
||||
*
|
||||
* This exception allows the 'what' field of unhandled std::exceptions
|
||||
* to be propagated across process boundaries.
|
||||
*/
|
||||
class std_exception : public unhandled_exception
|
||||
{
|
||||
public:
|
||||
std_exception( log_message&& m, std::exception_ptr e, const char* w );
|
||||
std_exception( log_messages );
|
||||
std_exception( const exception& c);
|
||||
virtual const char* what()const throw() { return _what.c_str(); }
|
||||
|
||||
protected:
|
||||
void from_variant( const variant& v );
|
||||
void to_variant( variant& v );
|
||||
private:
|
||||
string _what;
|
||||
};
|
||||
|
||||
|
||||
#define FC_DECLARE_EXCEPTION( TYPE, WHAT ) \
|
||||
class TYPE : public exception \
|
||||
{ \
|
||||
public: \
|
||||
TYPE( log_message&& m ); \
|
||||
TYPE( log_messages ); \
|
||||
TYPE( const TYPE& c ); \
|
||||
TYPE(); \
|
||||
virtual const char* what()const throw() { return WHAT; } \
|
||||
};
|
||||
|
||||
FC_DECLARE_EXCEPTION( timeout_exception, "Timeout" );
|
||||
FC_DECLARE_EXCEPTION( file_not_found_exception, "File Not Found" );
|
||||
/**
|
||||
* @brief report's parse errors
|
||||
*/
|
||||
FC_DECLARE_EXCEPTION( parse_error_exception, "Parse Error" );
|
||||
FC_DECLARE_EXCEPTION( invalid_arg_exception, "Invalid Argument" );
|
||||
/**
|
||||
* @brief reports when a key, guid, or other item is not found.
|
||||
*/
|
||||
FC_DECLARE_EXCEPTION( key_not_found_exception, "Key Not Found" );
|
||||
FC_DECLARE_EXCEPTION( bad_cast_exception, "Bad Cast" );
|
||||
FC_DECLARE_EXCEPTION( out_of_range_exception, "Out of Range" );
|
||||
|
||||
/** @brief if an operation is unsupported or not valid this may be thrown */
|
||||
FC_DECLARE_EXCEPTION( invalidOperation_exception, "Invalid Operation" );
|
||||
|
||||
/**
|
||||
* @brief used to report a canceled Operation
|
||||
*/
|
||||
FC_DECLARE_EXCEPTION( canceled_exception, "Canceled" );
|
||||
/**
|
||||
* @brief used inplace of assert() to report violations of pre conditions.
|
||||
*/
|
||||
FC_DECLARE_EXCEPTION( assert_exception, "Assert Exception" );
|
||||
FC_DECLARE_EXCEPTION( eof_exception, "End Of File" );
|
||||
|
||||
fc::string except_str();
|
||||
|
||||
|
||||
} // namespace fc
|
||||
/**
|
||||
* @brief Checks a condition and throws an assert_exception if the test is FALSE
|
||||
*/
|
||||
#define FC_ASSERT( TEST, ... ) \
|
||||
if( !(TEST) ) { FC_THROW_EXCEPTION( assert_exception, #TEST __VA_ARGS__ ); }
|
||||
|
||||
#define FC_THROW( FORMAT, ... ) \
|
||||
throw fc::exception( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) )
|
||||
|
||||
#define FC_EXCEPTION( EXCEPTION_TYPE, FORMAT, ... ) \
|
||||
fc::EXCEPTION_TYPE( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) )
|
||||
/**
|
||||
* @def FC_THROW_EXCEPTION( EXCEPTION, FORMAT, ... )
|
||||
* @param EXCEPTION a class in the Phoenix::Athena::API namespace that inherits
|
||||
* @param format - a const char* string with "${keys}"
|
||||
*/
|
||||
#define FC_THROW_EXCEPTION( EXCEPTION, FORMAT, ... ) \
|
||||
throw fc::EXCEPTION( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) )
|
||||
|
||||
|
||||
/**
|
||||
* @def FC_RETHROW_EXCEPTION(ER,LOG_LEVEL,FORMAT,...)
|
||||
* @brief Appends a log_message to the exception ER and rethrows it.
|
||||
*/
|
||||
#define FC_RETHROW_EXCEPTION( ER, LOG_LEVEL, FORMAT, ... ) \
|
||||
do { \
|
||||
er.append_log( FC_LOG_MESSAGE( LOG_LEVEL, FORMAT, __VA_ARGS__ ) ); \
|
||||
throw;\
|
||||
} while(false)
|
||||
|
||||
/**
|
||||
* @def FC_RETHROW_EXCEPTIONS(LOG_LEVEL,FORMAT,...)
|
||||
* @brief Catchs all exception's, std::exceptions, and ... and rethrows them after
|
||||
* appending the provided log message.
|
||||
*/
|
||||
#define FC_RETHROW_EXCEPTIONS( LOG_LEVEL, FORMAT, ... ) \
|
||||
catch( fc::exception& er ) { \
|
||||
FC_RETHROW_EXCEPTION( er, LOG_LEVEL, FORMAT, __VA_ARGS__ ); \
|
||||
} catch( const std::exception& e ) { \
|
||||
throw fc::std_exception( \
|
||||
FC_LOG_MESSAGE( LOG_LEVEL, FORMAT,__VA_ARGS__), \
|
||||
std::current_exception(), \
|
||||
e.what() ) ; \
|
||||
} catch( ... ) { \
|
||||
throw fc::unhandled_exception( \
|
||||
FC_LOG_MESSAGE( LOG_LEVEL, FORMAT,__VA_ARGS__), \
|
||||
std::current_exception() ); \
|
||||
}
|
||||
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#include <utility>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/typename.hpp>
|
||||
#include <fc/reflect/typename.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
|
@ -60,6 +62,9 @@ namespace fc {
|
|||
|
||||
bool is_relative()const;
|
||||
bool is_absolute()const;
|
||||
|
||||
static char separator_char;
|
||||
|
||||
private:
|
||||
fwd<boost::filesystem::path,32> _p;
|
||||
};
|
||||
|
|
@ -104,20 +109,64 @@ namespace fc {
|
|||
void create_directories( const path& p );
|
||||
void remove_all( const path& p );
|
||||
path absolute( const path& p );
|
||||
path make_relative(const path& from, const path& to);
|
||||
path canonical( const path& p );
|
||||
uint64_t file_size( const path& p );
|
||||
bool remove( const path& p );
|
||||
void copy( const path& from, const path& to );
|
||||
void rename( const path& from, const path& to );
|
||||
|
||||
void create_hard_link( const path& from, const path& to );
|
||||
|
||||
path unique_path();
|
||||
path temp_directory_path();
|
||||
|
||||
class value;
|
||||
void pack( fc::value& , const fc::path& );
|
||||
void unpack( const fc::value& , fc::path& );
|
||||
class variant;
|
||||
void to_variant( const fc::path&, fc::variant& );
|
||||
void from_variant( const fc::variant& , fc::path& );
|
||||
|
||||
template<> struct get_typename<path> { static const char* name() { return "path"; } };
|
||||
|
||||
/**
|
||||
* Class which creates a temporary directory inside an existing temporary directory.
|
||||
*/
|
||||
class temp_file_base
|
||||
{
|
||||
public:
|
||||
inline ~temp_file_base() { remove(); }
|
||||
inline operator bool() const { return _path; }
|
||||
inline bool operator!() const { return !_path; }
|
||||
const fc::path& path() const;
|
||||
void remove();
|
||||
void release();
|
||||
protected:
|
||||
typedef fc::optional<fc::path> path_t;
|
||||
inline temp_file_base(const path_t& path) : _path(path) {}
|
||||
inline temp_file_base(path_t&& path) : _path(std::move(path)) {}
|
||||
path_t _path;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class which creates a temporary directory inside an existing temporary directory.
|
||||
*/
|
||||
class temp_file : public temp_file_base
|
||||
{
|
||||
public:
|
||||
temp_file(temp_file&& other);
|
||||
temp_file& operator=(temp_file&& other);
|
||||
temp_file(const fc::path& tempFolder = fc::temp_directory_path(), bool create = false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Class which creates a temporary directory inside an existing temporary directory.
|
||||
*/
|
||||
class temp_directory : public temp_file_base
|
||||
{
|
||||
public:
|
||||
temp_directory(temp_directory&& other);
|
||||
temp_directory& operator=(temp_directory&& other);
|
||||
temp_directory(const fc::path& tempFolder = fc::temp_directory_path());
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
#if 0
|
||||
#pragma once
|
||||
#include <fc/utility.hpp>
|
||||
#include <fc/shared_ptr.hpp>
|
||||
namespace fc {
|
||||
template<typename R,typename ... Args>
|
||||
class function {
|
||||
public:
|
||||
function(){}
|
||||
|
||||
template<typename Functor>
|
||||
function( Functor&& f )
|
||||
:func( new impl<Functor>( fc::forward<Functor>(f) ) ){};
|
||||
|
||||
function( const function& c ):func(c.func){}
|
||||
function( function&& c ) { fc::swap( func, c.func); }
|
||||
~function(){}
|
||||
|
||||
template<typename Functor>
|
||||
function& operator=( Functor&& f ) {
|
||||
func.reset( new impl<Functor>( fc::forward<Functor>(f) ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
function& operator=( const function& c ) { func = c.func; return *this; }
|
||||
function& operator=( function&& c ) { fc::swap(func,c.func); return *this; }
|
||||
|
||||
R operator()( Args... args)const { return func->call(args...); }
|
||||
|
||||
bool operator!()const { return !func; }
|
||||
|
||||
protected:
|
||||
|
||||
struct impl_base : public fc::retainable {
|
||||
virtual ~impl_base(){}
|
||||
virtual R call(Args...)const = 0;
|
||||
};
|
||||
|
||||
template<typename Functor>
|
||||
struct impl : impl_base {
|
||||
template<typename U>
|
||||
impl( U&& u ):func( fc::forward<U>(u) ){}
|
||||
|
||||
virtual R call(Args... args)const { return func(args...); }
|
||||
|
||||
Functor func;
|
||||
};
|
||||
function( const fc::shared_ptr<impl_base>& f ):func(f){}
|
||||
function( fc::shared_ptr<impl_base>&& f ):func(fc::move(f)){}
|
||||
|
||||
fc::shared_ptr<impl_base> func;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides functionality similar to boost::function.
|
||||
*
|
||||
* Functions have 'reference semantics', meaning that copies will all
|
||||
* refer to the same underlying function.
|
||||
*
|
||||
* TODO: Small functions are allocated on the stack, large functors are
|
||||
* allocated on the heap.
|
||||
*
|
||||
* Simply including boost/function adds an additional 0.6 seconds to every
|
||||
* object file compared to using fc/function.
|
||||
*
|
||||
* Including <functional> on the other hand adds a mere 0.05
|
||||
* seconds to every object file compared to fc/function.
|
||||
*/
|
||||
template<typename R>
|
||||
class function<R()> : public function<R> {
|
||||
public:
|
||||
function(){}
|
||||
template<typename U>
|
||||
function( U&& u ) { *this = fc::forward<U>(u); }
|
||||
using function<R>::operator=;
|
||||
};
|
||||
|
||||
template<typename R,typename A1>
|
||||
class function<R(A1)> : public function<R,A1> {
|
||||
public:
|
||||
function(){}
|
||||
function( const function<R,A1>& u ):function<R,A1>(u){}
|
||||
function( function<R,A1>&& u ):function<R,A1>(u){}
|
||||
function( const function& u ):function<R,A1>(u.func){}
|
||||
function( function&& u ):function<R,A1>(fc::move(u.func)){}
|
||||
|
||||
using function<R,A1>::operator=;
|
||||
};
|
||||
|
||||
template<typename R,typename A1,typename A2>
|
||||
class function<R(A1,A2)> : public function<R,A1,A2> {
|
||||
public:
|
||||
function(){}
|
||||
template<typename U>
|
||||
function( U&& u ):function<R,A1,A2>( fc::forward<U>(u) ){}
|
||||
function( const function& c ):function<R,A1,A2>(c.func){}
|
||||
using function<R,A1,A2>::operator=;
|
||||
};
|
||||
|
||||
template<typename R,typename A1,typename A2, typename A3>
|
||||
class function<R(A1,A2,A3)> : public function<R,A1,A2,A3> {
|
||||
public:
|
||||
function(){}
|
||||
template<typename U>
|
||||
function( U&& u ):function<R,A1,A2,A3>( fc::forward<U>(u) ){}
|
||||
function( const function& c ):function<R,A1,A2,A3>(c.func){}
|
||||
using function<R,A1,A2,A3>::operator=;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef _FC_FWD_IMPL_HPP_
|
||||
#define _FC_FWD_IMPL_HPP_
|
||||
#pragma once
|
||||
|
||||
#include <fc/utility.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
|
|
@ -134,4 +133,3 @@ namespace fc {
|
|||
|
||||
} // namespace fc
|
||||
|
||||
#endif //_FC_FWD_IMPL_HPP_
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef _FC_FWD_REFLECT_HPP_
|
||||
#define _FC_FWD_REFLECT_HPP_
|
||||
#include <fc/reflect.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
|
||||
namespace fc {
|
||||
template<typename T,unsigned int S>
|
||||
class reflector<fwd<T,S>> : public detail::reflector_impl<fwd<T,S>, reflector<fwd<T,S>> >{
|
||||
public:
|
||||
virtual const char* name()const { return instance().name(); }
|
||||
virtual void visit( void* s, const abstract_visitor& v )const {
|
||||
instance().visit(s,v);
|
||||
}
|
||||
virtual void visit( const void* s, const abstract_const_visitor& v )const {
|
||||
instance().visit(s,v);
|
||||
}
|
||||
|
||||
static reflector<T>& instance() { return reflector<T>::instance(); }
|
||||
};
|
||||
} // namespace fc
|
||||
#endif //_FC_FWD_REFLECT_HPP_
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/shared_impl.hpp>
|
||||
|
||||
namespace fc {
|
||||
namespace ip { class endpoint; }
|
||||
class tcp_socket;
|
||||
|
||||
namespace http {
|
||||
|
||||
struct header {
|
||||
header( fc::string k, fc::string v )
|
||||
:key(fc::move(k)),val(fc::move(v)){}
|
||||
header(){}
|
||||
fc::string key;
|
||||
fc::string val;
|
||||
};
|
||||
|
||||
struct reply {
|
||||
enum status_code {
|
||||
OK = 200,
|
||||
RecordCreated = 201,
|
||||
NotFound = 404,
|
||||
Found = 302,
|
||||
InternalServerError = 500
|
||||
};
|
||||
reply( status_code c = OK):status(c){}
|
||||
int status;
|
||||
fc::vector<header> headers;
|
||||
fc::vector<char> body;
|
||||
};
|
||||
|
||||
struct request {
|
||||
fc::string get_header( const fc::string& key )const;
|
||||
fc::string method;
|
||||
fc::string domain;
|
||||
fc::string path;
|
||||
fc::vector<header> headers;
|
||||
fc::vector<char> body;
|
||||
};
|
||||
|
||||
fc::vector<header> parse_urlencoded_params( const fc::string& f );
|
||||
|
||||
/**
|
||||
* Connections have reference semantics, all copies refer to the same
|
||||
* underlying socket.
|
||||
*/
|
||||
class connection {
|
||||
public:
|
||||
// used for clients
|
||||
void connect_to( const fc::ip::endpoint& ep );
|
||||
http::reply request( const fc::string& method, const fc::string& url, const fc::string& body );
|
||||
|
||||
// used for servers
|
||||
fc::tcp_socket& get_socket()const;
|
||||
|
||||
http::request read_request()const;
|
||||
|
||||
FC_REFERENCE_TYPE(connection)
|
||||
};
|
||||
|
||||
} } // fc::http
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ namespace fc {
|
|||
};
|
||||
class mapped_region {
|
||||
public:
|
||||
mapped_region( const file_mapping& fm, mode_t m, size_t start, size_t size );
|
||||
mapped_region( const file_mapping& fm, mode_t m, uint64_t start, size_t size );
|
||||
mapped_region( const file_mapping& fm, mode_t m );
|
||||
~mapped_region();
|
||||
void flush();
|
||||
|
|
|
|||
66
include/fc/interprocess/iprocess.hpp
Normal file
66
include/fc/interprocess/iprocess.hpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
#include <fc/thread/future.hpp>
|
||||
#include <fc/io/buffered_iostream.hpp>
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/filesystem.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
/**
|
||||
* @brief abstract interface for interacting with external processes
|
||||
*
|
||||
* At the very least we have ssh::process and direct child processes, and
|
||||
* there may be other processes that need to implement this protocol.
|
||||
*/
|
||||
class iprocess
|
||||
{
|
||||
public:
|
||||
enum exec_opts {
|
||||
open_none = 0,
|
||||
open_stdin = 0x01,
|
||||
open_stdout = 0x02,
|
||||
open_stderr = 0x04,
|
||||
open_all = open_stdin|open_stdout|open_stderr,
|
||||
};
|
||||
|
||||
virtual ~iprocess(){}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return *this
|
||||
*/
|
||||
virtual iprocess& exec( const fc::path& exe, vector<string> args,
|
||||
const fc::path& work_dir = fc::path(), exec_opts opts = open_all ) = 0;
|
||||
|
||||
/**
|
||||
* @return blocks until the process exits
|
||||
*/
|
||||
virtual int result() = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Forcefully kills the process.
|
||||
*/
|
||||
virtual void kill() = 0;
|
||||
|
||||
/**
|
||||
* @brief returns a stream that writes to the process' stdin
|
||||
*/
|
||||
virtual fc::buffered_ostream_ptr in_stream() = 0;
|
||||
|
||||
/**
|
||||
* @brief returns a stream that reads from the process' stdout
|
||||
*/
|
||||
virtual fc::buffered_istream_ptr out_stream() = 0;
|
||||
/**
|
||||
* @brief returns a stream that reads from the process' stderr
|
||||
*/
|
||||
virtual fc::buffered_istream_ptr err_stream() = 0;
|
||||
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<iprocess> iprocess_ptr;
|
||||
|
||||
|
||||
} // namespace fc
|
||||
36
include/fc/interprocess/process.hpp
Normal file
36
include/fc/interprocess/process.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#include <fc/interprocess/iprocess.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
fc::path find_executable_in_path( const fc::string name );
|
||||
|
||||
/**
|
||||
* @brief start and manage an local process
|
||||
* @note this class implements reference semantics.
|
||||
*/
|
||||
class process : public iprocess
|
||||
{
|
||||
public:
|
||||
process();
|
||||
~process();
|
||||
|
||||
virtual iprocess& exec( const fc::path& exe,
|
||||
vector<string> args,
|
||||
const fc::path& work_dir = fc::path(),
|
||||
exec_opts opts = open_all );
|
||||
|
||||
virtual int result();
|
||||
virtual void kill();
|
||||
virtual fc::buffered_ostream_ptr in_stream();
|
||||
virtual fc::buffered_istream_ptr out_stream();
|
||||
virtual fc::buffered_istream_ptr err_stream();
|
||||
|
||||
class impl;
|
||||
private:
|
||||
std::unique_ptr<impl> my;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<process> process_ptr;
|
||||
|
||||
} // namespace fc
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
#ifndef _FC_INVOKEABLE_HPP_
|
||||
#define _FC_INVOKEABLE_HPP_
|
||||
|
||||
namespace fc {
|
||||
|
||||
class invokeable {
|
||||
public:
|
||||
virtual ~invokeable(){};
|
||||
|
||||
virtual void invoke( const promise::ptr& prom, const string& name, size_t num_params, reflect::cref* params );
|
||||
|
||||
void invoke( const std::string& name ) { invoke( promise::ptr(), name, 0, 0 ); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // _FC_INVOKEABLE_HPP_
|
||||
13
include/fc/io/base16.hpp
Normal file
13
include/fc/io/base16.hpp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/utility.hpp>
|
||||
|
||||
namespace fc {
|
||||
uint8_t from_hex( char c );
|
||||
fc::string to_hex( const char* d, uint32_t s );
|
||||
|
||||
/**
|
||||
* @return the number of bytes decoded
|
||||
*/
|
||||
size_t from_hex( const fc::string& hex_str, char* out_data, size_t out_data_len );
|
||||
}
|
||||
8
include/fc/io/base58.hpp
Normal file
8
include/fc/io/base58.hpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc {
|
||||
fc::string to_base58( const char* d, size_t s );
|
||||
fc::vector<char> from_base58( const fc::string& base58_str );
|
||||
size_t from_base58( const fc::string& base58_str, char* out_data, size_t out_data_len );
|
||||
}
|
||||
71
include/fc/io/buffered_iostream.hpp
Normal file
71
include/fc/io/buffered_iostream.hpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#pragma once
|
||||
#include <fc/io/iostream.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class buffered_istream_impl;
|
||||
class buffered_ostream_impl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads data from an unbuffered stream
|
||||
* and enables peek functionality.
|
||||
*/
|
||||
class buffered_istream : public virtual istream
|
||||
{
|
||||
public:
|
||||
buffered_istream( istream_ptr is );
|
||||
buffered_istream( buffered_istream&& o );
|
||||
|
||||
buffered_istream& operator=( buffered_istream&& i );
|
||||
|
||||
virtual ~buffered_istream();
|
||||
|
||||
/** read at least 1 byte or throw, if no data is available
|
||||
* this method should block cooperatively until data is
|
||||
* available or fc::eof_exception is thrown.
|
||||
*
|
||||
* @pre len > 0
|
||||
* @pre buf != nullptr
|
||||
* @throws fc::eof if at least 1 byte cannot be read
|
||||
**/
|
||||
virtual std::size_t readsome( char* buf, std::size_t len );
|
||||
|
||||
/**
|
||||
* This method may block until at least 1 character is
|
||||
* available.
|
||||
*/
|
||||
char peek()const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<detail::buffered_istream_impl> my;
|
||||
};
|
||||
typedef std::shared_ptr<buffered_istream> buffered_istream_ptr;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class buffered_ostream : public virtual ostream
|
||||
{
|
||||
public:
|
||||
buffered_ostream( ostream_ptr o, size_t bufsize = 4096 );
|
||||
buffered_ostream( buffered_ostream&& m );
|
||||
~buffered_ostream();
|
||||
|
||||
buffered_ostream& operator=( buffered_ostream&& m );
|
||||
/**
|
||||
* This method will return immediately unless the buffer
|
||||
* is full, in which case it will flush which may block.
|
||||
*/
|
||||
virtual size_t writesome( const char* buf, size_t len );
|
||||
|
||||
virtual void close();
|
||||
virtual void flush();
|
||||
private:
|
||||
std::unique_ptr<detail::buffered_ostream_impl> my;
|
||||
};
|
||||
typedef std::shared_ptr<buffered_ostream> buffered_ostream_ptr;
|
||||
}
|
||||
182
include/fc/io/datastream.hpp
Normal file
182
include/fc/io/datastream.hpp
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
#pragma once
|
||||
#include <fc/utility.hpp>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace fc {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
NO_RETURN void throw_datastream_range_error( const char* file, size_t len, size_t over );
|
||||
}
|
||||
|
||||
/**
|
||||
* The purpose of this datastream is to provide a fast, effecient, means
|
||||
* of calculating the amount of data "about to be written" and then
|
||||
* writing it. This means having two modes of operation, "test run" where
|
||||
* you call the entire pack sequence calculating the size, and then
|
||||
* actually packing it after doing a single allocation.
|
||||
*/
|
||||
template<typename T>
|
||||
class datastream {
|
||||
public:
|
||||
datastream( T start, size_t s )
|
||||
:_start(start),_pos(start),_end(start+s){};
|
||||
|
||||
|
||||
inline void skip( size_t s ){ _pos += s; }
|
||||
inline bool read( char* d, size_t s ) {
|
||||
if( size_t(_end - _pos) >= (size_t)s ) {
|
||||
memcpy( d, _pos, s );
|
||||
_pos += s;
|
||||
return true;
|
||||
}
|
||||
detail::throw_datastream_range_error( "read", _end-_start, int64_t(-((_end-_pos) - 1)));
|
||||
}
|
||||
|
||||
inline bool write( const char* d, size_t s ) {
|
||||
if( _end - _pos >= (int32_t)s ) {
|
||||
memcpy( _pos, d, s );
|
||||
_pos += s;
|
||||
return true;
|
||||
}
|
||||
detail::throw_datastream_range_error( "write", _end-_start, int64_t(-((_end-_pos) - 1)));
|
||||
}
|
||||
|
||||
inline bool put(char c) {
|
||||
if( _pos < _end ) {
|
||||
*_pos = c;
|
||||
++_pos;
|
||||
return true;
|
||||
}
|
||||
detail::throw_datastream_range_error( "put", _end-_start, int64_t(-((_end-_pos) - 1)));
|
||||
}
|
||||
|
||||
inline bool get( unsigned char& c ) { return get( *(char*)&c ); }
|
||||
inline bool get( char& c )
|
||||
{
|
||||
if( _pos < _end ) {
|
||||
c = *_pos;
|
||||
++_pos;
|
||||
return true;
|
||||
}
|
||||
detail::throw_datastream_range_error( "get", _end-_start, int64_t(-((_end-_pos) - 1)));
|
||||
}
|
||||
|
||||
T pos()const { return _pos; }
|
||||
inline bool valid()const { return _pos <= _end && _pos >= _start; }
|
||||
inline bool seekp(size_t p) { _pos = _start + p; return _pos <= _end; }
|
||||
inline size_t tellp()const { return _pos - _start; }
|
||||
inline size_t remaining()const { return _end - _pos; }
|
||||
private:
|
||||
T _start;
|
||||
T _pos;
|
||||
T _end;
|
||||
};
|
||||
|
||||
template<>
|
||||
class datastream<size_t> {
|
||||
public:
|
||||
datastream( size_t init_size = 0):_size(init_size){};
|
||||
inline bool skip( size_t s ) { _size += s; return true; }
|
||||
inline bool write( const char* ,size_t s ) { _size += s; return true; }
|
||||
inline bool put(char ) { ++_size; return true; }
|
||||
inline bool valid()const { return true; }
|
||||
inline bool seekp(size_t p) { _size = p; return true; }
|
||||
inline size_t tellp()const { return _size; }
|
||||
inline size_t remaining()const { return 0; }
|
||||
private:
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int32_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int32_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint32_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint32_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int64_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int64_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint64_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint64_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int16_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int16_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint16_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint16_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int8_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, int8_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const uint8_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, uint8_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
#include <fc/utility.hpp>
|
||||
#include <fc/error_report.hpp>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
@ -14,96 +13,78 @@ namespace fc {
|
|||
* actually packing it after doing a single allocation.
|
||||
*/
|
||||
template<typename T>
|
||||
struct datastream {
|
||||
class datastream {
|
||||
public:
|
||||
datastream( T start, size_t s )
|
||||
:m_start(start),m_pos(start),m_end(start+s){};
|
||||
:_start(start),_pos(start),_end(start+s){};
|
||||
|
||||
|
||||
inline void skip( size_t s ){ m_pos += s; }
|
||||
inline void skip( size_t s ){ _pos += s; }
|
||||
inline bool read( char* d, size_t s ) {
|
||||
if( size_t(m_end - m_pos) >= (size_t)s ) {
|
||||
memcpy( d, m_pos, s );
|
||||
m_pos += s;
|
||||
if( size_t(_end - _pos) >= (size_t)s ) {
|
||||
memcpy( d, _pos, s );
|
||||
_pos += s;
|
||||
return true;
|
||||
}
|
||||
FC_THROW_REPORT( "Attempt to read ${bytes_past} bytes beyond end of buffer with size ${buffer_size} ",
|
||||
fc::value("bytes_past",int64_t(-((m_end-m_pos) - s)))
|
||||
("buffer_size", int64_t(m_end-m_start)) );
|
||||
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool write( const char* d, size_t s ) {
|
||||
if( m_end - m_pos >= (int32_t)s ) {
|
||||
memcpy( m_pos, d, s );
|
||||
m_pos += s;
|
||||
if( _end - _pos >= (int32_t)s ) {
|
||||
memcpy( _pos, d, s );
|
||||
_pos += s;
|
||||
return true;
|
||||
}
|
||||
FC_THROW_REPORT( "Attempt to write ${bytes_past} bytes beyond end of buffer with size ${buffer_size} ",
|
||||
fc::value("bytes_past",int64_t(-((m_end-m_pos) - s)))
|
||||
("buffer_size", int64_t(m_end-m_start)) );
|
||||
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool put(char c) {
|
||||
if( m_pos < m_end ) {
|
||||
*m_pos = c;
|
||||
++m_pos;
|
||||
if( _pos < _end ) {
|
||||
*_pos = c;
|
||||
++_pos;
|
||||
return true;
|
||||
}
|
||||
FC_THROW_REPORT( "Attempt to write ${bytes_past} bytes beyond end of buffer with size ${buffer_size} ",
|
||||
fc::value("bytes_past",int64_t(-((m_end-m_pos) - 1)))
|
||||
("buffer_size", int64_t(m_end-m_start)) );
|
||||
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
|
||||
}
|
||||
|
||||
inline bool get( unsigned char& c ) { return get( *(char*)&c ); }
|
||||
inline bool get( char& c ) {
|
||||
if( m_pos < m_end ) {
|
||||
c = *m_pos;
|
||||
++m_pos;
|
||||
if( _pos < _end ) {
|
||||
c = *_pos;
|
||||
++_pos;
|
||||
return true;
|
||||
}
|
||||
FC_THROW_REPORT( "Attempt to read ${bytes_past} bytes beyond end of buffer of size ${buffer_size} ",
|
||||
fc::value("bytes_past",int64_t(-((m_end-m_pos) - 1)))
|
||||
("buffer_size", int64_t(m_end-m_start)) );
|
||||
detail::throw_datastream_range_error( _end-start, int64_t(-((_end-_pos) - 1)))
|
||||
}
|
||||
|
||||
T pos()const { return m_pos; }
|
||||
inline bool valid()const { return m_pos <= m_end && m_pos >= m_start; }
|
||||
inline bool seekp(size_t p) { m_pos = m_start + p; return m_pos <= m_end; }
|
||||
inline size_t tellp()const { return m_pos - m_start; }
|
||||
inline size_t remaining()const { return m_end - m_pos; }
|
||||
T pos()const { return _pos; }
|
||||
inline bool valid()const { return _pos <= _end && _pos >= _start; }
|
||||
inline bool seekp(size_t p) { _pos = _start + p; return _pos <= _end; }
|
||||
inline size_t tellp()const { return _pos - _start; }
|
||||
inline size_t remaining()const { return _end - _pos; }
|
||||
private:
|
||||
T m_start;
|
||||
T m_pos;
|
||||
T m_end;
|
||||
T _start;
|
||||
T _pos;
|
||||
T _end;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct datastream<size_t> {
|
||||
datastream( size_t init_size = 0):m_size(init_size){};
|
||||
inline bool skip( size_t s ) { m_size += s; return true; }
|
||||
inline bool write( const char* d,size_t s ) { m_size += s; return true; }
|
||||
inline bool put(char c) { ++m_size; return true; }
|
||||
inline bool valid()const { return true; }
|
||||
inline bool seekp(size_t p) { m_size = p; return true; }
|
||||
inline size_t tellp()const { return m_size; }
|
||||
inline size_t remaining()const { return 0; }
|
||||
private:
|
||||
size_t m_size;
|
||||
class datastream<size_t> {
|
||||
public:
|
||||
datastream( size_t init_size = 0):_size(init_size){};
|
||||
inline bool skip( size_t s ) { _size += s; return true; }
|
||||
inline bool write( const char* d,size_t s ) { _size += s; return true; }
|
||||
inline bool put(char c) { ++_size; return true; }
|
||||
inline bool valid()const { return true; }
|
||||
inline bool seekp(size_t p) { _size = p; return true; }
|
||||
inline size_t tellp()const { return _size; }
|
||||
inline size_t remaining()const { return 0; }
|
||||
private:
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
/*
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const size_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
return *this;
|
||||
}
|
||||
template<typename ST, typename DATA>
|
||||
inline datastream<ST>& operator>>(datastream<ST>& ds, size_t& d) {
|
||||
ds.read((char*)&d, sizeof(d) );
|
||||
return *this;
|
||||
}
|
||||
*/
|
||||
template<typename ST>
|
||||
inline datastream<ST>& operator<<(datastream<ST>& ds, const int32_t& d) {
|
||||
ds.write( (const char*)&d, sizeof(d) );
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
#include <fc/shared_ptr.hpp>
|
||||
#include <fc/filesystem.hpp>
|
||||
#include <fc/iostream.hpp>
|
||||
#include <fc/io/iostream.hpp>
|
||||
|
||||
namespace fc {
|
||||
class path;
|
||||
|
|
@ -13,7 +13,7 @@ namespace fc {
|
|||
~ofstream();
|
||||
|
||||
void open( const fc::path& file, int m = binary );
|
||||
ofstream& write( const char* buf, size_t len );
|
||||
size_t writesome( const char* buf, size_t len );
|
||||
void put( char c );
|
||||
void close();
|
||||
void flush();
|
||||
81
include/fc/io/iobuffer.hpp
Normal file
81
include/fc/io/iobuffer.hpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#pragma once
|
||||
#include <fc/io/iostream.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
/**
|
||||
* Records the size, but discards the data.
|
||||
*/
|
||||
class size_stream : public virtual fc::ostream
|
||||
{
|
||||
public:
|
||||
size_stream( size_t s = 0):_size(s){}
|
||||
|
||||
size_t size()const { return _size; }
|
||||
size_t seek( size_t pos ) { return _size = pos; }
|
||||
|
||||
virtual size_t writesome( const char* /*ignored buf*/, size_t len )
|
||||
{
|
||||
_size += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
virtual void close(){}
|
||||
virtual void flush(){}
|
||||
|
||||
private:
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
|
||||
class iobuffer : public virtual fc::iostream
|
||||
{
|
||||
public:
|
||||
iobuffer( size_t s )
|
||||
:_data(s){}
|
||||
|
||||
size_t size()const { return _data.size(); }
|
||||
size_t pos()const { return _pos; }
|
||||
size_t seek( size_t pos )
|
||||
{
|
||||
return _pos = std::min<size_t>(_data.size(),pos);
|
||||
}
|
||||
|
||||
virtual size_t readsome( char* buf, size_t len )
|
||||
{
|
||||
auto avail = std::min<size_t>( _data.size()-_pos, len );
|
||||
if( avail == 0 ) throw fc::eof_exception();
|
||||
memcpy( buf, _data.data()+_pos, avail );
|
||||
_pos += avail;
|
||||
return avail;
|
||||
}
|
||||
/**
|
||||
* This method may block until at least 1 character is
|
||||
* available.
|
||||
*/
|
||||
char peek()const
|
||||
{
|
||||
if( _pos == _data.size() ) throw fc::eof_exception();
|
||||
return _data[_pos];
|
||||
}
|
||||
|
||||
virtual size_t writesome( const char* buf, size_t len )
|
||||
{
|
||||
auto avail = std::max<size_t>( _data.size(), _pos + len );
|
||||
_data.resize(avail);
|
||||
memcpy( _data.data()+_pos, buf, len );
|
||||
_pos += avail;
|
||||
return avail;
|
||||
}
|
||||
char* data() { return _data.data(); }
|
||||
|
||||
virtual void close(){}
|
||||
virtual void flush(){}
|
||||
|
||||
private:
|
||||
std::vector<char> _data;
|
||||
size_t _pos;
|
||||
};
|
||||
|
||||
}
|
||||
98
include/fc/io/iostream.hpp
Normal file
98
include/fc/io/iostream.hpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#pragma once
|
||||
#include <fc/utility.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace fc {
|
||||
|
||||
/**
|
||||
* Provides a fc::thread friendly cooperatively multi-tasked stream that
|
||||
* will block 'cooperatively' instead of hard blocking.
|
||||
*/
|
||||
class istream
|
||||
{
|
||||
public:
|
||||
virtual ~istream(){};
|
||||
|
||||
/** read at least 1 byte or throw, if no data is available
|
||||
* this method should block cooperatively until data is
|
||||
* available or fc::eof is thrown.
|
||||
*
|
||||
* @throws fc::eof if at least 1 byte cannot be read
|
||||
**/
|
||||
virtual size_t readsome( char* buf, size_t len ) = 0;
|
||||
|
||||
/** read len bytes or throw, this method is implemented
|
||||
* in terms of readsome.
|
||||
*
|
||||
* @throws fc::eof_exception if len bytes cannot be read
|
||||
**/
|
||||
istream& read( char* buf, size_t len );
|
||||
char get();
|
||||
};
|
||||
typedef std::shared_ptr<istream> istream_ptr;
|
||||
|
||||
/**
|
||||
* Provides a fc::thread friendly cooperatively multi-tasked stream that
|
||||
* will block 'cooperatively' instead of hard blocking.
|
||||
*/
|
||||
class ostream
|
||||
{
|
||||
public:
|
||||
virtual ~ostream(){};
|
||||
virtual size_t writesome( const char* buf, size_t len ) = 0;
|
||||
virtual void close() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
void put( char c ) { write(&c,1); }
|
||||
|
||||
/** implemented in terms of writesome, guarantees len bytes are sent
|
||||
* but not flushed.
|
||||
**/
|
||||
ostream& write( const char* buf, size_t len );
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<ostream> ostream_ptr;
|
||||
|
||||
class iostream : public virtual ostream, public virtual istream {};
|
||||
|
||||
fc::istream& getline( fc::istream&, fc::string&, char delim = '\n' );
|
||||
|
||||
template<size_t N>
|
||||
ostream& operator<<( ostream& o, char (&array)[N] )
|
||||
{
|
||||
return o.write( array, N );
|
||||
}
|
||||
|
||||
ostream& operator<<( ostream& o, char );
|
||||
ostream& operator<<( ostream& o, const char* v );
|
||||
ostream& operator<<( ostream& o, const std::string& v );
|
||||
ostream& operator<<( ostream& o, const fc::string& v );
|
||||
ostream& operator<<( ostream& o, const double& v );
|
||||
ostream& operator<<( ostream& o, const float& v );
|
||||
ostream& operator<<( ostream& o, const int64_t& v );
|
||||
ostream& operator<<( ostream& o, const uint64_t& v );
|
||||
ostream& operator<<( ostream& o, const int32_t& v );
|
||||
ostream& operator<<( ostream& o, const uint32_t& v );
|
||||
ostream& operator<<( ostream& o, const int16_t& v );
|
||||
ostream& operator<<( ostream& o, const uint16_t& v );
|
||||
ostream& operator<<( ostream& o, const int8_t& v );
|
||||
ostream& operator<<( ostream& o, const uint8_t& v );
|
||||
#ifndef _MSC_VER
|
||||
ostream& operator<<( ostream& o, const size_t& v );
|
||||
#endif
|
||||
|
||||
istream& operator>>( istream& o, std::string& v );
|
||||
istream& operator>>( istream& o, fc::string& v );
|
||||
istream& operator>>( istream& o, char& v );
|
||||
istream& operator>>( istream& o, double& v );
|
||||
istream& operator>>( istream& o, float& v );
|
||||
istream& operator>>( istream& o, int64_t& v );
|
||||
istream& operator>>( istream& o, uint64_t& v );
|
||||
istream& operator>>( istream& o, int32_t& v );
|
||||
istream& operator>>( istream& o, uint32_t& v );
|
||||
istream& operator>>( istream& o, int16_t& v );
|
||||
istream& operator>>( istream& o, uint16_t& v );
|
||||
istream& operator>>( istream& o, int8_t& v );
|
||||
istream& operator>>( istream& o, uint8_t& v );
|
||||
}
|
||||
56
include/fc/io/json.hpp
Normal file
56
include/fc/io/json.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
#include <fc/variant.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
class path;
|
||||
class ostream;
|
||||
class buffered_istream;
|
||||
|
||||
/**
|
||||
* Provides interface for json serialization.
|
||||
*
|
||||
* json strings are always UTF8
|
||||
*/
|
||||
class json
|
||||
{
|
||||
public:
|
||||
static ostream& to_stream( ostream& out, const fc::string& );
|
||||
static ostream& to_stream( ostream& out, const variant& v );
|
||||
static ostream& to_stream( ostream& out, const variants& v );
|
||||
static ostream& to_stream( ostream& out, const variant_object& v );
|
||||
|
||||
static variant from_stream( buffered_istream& in );
|
||||
|
||||
static variant from_string( const string& utf8_str );
|
||||
static string to_string( const variant& v );
|
||||
static string to_pretty_string( const variant& v );
|
||||
static void save_to_file( const variant& v, const string& fi, bool pretty = true );
|
||||
static variant from_file( const fc::path& p );
|
||||
|
||||
template<typename T>
|
||||
static T from_file( const fc::path& p )
|
||||
{
|
||||
return json::from_file(p).as<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static string to_string( const T& v )
|
||||
{
|
||||
return to_string( variant(v) );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static string to_pretty_string( const T& v )
|
||||
{
|
||||
return to_pretty_string( variant(v) );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void save_to_file( const T& v, const string& p, bool pretty = true )
|
||||
{
|
||||
save_to_file( variant(v), p, pretty );
|
||||
}
|
||||
};
|
||||
|
||||
} // fc
|
||||
|
|
@ -1,52 +1,55 @@
|
|||
#pragma once
|
||||
#include <fc/reflect.hpp>
|
||||
#include <fc/datastream.hpp>
|
||||
#include <fc/varint.hpp>
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
#include <fc/io/datastream.hpp>
|
||||
#include <fc/io/varint.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/array.hpp>
|
||||
#include <fc/time.hpp>
|
||||
#include <fc/io/raw_fwd.hpp>
|
||||
#include <fc/variant_object.hpp>
|
||||
#include <fc/variant.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
|
||||
namespace fc {
|
||||
class value;
|
||||
namespace raw {
|
||||
|
||||
template<typename Stream, typename T>
|
||||
void unpack( Stream& s, fc::optional<T>& v );
|
||||
template<typename Stream, typename T>
|
||||
void pack( Stream& s, const fc::optional<T>& v );
|
||||
template<typename Stream>
|
||||
inline void pack( Stream& s, const variant_object& v );
|
||||
template<typename Stream>
|
||||
inline void unpack( Stream& s, variant_object& v );
|
||||
|
||||
template<typename Stream>
|
||||
void unpack( Stream& s, fc::value& );
|
||||
inline void pack( Stream& s, const variant& v );
|
||||
template<typename Stream>
|
||||
void pack( Stream& s, const fc::value& );
|
||||
inline void unpack( Stream& s, variant& v );
|
||||
|
||||
template<typename Stream>
|
||||
void unpack( Stream& s, fc::string& );
|
||||
inline void pack( Stream& s, const fc::time_point& tp )
|
||||
{
|
||||
uint64_t usec = tp.time_since_epoch().count();
|
||||
s.write( (const char*)&usec, sizeof(usec) );
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void pack( Stream& s, const fc::string& );
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const T& v );
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, T& v );
|
||||
|
||||
template<typename Stream, typename T>
|
||||
inline void pack( Stream& s, const fc::vector<T>& v );
|
||||
template<typename Stream, typename T>
|
||||
inline void unpack( Stream& s, fc::vector<T>& v );
|
||||
|
||||
inline void unpack( Stream& s, fc::time_point& tp )
|
||||
{
|
||||
uint64_t usec;
|
||||
s.read( (char*)&usec, sizeof(usec) );
|
||||
tp = fc::time_point() + fc::microseconds(usec);
|
||||
}
|
||||
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void pack( Stream& s, const fc::array<T,N>& v) {
|
||||
s.write((const char*)&v.data[0],N*sizeof(T));
|
||||
}
|
||||
|
||||
template<typename Stream, typename T, size_t N>
|
||||
inline void unpack( Stream& s, fc::array<T,N>& v) {
|
||||
s.read((char*)&v.data[0],N*sizeof(T));
|
||||
}
|
||||
|
||||
template<typename Stream> inline void pack( Stream& s, const signed_int& v ) {
|
||||
uint32_t val = (v.value<<1) ^ (v.value>>31);
|
||||
do {
|
||||
|
|
@ -239,12 +242,152 @@ namespace fc {
|
|||
fc::raw::detail::if_reflected< typename fc::reflector<T>::is_defined >::unpack(s,v);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
class variant_packer : public variant::visitor
|
||||
{
|
||||
public:
|
||||
variant_packer( Stream& _s ):s(_s){}
|
||||
virtual void handle()const { }
|
||||
virtual void handle( const int64_t& v )const
|
||||
{
|
||||
fc::raw::pack( s, v );
|
||||
}
|
||||
virtual void handle( const uint64_t& v )const
|
||||
{
|
||||
fc::raw::pack( s, v );
|
||||
}
|
||||
virtual void handle( const double& v )const
|
||||
{
|
||||
fc::raw::pack( s, v );
|
||||
}
|
||||
virtual void handle( const bool& v )const
|
||||
{
|
||||
fc::raw::pack( s, v );
|
||||
}
|
||||
virtual void handle( const string& v )const
|
||||
{
|
||||
fc::raw::pack( s, v );
|
||||
}
|
||||
virtual void handle( const variant_object& v)const
|
||||
{
|
||||
fc::raw::pack( s, v );
|
||||
}
|
||||
virtual void handle( const variants& v)const
|
||||
{
|
||||
fc::raw::pack( s, v );
|
||||
}
|
||||
|
||||
Stream& s;
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<typename Stream>
|
||||
inline void pack( Stream& s, const variant& v )
|
||||
{
|
||||
pack( s, uint8_t(v.get_type()) );
|
||||
v.visit( variant_packer<Stream>(s) );
|
||||
}
|
||||
template<typename Stream>
|
||||
inline void unpack( Stream& s, variant& v )
|
||||
{
|
||||
uint8_t t;
|
||||
unpack( s, t );
|
||||
switch( t )
|
||||
{
|
||||
case variant::null_type:
|
||||
return;
|
||||
case variant::int64_type:
|
||||
{
|
||||
int64_t val;
|
||||
raw::unpack(s,val);
|
||||
v = val;
|
||||
return;
|
||||
}
|
||||
case variant::uint64_type:
|
||||
{
|
||||
uint64_t val;
|
||||
raw::unpack(s,val);
|
||||
v = val;
|
||||
return;
|
||||
}
|
||||
case variant::double_type:
|
||||
{
|
||||
double val;
|
||||
raw::unpack(s,val);
|
||||
v = val;
|
||||
return;
|
||||
}
|
||||
case variant::bool_type:
|
||||
{
|
||||
bool val;
|
||||
raw::unpack(s,val);
|
||||
v = val;
|
||||
return;
|
||||
}
|
||||
case variant::string_type:
|
||||
{
|
||||
fc::string val;
|
||||
raw::unpack(s,val);
|
||||
v = fc::move(val);
|
||||
return;
|
||||
}
|
||||
case variant::array_type:
|
||||
{
|
||||
variants val;
|
||||
raw::unpack(s,val);
|
||||
v = fc::move(val);
|
||||
return;
|
||||
}
|
||||
case variant::object_type:
|
||||
{
|
||||
variant_object val;
|
||||
raw::unpack(s,val);
|
||||
v = fc::move(val);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
FC_THROW_EXCEPTION( parse_error_exception, "Unknown Variant Type ${t}", ("t", t) );
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
inline void pack( Stream& s, const variant_object& v )
|
||||
{
|
||||
unsigned_int vs = v.size();
|
||||
pack( s, vs );
|
||||
for( auto itr = v.begin(); itr != v.end(); ++itr )
|
||||
{
|
||||
pack( s, itr->key() );
|
||||
pack( s, itr->value() );
|
||||
}
|
||||
wlog( "------------ done pack -------------" );
|
||||
}
|
||||
template<typename Stream>
|
||||
inline void unpack( Stream& s, variant_object& v )
|
||||
{
|
||||
unsigned_int vs;
|
||||
unpack( s, vs );
|
||||
|
||||
mutable_variant_object mvo;
|
||||
mvo.reserve(vs.value);
|
||||
for( auto i = 0; i < vs.value; ++i )
|
||||
{
|
||||
fc::string key;
|
||||
fc::variant value;
|
||||
fc::raw::unpack(s,key);
|
||||
fc::raw::unpack(s,value);
|
||||
mvo.set( fc::move(key), fc::move(value) );
|
||||
}
|
||||
v = fc::move(mvo);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline fc::vector<char> pack( const T& v ) {
|
||||
datastream<size_t> ps;
|
||||
raw::pack(ps,v );
|
||||
fc::vector<char> vec(ps.tellp());
|
||||
|
||||
if( vec.size() ) {
|
||||
datastream<char*> ds( vec.data(), size_t(vec.size()) );
|
||||
raw::pack(ds,v);
|
||||
|
|
@ -275,6 +418,12 @@ namespace fc {
|
|||
raw::unpack(ds,v);
|
||||
return v;
|
||||
}
|
||||
template<typename T>
|
||||
inline void unpack( const char* d, uint32_t s, T& v ) {
|
||||
datastream<const char*> ds( d, s );
|
||||
raw::unpack(ds,v);
|
||||
return v;
|
||||
}
|
||||
|
||||
} } // namespace fc::raw
|
||||
|
||||
38
include/fc/io/raw_fwd.hpp
Normal file
38
include/fc/io/raw_fwd.hpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
#include <fc/io/varint.hpp>
|
||||
#include <fc/array.hpp>
|
||||
|
||||
namespace fc { namespace raw {
|
||||
template<typename Stream, typename T> void unpack( Stream& s, fc::optional<T>& v );
|
||||
template<typename Stream, typename T> void pack( Stream& s, const fc::optional<T>& v );
|
||||
|
||||
template<typename Stream> void unpack( Stream& s, fc::string& );
|
||||
template<typename Stream> void pack( Stream& s, const fc::string& );
|
||||
|
||||
template<typename Stream, typename T> inline void pack( Stream& s, const T& v );
|
||||
template<typename Stream, typename T> inline void unpack( Stream& s, T& v );
|
||||
|
||||
template<typename Stream, typename T> inline void pack( Stream& s, const fc::vector<T>& v );
|
||||
template<typename Stream, typename T> inline void unpack( Stream& s, fc::vector<T>& v );
|
||||
|
||||
template<typename Stream> inline void pack( Stream& s, const signed_int& v );
|
||||
template<typename Stream> inline void unpack( Stream& s, signed_int& vi );
|
||||
|
||||
template<typename Stream> inline void pack( Stream& s, const unsigned_int& v );
|
||||
template<typename Stream> inline void unpack( Stream& s, unsigned_int& vi );
|
||||
|
||||
template<typename Stream> inline void pack( Stream& s, const char* v );
|
||||
template<typename Stream> inline void pack( Stream& s, const fc::vector<char>& value );
|
||||
template<typename Stream> inline void unpack( Stream& s, fc::vector<char>& value );
|
||||
|
||||
template<typename Stream, typename T, size_t N> inline void pack( Stream& s, const fc::array<T,N>& v);
|
||||
template<typename Stream, typename T, size_t N> inline void unpack( Stream& s, fc::array<T,N>& v);
|
||||
|
||||
template<typename Stream> inline void pack( Stream& s, const bool& v );
|
||||
template<typename Stream> inline void unpack( Stream& s, bool& v );
|
||||
|
||||
template<typename T> inline fc::vector<char> pack( const T& v );
|
||||
template<typename T> inline T unpack( const fc::vector<char>& s );
|
||||
template<typename T> inline T unpack( const char* d, uint32_t s );
|
||||
template<typename T> inline void unpack( const char* d, uint32_t s, T& v );
|
||||
} }
|
||||
24
include/fc/io/raw_unpack_file.hpp
Normal file
24
include/fc/io/raw_unpack_file.hpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
#include <fc/io/raw.hpp>
|
||||
#include <fc/interprocess/file_mapping.hpp>
|
||||
#include <fc/filesystem.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
namespace raw
|
||||
{
|
||||
template<typename T>
|
||||
void unpack_file( const fc::path& filename, T& obj )
|
||||
{
|
||||
try {
|
||||
fc::file_mapping fmap( filename.generic_string().c_str(), fc::read_only);
|
||||
fc::mapped_region mapr( fmap, fc::read_only, 0, fc::file_size(filename) );
|
||||
auto cs = (const char*)mapr.get_address();
|
||||
|
||||
fc::datastream<const char*> ds( cs, mapr.get_size() );
|
||||
fc::raw::unpack(ds,obj);
|
||||
} FC_RETHROW_EXCEPTIONS( info, "unpacking file ${file}", ("file",filename) );
|
||||
}
|
||||
}
|
||||
}
|
||||
31
include/fc/io/sstream.hpp
Normal file
31
include/fc/io/sstream.hpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
#include <fc/io/iostream.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
class stringstream : virtual public iostream {
|
||||
public:
|
||||
stringstream();
|
||||
stringstream( fc::string& s);
|
||||
stringstream( const fc::string& s);
|
||||
~stringstream();
|
||||
|
||||
fc::string str();
|
||||
void str(const fc::string& s);
|
||||
|
||||
void clear();
|
||||
|
||||
virtual bool eof()const;
|
||||
virtual size_t writesome( const char* buf, size_t len );
|
||||
virtual size_t readsome( char* buf, size_t len );
|
||||
virtual void close();
|
||||
virtual void flush();
|
||||
char peek();
|
||||
|
||||
private:
|
||||
class impl;
|
||||
fwd<impl,368> my;
|
||||
};
|
||||
|
||||
}
|
||||
36
include/fc/io/stdio.hpp
Normal file
36
include/fc/io/stdio.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#include <fc/io/iostream.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
|
||||
class cout_t : virtual public ostream {
|
||||
public:
|
||||
virtual size_t writesome( const char* buf, size_t len );
|
||||
virtual void close();
|
||||
virtual void flush();
|
||||
};
|
||||
|
||||
class cerr_t : virtual public ostream {
|
||||
public:
|
||||
virtual size_t writesome( const char* buf, size_t len );
|
||||
virtual void close();
|
||||
virtual void flush();
|
||||
};
|
||||
|
||||
class cin_t : virtual public istream {
|
||||
public:
|
||||
~cin_t();
|
||||
virtual size_t readsome( char* buf, size_t len );
|
||||
virtual istream& read( char* buf, size_t len );
|
||||
virtual bool eof()const;
|
||||
};
|
||||
|
||||
extern cout_t& cout;
|
||||
extern cerr_t& cerr;
|
||||
extern cin_t& cin;
|
||||
|
||||
extern std::shared_ptr<cin_t> cin_ptr;
|
||||
extern std::shared_ptr<cout_t> cout_ptr;
|
||||
extern std::shared_ptr<cerr_t> cerr_ptr;
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef _FC_VARINT_HPP_
|
||||
#define _FC_VARINT_HPP_
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace fc {
|
||||
|
|
@ -24,7 +23,13 @@ struct signed_int {
|
|||
int32_t value;
|
||||
};
|
||||
|
||||
class variant;
|
||||
|
||||
void to_variant( const signed_int& var, variant& vo );
|
||||
void from_variant( const variant& var, signed_int& vo );
|
||||
void to_variant( const unsigned_int& var, variant& vo );
|
||||
void from_variant( const variant& var, unsigned_int& vo );
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/utility.hpp>
|
||||
#include <fc/lexical_cast.hpp>
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
class istream {
|
||||
public:
|
||||
virtual ~istream(){};
|
||||
|
||||
virtual size_t readsome( char* buf, size_t len ) = 0;
|
||||
virtual istream& read( char* buf, size_t len ) = 0;
|
||||
|
||||
virtual bool eof()const = 0;
|
||||
};
|
||||
|
||||
class ostream {
|
||||
public:
|
||||
virtual ~ostream(){};
|
||||
|
||||
virtual ostream& write( const char* buf, size_t len ) = 0;
|
||||
virtual void close(){}
|
||||
virtual void flush(){}
|
||||
};
|
||||
|
||||
class iostream : public virtual ostream, public virtual istream {};
|
||||
|
||||
|
||||
struct cout_t : virtual public ostream {
|
||||
virtual ostream& write( const char* buf, size_t len );
|
||||
virtual void close();
|
||||
virtual void flush();
|
||||
|
||||
virtual ostream& write( const fc::string& );
|
||||
};
|
||||
|
||||
struct cerr_t : virtual public ostream {
|
||||
virtual ostream& write( const char* buf, size_t len );
|
||||
virtual void close();
|
||||
virtual void flush();
|
||||
|
||||
virtual ostream& write( const fc::string& );
|
||||
};
|
||||
|
||||
struct cin_t : virtual public istream {
|
||||
~cin_t();
|
||||
virtual size_t readsome( char* buf, size_t len );
|
||||
virtual istream& read( char* buf, size_t len );
|
||||
virtual bool eof()const;
|
||||
};
|
||||
fc::istream& getline( fc::istream&, fc::string&, char delim = '\n' );
|
||||
|
||||
|
||||
extern cout_t cout;
|
||||
extern cerr_t cerr;
|
||||
extern cin_t cin;
|
||||
|
||||
|
||||
template<typename T>
|
||||
ostream& operator<<( ostream& o, const T& v ) {
|
||||
auto str = fc::lexical_cast<fc::string>(v);
|
||||
o.write( str.c_str(), static_cast<size_t>(str.size()) );
|
||||
return o;
|
||||
}
|
||||
ostream& operator<<( ostream& o, const char* v );
|
||||
|
||||
template<typename T>
|
||||
ostream& operator<<( ostream& o, const fc::string& str ) {
|
||||
o.write( str.c_str(), static_cast<size_t>(str.size()) );
|
||||
return o;
|
||||
}
|
||||
template<typename T>
|
||||
istream& operator>>( istream& o, T& v ) {
|
||||
fc::string str;
|
||||
getline( o, str, ' ' );
|
||||
v = fc::lexical_cast<T>(str);
|
||||
return o;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/iostream.hpp>
|
||||
#include <fc/shared_ptr.hpp>
|
||||
#include <fc/log.hpp>
|
||||
|
||||
namespace fc {
|
||||
/**
|
||||
* Used to wrap references to other streams
|
||||
*/
|
||||
class ostream_wrapper : public ostream {
|
||||
public:
|
||||
template<typename Stream>
|
||||
ostream_wrapper( Stream& s )
|
||||
:my( new impl<Stream>(s) ){}
|
||||
|
||||
virtual ~ostream_wrapper(){};
|
||||
|
||||
virtual ostream& write( const char* buf, size_t len ) {
|
||||
my->write(buf,len);
|
||||
return *this;
|
||||
}
|
||||
virtual void close() {
|
||||
// TODO: move to cpp
|
||||
my->close();
|
||||
}
|
||||
virtual void flush() {
|
||||
my->flush();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ostream& write( const fc::string& s ) {
|
||||
return write( s.c_str(), s.size() );
|
||||
}
|
||||
|
||||
struct impl_base : public fc::retainable {
|
||||
virtual ~impl_base(){}
|
||||
virtual void write( const char* buf, size_t len ) = 0;
|
||||
virtual void close() = 0;
|
||||
virtual void flush() = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct impl : public impl_base {
|
||||
impl(T& i):st(i){}
|
||||
|
||||
virtual void write( const char* buf, size_t len ) {
|
||||
st.write(buf,len);
|
||||
}
|
||||
virtual void close() { st.close(); }
|
||||
virtual void flush() { st.flush(); }
|
||||
T& st;
|
||||
};
|
||||
|
||||
fc::shared_ptr<impl_base> my;
|
||||
};
|
||||
/**
|
||||
* Used to wrap references to other streams
|
||||
*/
|
||||
class istream_wrapper : public istream {
|
||||
public:
|
||||
template<typename Stream>
|
||||
istream_wrapper( Stream& s )
|
||||
:my( new impl<Stream>(s) ){}
|
||||
|
||||
virtual ~istream_wrapper(){};
|
||||
|
||||
virtual size_t readsome( char* buf, size_t len ) {
|
||||
return my->readsome(buf,len);
|
||||
}
|
||||
virtual istream& read( char* buf, size_t len ) {
|
||||
// slog( "%p %lld", my.get(), len );
|
||||
my->read(buf,len);
|
||||
return *this;
|
||||
}
|
||||
virtual void close() { }
|
||||
virtual bool eof()const{ return my->eof(); }
|
||||
|
||||
/*
|
||||
virtual istream& read( int64_t& ) { return *this; }
|
||||
virtual istream& read( uint64_t& ) { return *this; }
|
||||
virtual istream& read( int32_t& ) { return *this; }
|
||||
virtual istream& read( uint32_t& ) { return *this; }
|
||||
virtual istream& read( int16_t& ) { return *this; }
|
||||
virtual istream& read( uint16_t& ) { return *this; }
|
||||
virtual istream& read( int8_t& ) { return *this; }
|
||||
virtual istream& read( uint8_t& ) { return *this; }
|
||||
virtual istream& read( float& ) { return *this; }
|
||||
virtual istream& read( double& ) { return *this; }
|
||||
virtual istream& read( bool& ) { return *this; }
|
||||
virtual istream& read( char& ) { return *this; }
|
||||
virtual istream& read( fc::string& ) { return *this; }
|
||||
*/
|
||||
|
||||
protected:
|
||||
struct impl_base : public fc::retainable {
|
||||
virtual ~impl_base(){}
|
||||
virtual void read( char* buf, size_t len )=0;
|
||||
virtual size_t readsome( char* buf, size_t len )=0;
|
||||
virtual bool eof()const=0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct impl : public impl_base {
|
||||
impl(T& i):st(i){}
|
||||
|
||||
virtual size_t readsome( char* buf, size_t len ) { return size_t(st.readsome(buf,len)); }
|
||||
virtual void read( char* buf, size_t len ) {
|
||||
st.read(buf,len);
|
||||
}
|
||||
virtual bool eof()const { return st.eof() || !st.good(); }
|
||||
T& st;
|
||||
};
|
||||
|
||||
fc::shared_ptr<impl_base> my;
|
||||
};
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/value.hpp>
|
||||
#include <fc/value_cast.hpp>
|
||||
#include <fc/vector_fwd.hpp>
|
||||
|
||||
namespace fc {
|
||||
class istream;
|
||||
class ostream;
|
||||
class path;
|
||||
|
||||
namespace json {
|
||||
string to_string( const value& o );
|
||||
string to_pretty_string( const value& v );
|
||||
|
||||
|
||||
value from_string( const string& s );
|
||||
value from_string( const char* s, const char* e );
|
||||
value from_string( const fc::vector<char>& v );
|
||||
|
||||
|
||||
string escape_string( const string& );
|
||||
string unescape_string( const string& );
|
||||
|
||||
void write( ostream& out, const value& val );
|
||||
|
||||
template<typename T>
|
||||
void write( ostream& out, const T& val ) {
|
||||
write( out, value(val) );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
string to_string( const T& o ) {
|
||||
return json::to_string(value(o));
|
||||
}
|
||||
template<typename T>
|
||||
string to_pretty_string( const T& o ) {
|
||||
return json::to_pretty_string(value(o));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T from_string( const string& s ) {
|
||||
return value_cast<T>( from_string(s) );
|
||||
}
|
||||
|
||||
value from_file( const fc::path& s );
|
||||
template<typename T>
|
||||
T from_file( const fc::path& s ) {
|
||||
return value_cast<T>( fc::json::from_file(s) );
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
} // fc
|
||||
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/actor.hpp>
|
||||
#include <fc/json_rpc_connection.hpp>
|
||||
#include <boost/preprocessor/repeat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
||||
#include <boost/preprocessor/facilities/empty.hpp>
|
||||
|
||||
|
||||
namespace fc { namespace json {
|
||||
|
||||
namespace detail {
|
||||
struct rpc_member {
|
||||
#ifdef BOOST_NO_VARIADIC_TEMPLATES
|
||||
#define RPC_MEMBER_FUNCTOR(z,n,IS_CONST) \
|
||||
template<typename R, typename C, typename P BOOST_PP_ENUM_TRAILING_PARAMS( n, typename A)> \
|
||||
static std::function<fc::future<R>( BOOST_PP_ENUM_PARAMS(n,A) ) > \
|
||||
functor( P, R (C::*mem_func)(BOOST_PP_ENUM_PARAMS(n,A)) IS_CONST, \
|
||||
const rpc_connection::ptr& c = rpc_connection::ptr(), const char* name = nullptr ) { \
|
||||
return [=](BOOST_PP_ENUM_BINARY_PARAMS(n,A,a))->fc::future<R>{ \
|
||||
return c->invoke<R>( name, make_tuple(BOOST_PP_ENUM_PARAMS(n,a)) ); }; \
|
||||
}
|
||||
BOOST_PP_REPEAT( 8, RPC_MEMBER_FUNCTOR, const )
|
||||
BOOST_PP_REPEAT( 8, RPC_MEMBER_FUNCTOR, BOOST_PP_EMPTY() )
|
||||
#undef RPC_MEMBER_FUNCTOR
|
||||
|
||||
#else
|
||||
template<typename R, typename C, typename P, typename... Args>
|
||||
static std::function<fc::future<R>(Args...)> functor( P&& p, R (C::*mem_func)(Args...),
|
||||
const rpc_connection::ptr& c = rpc_connection::ptr(), const char* name = nullptr ) {
|
||||
return [=](Args... args)->fc::future<R>{
|
||||
return c->invoke<R>( name, make_tuple(args...) ); };
|
||||
}
|
||||
template<typename R, typename C, typename P, typename... Args>
|
||||
static std::function<fc::future<R>(Args...)> functor( P&& p, R (C::*mem_func)(Args...)const,
|
||||
const rpc_connection::ptr& c = rpc_connection::ptr(), const char* name = nullptr ) {
|
||||
return [=](Args... args)->fc::future<R>{
|
||||
return c->invoke<R>( name, make_tuple(args...) ); };
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct vtable_visitor {
|
||||
vtable_visitor( rpc_connection::ptr& c ):_con(c){}
|
||||
|
||||
template<typename Function, typename MemberPtr>
|
||||
void operator()( const char* name, Function& memb, MemberPtr m )const {
|
||||
memb = rpc_member::functor( nullptr, m, _con, name );
|
||||
}
|
||||
rpc_connection::ptr& _con;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<typename InterfaceType>
|
||||
class rpc_client : public actor<InterfaceType> { //ptr<InterfaceType,fc::json::detail::rpc_member> {
|
||||
public:
|
||||
rpc_client(){}
|
||||
rpc_client( const rpc_connection::ptr& c ){ set_connection(c); }
|
||||
//rpc_client( const rpc_client& c ):_con(c._con){}
|
||||
|
||||
void set_connection( const rpc_connection::ptr& c ) {
|
||||
_con = c;
|
||||
this->_vtable.reset(new fc::detail::vtable<InterfaceType,fc::detail::actor_member>() );
|
||||
this->_vtable->template visit_other<InterfaceType>( fc::json::detail::vtable_visitor(_con) );
|
||||
}
|
||||
const rpc_connection::ptr& connection()const { return _con; }
|
||||
|
||||
private:
|
||||
rpc_connection::ptr _con;
|
||||
};
|
||||
|
||||
} } // fc::json
|
||||
|
|
@ -1,196 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/json_rpc_error_object.hpp>
|
||||
#include <fc/json.hpp>
|
||||
#include <fc/future.hpp>
|
||||
#include <fc/function.hpp>
|
||||
#include <fc/ptr.hpp>
|
||||
|
||||
namespace fc { namespace json {
|
||||
class rpc_connection;
|
||||
class error_object;
|
||||
|
||||
struct rpc_server_method : public fc::retainable {
|
||||
typedef fc::shared_ptr<rpc_server_method> ptr;
|
||||
virtual value call( const value& v ) = 0;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
struct pending_result : virtual public promise_base {
|
||||
typedef shared_ptr<pending_result> ptr;
|
||||
virtual void handle_result( const fc::value& ) = 0;
|
||||
void handle_error( const fc::string& );
|
||||
int64_t id;
|
||||
pending_result::ptr next;
|
||||
protected:
|
||||
~pending_result(){}
|
||||
};
|
||||
template<typename T>
|
||||
struct pending_result_impl : virtual public promise<T>, virtual public pending_result {
|
||||
virtual void handle_result( const fc::value& s ) {
|
||||
this->set_value( value_cast<T>(s) );
|
||||
}
|
||||
protected:
|
||||
~pending_result_impl(){}
|
||||
};
|
||||
template<>
|
||||
struct pending_result_impl<void> : virtual public promise<void>, virtual public pending_result {
|
||||
virtual void handle_result( const fc::value& ) {
|
||||
set_value();
|
||||
}
|
||||
protected:
|
||||
~pending_result_impl(){}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct named_param {
|
||||
typedef fc::false_type type;
|
||||
static T cast( const value& v ) { return fc::value_cast<T>(v); }
|
||||
|
||||
template<typename X>
|
||||
static value to_value( X&& x ) { return value(fc::forward<X>(x)); }
|
||||
};
|
||||
|
||||
#define FC_JSON_NAMED_PARAMS( T ) \
|
||||
namespace fc { namespace json {namespace detail { \
|
||||
template<> \
|
||||
struct named_param< fc::tuple<T> > { \
|
||||
typedef fc::true_type type; \
|
||||
static tuple<T> cast( const value& v ) { return make_tuple(fc::value_cast<T>(v)); } \
|
||||
template<typename X> \
|
||||
static value to_value( X&& x ) { return value( x.a0 ); }\
|
||||
}; \
|
||||
} } }
|
||||
|
||||
template<typename R, typename ArgsTuple, typename Signature>
|
||||
struct rpc_server_method_impl : public rpc_server_method {
|
||||
rpc_server_method_impl( const std::function<Signature>& f ):func(f){}
|
||||
virtual value call( const value& v ) {
|
||||
return value( fc::call_fused(func, named_param<typename deduce<ArgsTuple>::type>::cast(v) ) );
|
||||
}
|
||||
std::function<Signature> func;
|
||||
};
|
||||
template<typename ArgsTuple, typename Signature>
|
||||
struct rpc_server_method_impl<void,ArgsTuple,Signature> : public rpc_server_method {
|
||||
rpc_server_method_impl( const std::function<Signature>& f ):func(f){}
|
||||
virtual value call( const value& v ) {
|
||||
fc::call_fused(func, named_param<typename deduce<ArgsTuple>::type>::cast(v) );
|
||||
return value();
|
||||
}
|
||||
std::function<Signature> func;
|
||||
};
|
||||
|
||||
template<typename InterfaceType>
|
||||
struct add_method_visitor {
|
||||
public:
|
||||
add_method_visitor( const fc::ptr<InterfaceType>& p, fc::json::rpc_connection& c ):_ptr(p),_con(c){}
|
||||
|
||||
template<typename R>
|
||||
void operator()( const char* name, std::function<R()>& meth);
|
||||
template<typename R, typename A1>
|
||||
void operator()( const char* name, std::function<R(A1)>& meth);
|
||||
template<typename R, typename A1, typename A2>
|
||||
void operator()( const char* name, std::function<R(A1,A2)>& meth);
|
||||
template<typename R, typename A1, typename A2, typename A3>
|
||||
void operator()( const char* name, std::function<R(A1,A2,A3)>& meth);
|
||||
|
||||
const fc::ptr<InterfaceType>& _ptr;
|
||||
fc::json::rpc_connection& _con;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the base JSON RPC connection that handles the protocol
|
||||
* level issues. It does not implement a transport which should
|
||||
* be provided separately and use the handle_message and set_send_delegate
|
||||
* methods to manage the protocol.
|
||||
*/
|
||||
class rpc_connection : public fc::retainable {
|
||||
public:
|
||||
rpc_connection();
|
||||
rpc_connection(const rpc_connection&);
|
||||
rpc_connection(rpc_connection&&);
|
||||
~rpc_connection();
|
||||
rpc_connection& operator=(const rpc_connection&);
|
||||
rpc_connection& operator=(rpc_connection&&);
|
||||
|
||||
typedef fc::shared_ptr<rpc_connection> ptr;
|
||||
|
||||
void cancel_pending_requests();
|
||||
|
||||
template<typename R, typename Args >
|
||||
future<R> invoke( const fc::string& method, Args&& a = nullptr ){
|
||||
auto r = new detail::pending_result_impl<R>();
|
||||
typename promise<R>::ptr rtn( r, true );
|
||||
invoke( detail::pending_result::ptr(r), method,
|
||||
value(detail::named_param<typename fc::deduce<Args>::type>::to_value(a)) );
|
||||
return rtn;
|
||||
}
|
||||
|
||||
template<typename Args >
|
||||
void notice( const fc::string& method, Args&& a = nullptr ){
|
||||
send_notice( method,
|
||||
value(detail::named_param<typename fc::deduce<Args>::type>::to_value(a)) );
|
||||
}
|
||||
|
||||
template<typename InterfaceType>
|
||||
void add_interface( const fc::ptr<InterfaceType>& it ) {
|
||||
it->TEMPLATE visit( detail::add_method_visitor<InterfaceType>( it, *this ) );
|
||||
}
|
||||
|
||||
void add_method( const fc::string& name, const fc::json::rpc_server_method::ptr& func );
|
||||
|
||||
virtual void close(){};
|
||||
|
||||
protected:
|
||||
void handle_message( const value& m );
|
||||
virtual void send_notice( const fc::string& m, value&& param ) = 0;
|
||||
virtual void send_invoke( uint64_t id, const fc::string& m, value&& param ) = 0;
|
||||
virtual void send_error( uint64_t id, const error_object& e ) = 0;
|
||||
virtual void send_result( uint64_t id, value&& r ) = 0;
|
||||
|
||||
|
||||
private:
|
||||
void invoke( detail::pending_result::ptr&& p, const fc::string& m, value&& param );
|
||||
void add_method( const fc::string& name, rpc_server_method::ptr&& m );
|
||||
template<typename InterfaceType>
|
||||
friend struct detail::add_method_visitor;
|
||||
|
||||
class impl;
|
||||
fc::shared_ptr<class impl> my;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename InterfaceType>
|
||||
template<typename R, typename A1>
|
||||
void add_method_visitor<InterfaceType>::operator()( const char* name,
|
||||
std::function<R(A1)>& meth) {
|
||||
_con.add_method( name, rpc_server_method::ptr(
|
||||
new rpc_server_method_impl<R,tuple<A1>,R(A1) >(meth) ) );
|
||||
}
|
||||
template<typename InterfaceType>
|
||||
template<typename R, typename A1, typename A2>
|
||||
void add_method_visitor<InterfaceType>::operator()( const char* name,
|
||||
std::function<R(A1,A2)>& meth) {
|
||||
_con.add_method( name, rpc_server_method::ptr(
|
||||
new rpc_server_method_impl<R,tuple<A1,A2>,R(A1,A2) >(meth) ) );
|
||||
}
|
||||
template<typename InterfaceType>
|
||||
template<typename R, typename A1, typename A2, typename A3>
|
||||
void add_method_visitor<InterfaceType>::operator()( const char* name,
|
||||
std::function<R(A1,A2,A3)>& meth) {
|
||||
_con.add_method( name, rpc_server_method::ptr(
|
||||
new rpc_server_method_impl<R,tuple<A1,A2,A3>,R(A1,A2,A3) >(meth) ) );
|
||||
}
|
||||
template<typename InterfaceType>
|
||||
template<typename R>
|
||||
void add_method_visitor<InterfaceType>::operator()( const char* name,
|
||||
std::function<R()>& meth) {
|
||||
_con.add_method( name, rpc_server_method::ptr(
|
||||
new rpc_server_method_impl<R,tuple<>,R() >(meth) ) );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} } // fc::json
|
||||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <fc/value.hpp>
|
||||
#include <fc/reflect.hpp>
|
||||
|
||||
|
||||
namespace fc {
|
||||
class value;
|
||||
|
||||
namespace json {
|
||||
|
||||
class error_object {
|
||||
public:
|
||||
error_object( const fc::string& msg, const fc::value& v , int64_t c = -32000);
|
||||
error_object( const fc::string& msg=fc::string(), int64_t c = -32000 );
|
||||
error_object( const error_object& e );
|
||||
~error_object();
|
||||
|
||||
int64_t code;
|
||||
fc::string message;
|
||||
fc::optional<fc::value> data;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
FC_REFLECT( fc::json::error_object, (code)(message)(data) )
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/json_rpc_client.hpp>
|
||||
#include <fc/json_rpc_stream_connection.hpp>
|
||||
#include <fc/process.hpp>
|
||||
#include <fc/filesystem.hpp>
|
||||
|
||||
namespace fc { namespace json {
|
||||
|
||||
template<typename InterfaceType>
|
||||
class rpc_process_client : public ptr<InterfaceType,fc::json::detail::rpc_member> {
|
||||
public:
|
||||
|
||||
fc::future<int> exec( const fc::path& exe, int opt = fc::process::open_all ) {
|
||||
return exec( exe, fc::path("."), opt );
|
||||
}
|
||||
fc::future<int> exec( const fc::path& exe, const fc::path& wd,
|
||||
int opt = fc::process::open_all ) {
|
||||
return exec( exe, fc::vector<fc::string>(), wd, opt );
|
||||
}
|
||||
fc::future<int> exec( const fc::path& exe, fc::vector<fc::string>&& args ,
|
||||
int opt = fc::process::open_all ) {
|
||||
return exec( exe, fc::move(args), fc::path("."), opt );
|
||||
}
|
||||
fc::future<int> exec( const fc::path& exe, fc::vector<fc::string>&& args,
|
||||
const fc::path& wd, int opt = fc::process::open_all ) {
|
||||
auto r = _proc.exec( canonical(exe), fc::move(args), wd, opt );
|
||||
_con.reset( new fc::json::rpc_stream_connection( _proc.out_stream(), _proc.in_stream() ) );
|
||||
this->_vtable.reset(new fc::detail::vtable<InterfaceType,fc::json::detail::rpc_member>() );
|
||||
rpc_connection::ptr p(_con);
|
||||
this->_vtable->template visit_other<InterfaceType>( fc::json::detail::vtable_visitor(p) );
|
||||
return r;
|
||||
}
|
||||
|
||||
void kill() { _con->close(); _proc.kill(); }
|
||||
|
||||
/**
|
||||
* @brief returns a stream that reads from the process' stderr
|
||||
*/
|
||||
fc::istream& err_stream() { return _proc.err_stream(); }
|
||||
|
||||
template<typename T>
|
||||
void on_close( T&& f) { _con->on_close( fc::forward<T>(f) ); }
|
||||
|
||||
const fc::json::rpc_stream_connection::ptr& connection()const { return _con; }
|
||||
|
||||
~rpc_process_client() {
|
||||
if(_con)
|
||||
_con->close();
|
||||
}
|
||||
private:
|
||||
fc::process _proc;
|
||||
fc::json::rpc_stream_connection::ptr _con;
|
||||
};
|
||||
} }
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/json_rpc_client.hpp>
|
||||
#include <fc/json_rpc_stream_connection.hpp>
|
||||
#include <fc/ssh/process.hpp>
|
||||
|
||||
namespace fc { namespace json {
|
||||
|
||||
template<typename InterfaceType>
|
||||
class rpc_ssh_process_client : public rpc_client<InterfaceType> {
|
||||
public:
|
||||
rpc_ssh_process_client(){}
|
||||
bool valid()const { return proc.valid(); }
|
||||
|
||||
rpc_ssh_process_client( const fc::ssh::process& proc )
|
||||
:rpc_client<InterfaceType>(rpc_connection::ptr(new fc::json::rpc_stream_connection( proc.out_stream(), proc.in_stream() ) ) ){}
|
||||
|
||||
rpc_ssh_process_client& operator = ( const fc::ssh::process& proc ) {
|
||||
this->set_connection( rpc_connection::ptr(new fc::json::rpc_stream_connection( proc.out_stream(), proc.in_stream() ) ) );
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns a stream that reads from the process' stderr
|
||||
*/
|
||||
fc::istream& err_stream() { return proc.err_stream(); }
|
||||
|
||||
fc::ssh::process& get_ssh_process() { return proc; }
|
||||
private:
|
||||
fc::ssh::process proc;
|
||||
fc::json::rpc_stream_connection::ptr _con;
|
||||
|
||||
};
|
||||
} }
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/json_rpc_connection.hpp>
|
||||
|
||||
namespace fc {
|
||||
class istream;
|
||||
class ostream;
|
||||
|
||||
namespace json {
|
||||
class rpc_stream_connection : public rpc_connection {
|
||||
public:
|
||||
typedef fc::shared_ptr<rpc_stream_connection> ptr;
|
||||
rpc_stream_connection( fc::istream&, fc::ostream& );
|
||||
rpc_stream_connection(const rpc_stream_connection& );
|
||||
rpc_stream_connection();
|
||||
|
||||
// the life of the streams must exceed the life of all copies
|
||||
// of this rpc_stream_connection
|
||||
void open( fc::istream&, fc::ostream& );
|
||||
|
||||
// cancels all pending requests, closes the ostream
|
||||
// results on_close() being called if the stream is not already closed.
|
||||
virtual void close();
|
||||
|
||||
/**
|
||||
* When the connection is closed, call the given method
|
||||
*/
|
||||
void on_close( const std::function<void()>& );
|
||||
|
||||
protected:
|
||||
~rpc_stream_connection();
|
||||
virtual void send_invoke( uint64_t id, const fc::string& m, value&& param );
|
||||
virtual void send_notice( const fc::string& m, value&& param );
|
||||
virtual void send_error( uint64_t id, const error_object& eo );
|
||||
virtual void send_result( uint64_t id, value&& r );
|
||||
|
||||
private:
|
||||
class impl;
|
||||
fc::shared_ptr<impl> my;
|
||||
};
|
||||
} } // fc::json
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/json_rpc_stream_connection.hpp>
|
||||
|
||||
namespace fc {
|
||||
class tcp_socket;
|
||||
namespace ip { class endpoint; }
|
||||
|
||||
namespace json {
|
||||
class rpc_tcp_connection : public rpc_stream_connection {
|
||||
public:
|
||||
typedef fc::shared_ptr<rpc_tcp_connection> ptr;
|
||||
|
||||
rpc_tcp_connection();
|
||||
rpc_tcp_connection( const rpc_tcp_connection& c );
|
||||
~rpc_tcp_connection();
|
||||
|
||||
void connect_to( const fc::ip::endpoint& e );
|
||||
void start();
|
||||
tcp_socket& get_socket()const;
|
||||
|
||||
virtual void close();
|
||||
|
||||
private:
|
||||
class impl;
|
||||
fc::shared_ptr<impl> my;
|
||||
};
|
||||
} // json
|
||||
} // fc
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/json_rpc_connection.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
namespace json {
|
||||
class rpc_tcp_server {
|
||||
private:
|
||||
template<typename Interface>
|
||||
struct add_method_visitor {
|
||||
add_method_visitor( fc::ptr<Interface>& p, rpc_connection& s ):_ptr(p),_rpcc(s) { }
|
||||
|
||||
template<typename Functor>
|
||||
void operator()( const char* name, Functor& fun ) {
|
||||
_rpcc.add_method( name, fun );
|
||||
}
|
||||
|
||||
fc::ptr<Interface>& _ptr;
|
||||
rpc_connection& _rpcc;
|
||||
};
|
||||
|
||||
public:
|
||||
rpc_tcp_server();
|
||||
~rpc_tcp_server();
|
||||
|
||||
template<typename Interface>
|
||||
void add_interface( const fc::ptr<Interface>& ptr ) {
|
||||
on_new_connection( [=]( rpc_connection& c ) {
|
||||
ptr->visit( detail::add_method_visitor<Interface>( ptr, c ) );
|
||||
});
|
||||
}
|
||||
|
||||
void on_new_connection( const std::function<void(rpc_connection&)>& c );
|
||||
|
||||
void listen( uint16_t port );
|
||||
|
||||
private:
|
||||
class impl;
|
||||
impl* my;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
namespace detail {
|
||||
template<typename T, typename R>
|
||||
struct lexical_cast { };
|
||||
|
||||
double to_double( const fc::string& s );
|
||||
inline double to_double( double d ) { return d; }
|
||||
|
||||
int64_t to_int64( const fc::string& s );
|
||||
inline int64_t to_int64( double d ) { return static_cast<int64_t>(d); }
|
||||
inline int64_t to_int64( int64_t d ) { return d; }
|
||||
|
||||
uint64_t to_uint64( const fc::string& s );
|
||||
inline uint64_t to_uint64( double d ) { return static_cast<uint64_t>(d); }
|
||||
inline uint64_t to_uint64( uint64_t d ) { return d; }
|
||||
|
||||
fc::string to_string( double d );
|
||||
fc::string to_string( size_t d );
|
||||
fc::string to_string( uint64_t d );
|
||||
fc::string to_string( uint32_t d );
|
||||
fc::string to_string( uint16_t d );
|
||||
fc::string to_string( uint8_t d );
|
||||
fc::string to_string( int64_t d );
|
||||
fc::string to_string( int32_t d );
|
||||
fc::string to_string( int16_t d );
|
||||
fc::string to_string( int8_t d );
|
||||
fc::string to_string( char d );
|
||||
inline fc::string to_string( const char* d ) { return d; }
|
||||
inline fc::string to_string( fc::string s ) { return s; }
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<double, R> {
|
||||
static double cast( const R& v ) { return to_double( v ); }
|
||||
};
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<fc::string, R> {
|
||||
static fc::string cast( const R& v ) { return to_string( v ); }
|
||||
};
|
||||
template<typename R>
|
||||
struct lexical_cast<std::string, R> {
|
||||
static std::string cast( const R& v ) { return to_string( v ); }
|
||||
};
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<uint64_t, R> {
|
||||
static uint64_t cast( const R& v ) { return to_uint64( v ); }
|
||||
};
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<int64_t, R> { static int64_t cast( const R& v ) { return static_cast<int64_t>(to_int64( v )); } };
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<int32_t, R> { static int32_t cast( const R& v ) { return static_cast<int32_t>(to_int64( v )); } };
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<int16_t, R> { static int16_t cast( const R& v ) { return static_cast<int16_t>(to_int64( v )); } };
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<int8_t, R> { static int8_t cast( const R& v ) { return static_cast<int8_t>(to_int64( v )); } };
|
||||
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<uint32_t, R> { static uint32_t cast( const R& v ) { return static_cast<uint32_t>(to_uint64( v )); } };
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<uint16_t, R> { static uint16_t cast( const R& v ) { return static_cast<uint16_t>(to_uint64( v )); } };
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<uint8_t, R> { static uint8_t cast( const R& v ) { return static_cast<uint8_t>(to_uint64( v )); } };
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<bool, R> { static bool cast( const R& v ) { return v != 0; } };
|
||||
|
||||
template<>
|
||||
struct lexical_cast<char, fc::string> { static char cast( const fc::string& v )
|
||||
{ return v[0]; } };// TODO: check string len
|
||||
|
||||
template<>
|
||||
struct lexical_cast<bool, fc::string> { static bool cast( const fc::string& v ) { return v == "true"; } };
|
||||
|
||||
template<>
|
||||
struct lexical_cast<fc::string,bool> { static fc::string cast( const bool& v ) { return v ? "true" : "false";} };
|
||||
|
||||
template<typename R>
|
||||
struct lexical_cast<float, R> { static float cast( const R& v ) { return static_cast<float>(to_double( v )); } };
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename R>
|
||||
T lexical_cast( const R& v ) {
|
||||
return detail::lexical_cast<T,R>::cast(v);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/utility.hpp>
|
||||
|
||||
namespace boost { class mutex; }
|
||||
|
||||
namespace fc {
|
||||
/** wrapper on printf */
|
||||
void log( const char* color, const char* file_name, size_t line_num, const char* method_name, const char* format, ... );
|
||||
|
||||
/** used to add extra fields to be printed (thread,fiber,time,etc) */
|
||||
void add_log_field( void (*f)() );
|
||||
void remove_log_field( void (*f)() );
|
||||
|
||||
boost::mutex& log_mutex();
|
||||
}
|
||||
|
||||
#ifndef __func__
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#define COLOR_CONSOLE 1
|
||||
#endif
|
||||
#include <fc/console_defines.h>
|
||||
|
||||
#define dlog(...) do { fc::log( CONSOLE_DEFAULT, __FILE__, __LINE__, __func__, __VA_ARGS__ ); }while(false)
|
||||
#define slog(...) do { fc::log( CONSOLE_DEFAULT, __FILE__, __LINE__, __func__, __VA_ARGS__ ); }while(false)
|
||||
#define wlog(...) do { fc::log( CONSOLE_BROWN, __FILE__, __LINE__, __func__, __VA_ARGS__ ); }while(false)
|
||||
#define elog(...) do { fc::log( CONSOLE_RED, __FILE__, __LINE__, __func__, __VA_ARGS__ ); }while(false)
|
||||
|
||||
|
||||
|
|
@ -4,22 +4,22 @@
|
|||
namespace fc {
|
||||
class appender;
|
||||
class log_message;
|
||||
class value;
|
||||
class string;
|
||||
class variant;
|
||||
|
||||
class appender_factory : public fc::retainable {
|
||||
public:
|
||||
typedef fc::shared_ptr<appender_factory> ptr;
|
||||
|
||||
virtual ~appender_factory(){};
|
||||
virtual fc::shared_ptr<appender> create( const value& args ) = 0;
|
||||
virtual fc::shared_ptr<appender> create( const variant& args ) = 0;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
class appender_factory_impl : public appender_factory {
|
||||
public:
|
||||
virtual fc::shared_ptr<appender> create( const value& args ) {
|
||||
virtual fc::shared_ptr<appender> create( const variant& args ) {
|
||||
return fc::shared_ptr<appender>(new T(args));
|
||||
}
|
||||
};
|
||||
|
|
@ -34,7 +34,7 @@ namespace fc {
|
|||
return register_appender( type, new detail::appender_factory_impl<T>() );
|
||||
}
|
||||
|
||||
static appender::ptr create( const fc::string& name, const fc::string& type, const value& args );
|
||||
static appender::ptr create( const fc::string& name, const fc::string& type, const variant& args );
|
||||
static appender::ptr get( const fc::string& name );
|
||||
static bool register_appender( const fc::string& type, const appender_factory::ptr& f );
|
||||
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
#pragma once
|
||||
#include <fc/appender.hpp>
|
||||
#include <fc/logger.hpp>
|
||||
#include <fc/log/appender.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
|
||||
namespace fc {
|
||||
class console_appender : public appender {
|
||||
namespace fc
|
||||
{
|
||||
class console_appender : public appender
|
||||
{
|
||||
public:
|
||||
struct color {
|
||||
struct color
|
||||
{
|
||||
enum type {
|
||||
red,
|
||||
green,
|
||||
|
|
@ -17,20 +20,23 @@ namespace fc {
|
|||
console_default,
|
||||
};
|
||||
};
|
||||
|
||||
struct stream { enum type { std_out, std_error }; };
|
||||
|
||||
struct level_color {
|
||||
level_color( log_level::type l=log_level::all,
|
||||
struct level_color
|
||||
{
|
||||
level_color( log_level l=log_level::all,
|
||||
color::type c=color::console_default )
|
||||
:level(l),color(c){}
|
||||
|
||||
log_level::type level;
|
||||
log_level level;
|
||||
console_appender::color::type color;
|
||||
};
|
||||
|
||||
struct config {
|
||||
struct config
|
||||
{
|
||||
config()
|
||||
:format( "${when} ${thread} ${context} ${file}:${line} ${method} ${level}] ${message}" ),
|
||||
:format( "${timestamp} ${thread_name} ${context} ${file}:${line} ${method} ${level}] ${message}" ),
|
||||
stream(console_appender::stream::std_error),flush(true){}
|
||||
|
||||
fc::string format;
|
||||
|
|
@ -40,16 +46,17 @@ namespace fc {
|
|||
};
|
||||
|
||||
|
||||
console_appender( const value& args );
|
||||
const char* get_color( log_level::type l )const;
|
||||
console_appender( const variant& args );
|
||||
const char* get_color( log_level l )const;
|
||||
virtual void log( const log_message& m );
|
||||
|
||||
private:
|
||||
config cfg;
|
||||
color::type lc[log_level::off+1];
|
||||
};
|
||||
} // namespace fc
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
FC_REFLECT_ENUM( fc::console_appender::stream::type, (std_out)(std_error) )
|
||||
FC_REFLECT_ENUM( fc::console_appender::color::type, (red)(green)(brown)(blue)(magenta)(cyan)(white)(console_default) )
|
||||
FC_REFLECT( fc::console_appender::level_color, (level)(color) )
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
#pragma once
|
||||
#include <fc/appender.hpp>
|
||||
#include <fc/logger.hpp>
|
||||
#include <fc/log/appender.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <fc/filesystem.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
class varaint;
|
||||
|
||||
class file_appender : public appender {
|
||||
public:
|
||||
struct config {
|
||||
|
|
@ -15,7 +17,7 @@ class file_appender : public appender {
|
|||
bool flush;
|
||||
bool truncate;
|
||||
};
|
||||
file_appender( const value& args );
|
||||
file_appender( const variant& args );
|
||||
~file_appender();
|
||||
virtual void log( const log_message& m );
|
||||
|
||||
|
|
@ -25,5 +27,5 @@ class file_appender : public appender {
|
|||
};
|
||||
} // namespace fc
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
FC_REFLECT( fc::file_appender::config, (format)(filename)(flush)(truncate) )
|
||||
159
include/fc/log/log_message.hpp
Normal file
159
include/fc/log/log_message.hpp
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
#pragma once
|
||||
/**
|
||||
* @file log_message.hpp
|
||||
* @brief Defines types and helper macros necessary for generating log messages.
|
||||
*/
|
||||
#include <fc/time.hpp>
|
||||
#include <fc/variant_object.hpp>
|
||||
#include <fc/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class log_context_impl;
|
||||
class log_message_impl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Named scope for log_level enumeration.
|
||||
*/
|
||||
class log_level
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Define's the various log levels for reporting.
|
||||
*
|
||||
* Each log level includes all higher levels such that
|
||||
* Debug includes Error, but Error does not include Debug.
|
||||
*/
|
||||
enum values
|
||||
{
|
||||
all,
|
||||
debug,
|
||||
info,
|
||||
warn,
|
||||
error,
|
||||
off
|
||||
};
|
||||
log_level( values v = off ):value(v){}
|
||||
explicit log_level( int v ):value( static_cast<values>(v)){}
|
||||
operator int()const { return value; }
|
||||
values value;
|
||||
};
|
||||
|
||||
void to_variant( log_level e, variant& v );
|
||||
void from_variant( const variant& e, log_level& ll );
|
||||
|
||||
/**
|
||||
* @brief provides information about where and when a log message was generated.
|
||||
* @ingroup AthenaSerializable
|
||||
*
|
||||
* @see FC_LOG_CONTEXT
|
||||
*/
|
||||
class log_context
|
||||
{
|
||||
public:
|
||||
log_context();
|
||||
log_context( log_level ll,
|
||||
const char* file,
|
||||
uint64_t line,
|
||||
const char* method );
|
||||
~log_context();
|
||||
explicit log_context( const variant& v );
|
||||
variant to_variant()const;
|
||||
|
||||
string get_file()const;
|
||||
uint64_t get_line_number()const;
|
||||
string get_method()const;
|
||||
string get_thread_name()const;
|
||||
string get_host_name()const;
|
||||
time_point get_timestamp()const;
|
||||
log_level get_log_level()const;
|
||||
string get_context()const;
|
||||
|
||||
void append_context( const fc::string& c );
|
||||
|
||||
string to_string()const;
|
||||
private:
|
||||
std::shared_ptr<detail::log_context_impl> my;
|
||||
};
|
||||
|
||||
void to_variant( const log_context& l, variant& v );
|
||||
void from_variant( const variant& l, log_context& c );
|
||||
|
||||
/**
|
||||
* @brief aggregates a message along with the context and associated meta-information.
|
||||
* @ingroup AthenaSerializable
|
||||
*
|
||||
* @note log_message has reference semantics, all copies refer to the same log message
|
||||
* and the message is read-only after construction.
|
||||
*
|
||||
* When converted to JSON, log_message has the following form:
|
||||
* @code
|
||||
* {
|
||||
* "context" : { ... },
|
||||
* "format" : "string with ${keys}",
|
||||
* "data" : { "keys" : "values" }
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @see FC_LOG_MESSAGE
|
||||
*/
|
||||
class log_message
|
||||
{
|
||||
public:
|
||||
log_message();
|
||||
/**
|
||||
* @param ctx - generally provided using the FC_LOG_CONTEXT(LEVEL) macro
|
||||
*/
|
||||
log_message( log_context ctx, const char* format, variant_object args = variant_object() );
|
||||
~log_message();
|
||||
|
||||
log_message( const variant& v );
|
||||
variant to_variant()const;
|
||||
|
||||
string get_message()const;
|
||||
|
||||
log_context get_context()const;
|
||||
string get_format()const;
|
||||
variant_object get_data()const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<detail::log_message_impl> my;
|
||||
};
|
||||
|
||||
void to_variant( const log_message& l, variant& v );
|
||||
void from_variant( const variant& l, log_message& c );
|
||||
|
||||
typedef fc::vector<log_message> log_messages;
|
||||
|
||||
|
||||
} // namespace fc
|
||||
|
||||
#ifndef __func__
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def FC_LOG_CONTEXT(LOG_LEVEL)
|
||||
* @brief Automatically captures the File, Line, and Method names and passes them to
|
||||
* the constructor of fc::log_context along with LOG_LEVEL
|
||||
* @param LOG_LEVEL - a valid log_level::Enum name.
|
||||
*/
|
||||
#define FC_LOG_CONTEXT(LOG_LEVEL) \
|
||||
fc::log_context( fc::log_level::LOG_LEVEL, __FILE__, __LINE__, __func__ )
|
||||
|
||||
/**
|
||||
* @def FC_LOG_MESSAGE(LOG_LEVEL,FORMAT,...)
|
||||
*
|
||||
* @brief A helper method for generating log messages.
|
||||
*
|
||||
* @param LOG_LEVEL a valid log_level::Enum name to be passed to the log_context
|
||||
* @param FORMAT A const char* string containing zero or more references to keys as "${key}"
|
||||
* @param ... A set of key/value pairs denoted as ("key",val)("key2",val2)...
|
||||
*/
|
||||
#define FC_LOG_MESSAGE( LOG_LEVEL, FORMAT, ... ) \
|
||||
fc::log_message( FC_LOG_CONTEXT(LOG_LEVEL), FORMAT, fc::mutable_variant_object()__VA_ARGS__ )
|
||||
|
||||
137
include/fc/log/logger.hpp
Normal file
137
include/fc/log/logger.hpp
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
#pragma once
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/time.hpp>
|
||||
#include <fc/shared_ptr.hpp>
|
||||
#include <fc/log/log_message.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
|
||||
class appender;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
@code
|
||||
void my_class::func()
|
||||
{
|
||||
fc_dlog( my_class_logger, "Format four: ${arg} five: ${five}", ("arg",4)("five",5) );
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
class logger
|
||||
{
|
||||
public:
|
||||
static logger get( const fc::string& name = "default");
|
||||
|
||||
logger();
|
||||
logger( const string& name, const logger& parent = nullptr );
|
||||
logger( std::nullptr_t );
|
||||
logger( const logger& c );
|
||||
logger( logger&& c );
|
||||
~logger();
|
||||
logger& operator=(const logger&);
|
||||
logger& operator=(logger&&);
|
||||
friend bool operator==( const logger&, nullptr_t );
|
||||
friend bool operator!=( const logger&, nullptr_t );
|
||||
|
||||
logger& set_log_level( log_level e );
|
||||
log_level get_log_level()const;
|
||||
logger& set_parent( const logger& l );
|
||||
logger get_parent()const;
|
||||
|
||||
void set_name( const fc::string& n );
|
||||
const fc::string& name()const;
|
||||
|
||||
void add_appender( const fc::shared_ptr<appender>& a );
|
||||
|
||||
bool is_enabled( log_level e )const;
|
||||
void log( log_message m );
|
||||
|
||||
private:
|
||||
class impl;
|
||||
fc::shared_ptr<impl> my;
|
||||
};
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
||||
#define fc_dlog( LOGGER, FORMAT, ... ) \
|
||||
do { \
|
||||
if( (LOGGER).is_enabled( fc::log_level::debug ) ) { \
|
||||
(LOGGER).log( FC_LOG_MESSAGE( debug, FORMAT, __VA_ARGS__ ) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define fc_ilog( LOGGER, FORMAT, ... ) \
|
||||
do { \
|
||||
if( (LOGGER).is_enabled( fc::log_level::info ) ) { \
|
||||
(LOGGER).log( FC_LOG_MESSAGE( info, FORMAT, __VA_ARGS__ ) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define fc_wlog( LOGGER, FORMAT, ... ) \
|
||||
do { \
|
||||
if( (LOGGER).is_enabled( fc::log_level::warn ) ) { \
|
||||
(LOGGER).log( FC_LOG_MESSAGE( warn, FORMAT, __VA_ARGS__ ) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define fc_elog( LOGGER, FORMAT, ... ) \
|
||||
do { \
|
||||
if( (LOGGER).is_enabled( fc::log_level::error ) ) { \
|
||||
(LOGGER).log( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define dlog( FORMAT, ... ) \
|
||||
do { \
|
||||
if( (fc::logger::get()).is_enabled( fc::log_level::debug ) ) { \
|
||||
(fc::logger::get()).log( FC_LOG_MESSAGE( debug, FORMAT, __VA_ARGS__ ) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ilog( FORMAT, ... ) \
|
||||
do { \
|
||||
if( (fc::logger::get()).is_enabled( fc::log_level::info ) ) { \
|
||||
(fc::logger::get()).log( FC_LOG_MESSAGE( info, FORMAT, __VA_ARGS__ ) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define wlog( FORMAT, ... ) \
|
||||
do { \
|
||||
if( (fc::logger::get()).is_enabled( fc::log_level::warn ) ) { \
|
||||
(fc::logger::get()).log( FC_LOG_MESSAGE( warn, FORMAT, __VA_ARGS__ ) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define elog( FORMAT, ... ) \
|
||||
do { \
|
||||
if( (fc::logger::get()).is_enabled( fc::log_level::error ) ) { \
|
||||
(fc::logger::get()).log( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) ); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/preprocessor/seq/size.hpp>
|
||||
#include <boost/preprocessor/seq/seq.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/punctuation/paren.hpp>
|
||||
|
||||
|
||||
#define FC_FORMAT_ARG(r, unused, base) \
|
||||
BOOST_PP_STRINGIZE(base) ": ${" BOOST_PP_STRINGIZE( base ) "} "
|
||||
|
||||
#define FC_FORMAT_ARGS(r, unused, base) \
|
||||
BOOST_PP_LPAREN() BOOST_PP_STRINGIZE(base),fc::variant(base) BOOST_PP_RPAREN()
|
||||
|
||||
#define FC_FORMAT( SEQ )\
|
||||
BOOST_PP_SEQ_FOR_EACH( FC_FORMAT_ARG, v, SEQ )
|
||||
|
||||
#define FC_FORMAT_ARG_PARAMS( SEQ )\
|
||||
BOOST_PP_SEQ_FOR_EACH( FC_FORMAT_ARGS, v, SEQ )
|
||||
|
||||
#define idump( SEQ ) \
|
||||
ilog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
||||
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
#pragma once
|
||||
#include <fc/logger.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
|
||||
namespace fc {
|
||||
class path;
|
||||
struct appender_config {
|
||||
appender_config(const fc::string& n="",const fc::string& t="", const value& a=value())
|
||||
:name(n),type(t),args(a),enabled(true){}
|
||||
string name;
|
||||
string type;
|
||||
value args;
|
||||
bool enabled;
|
||||
appender_config(const fc::string& n="",const fc::string& t="", variant a=variant())
|
||||
:name(n),type(t),args(fc::move(a)),enabled(true){}
|
||||
string name;
|
||||
string type;
|
||||
variant args;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
struct logger_config {
|
||||
|
|
@ -17,7 +17,7 @@ namespace fc {
|
|||
string name;
|
||||
ostring parent;
|
||||
/// if not set, then parents level is used.
|
||||
fc::optional<log_level::type> level;
|
||||
fc::optional<log_level> level;
|
||||
bool enabled;
|
||||
/// if any appenders are sepecified, then parent's appenders are not set.
|
||||
bool additivity;
|
||||
|
|
@ -37,7 +37,7 @@ namespace fc {
|
|||
bool configure_logging( const logging_config& l );
|
||||
}
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
FC_REFLECT( fc::appender_config, (name)(type)(args)(enabled) )
|
||||
FC_REFLECT( fc::logger_config, (name)(parent)(level)(enabled)(additivity)(appenders) )
|
||||
FC_REFLECT( fc::logging_config, (includes)(appenders)(loggers) )
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/value.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/time.hpp>
|
||||
#include <fc/shared_ptr.hpp>
|
||||
|
||||
|
||||
namespace fc {
|
||||
|
||||
struct log_level {
|
||||
enum type {
|
||||
all, trace, debug, info, warn, error, fatal, off
|
||||
};
|
||||
};
|
||||
|
||||
struct log_message {
|
||||
log_message(log_level::type, const string& file, int line, const string& func, const string& format );
|
||||
log_message();
|
||||
|
||||
otime_point when;
|
||||
log_level::type level;
|
||||
ostring context;
|
||||
ostring thread;
|
||||
ostring fiber;
|
||||
ostring host;
|
||||
string file;
|
||||
int line;
|
||||
string method;
|
||||
string format;
|
||||
value args;
|
||||
ovalue meta;
|
||||
|
||||
// key based args
|
||||
template<typename T>
|
||||
log_message& operator()( const string& arg, const T& v ) {
|
||||
return (*this)(arg,value(v));
|
||||
}
|
||||
|
||||
log_message& operator()( const string& arg, value&& v );
|
||||
log_message& operator()( const string& arg, const value& v );
|
||||
// position based args...
|
||||
log_message& operator()( value&& v );
|
||||
log_message& operator()( const value& v );
|
||||
};
|
||||
|
||||
class appender;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
@code
|
||||
void my_class::func()
|
||||
{
|
||||
fc_dlog( my_class_logger, "Format four: ${arg} five: ${five}", ("arg",4)("five",5) );
|
||||
}
|
||||
@endcode
|
||||
*/
|
||||
class logger {
|
||||
public:
|
||||
static logger get( const fc::string& name = "default");
|
||||
|
||||
logger();
|
||||
logger( const string& name, const logger& parent = nullptr );
|
||||
logger( std::nullptr_t );
|
||||
logger( const logger& c );
|
||||
logger( logger&& c );
|
||||
~logger();
|
||||
logger& operator=(const logger&);
|
||||
logger& operator=(logger&&);
|
||||
friend bool operator==( const logger&, std::nullptr_t );
|
||||
friend bool operator!=( const logger&, std::nullptr_t );
|
||||
|
||||
logger& set_log_level( log_level::type e );
|
||||
log_level::type get_log_level()const;
|
||||
logger& set_parent( const logger& l );
|
||||
logger get_parent()const;
|
||||
|
||||
void set_name( const fc::string& n );
|
||||
const fc::string& name()const;
|
||||
|
||||
void add_appender( const fc::shared_ptr<appender>& a );
|
||||
|
||||
|
||||
bool is_enabled( log_level::type e )const;
|
||||
void log( log_message m );
|
||||
|
||||
private:
|
||||
class impl;
|
||||
fc::shared_ptr<impl> my;
|
||||
};
|
||||
|
||||
/**
|
||||
* This helper class is used to automatically print a log message
|
||||
* once upon construction, and again upon destruction and is therefore
|
||||
* helpful in catching scope changes.
|
||||
struct tracer {
|
||||
tracer( const logger::ptr& lgr );
|
||||
~tracer();
|
||||
|
||||
void set_message( log_message&& ms g);
|
||||
|
||||
private:
|
||||
logger::ptr logger;
|
||||
log_message msg;
|
||||
};
|
||||
*/
|
||||
|
||||
} // namespace fc
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
FC_REFLECT( fc::log_message, (when)(level)(context)(thread)(fiber)(host)(method)(file)(line)(format)(args)(meta) )
|
||||
FC_REFLECT_ENUM( fc::log_level::type, (all)(trace)(debug)(info)(warn)(error)(fatal)(off) )
|
||||
|
||||
#define fc_scope_log( LOGGER, FORMAT, ... ) \
|
||||
fc::tracer __tracer; \
|
||||
if( (LOGGER).is_enabled( fc::log_level::trace ) ) { \
|
||||
__tracer.set_message( fc::log_message( fc::log_level::trace, __FILE__, __LINE__, __func__, FORMAT ) __VA_ARGS__ );\
|
||||
}
|
||||
|
||||
#define fc_dlog( LOGGER, FORMAT, ... ) \
|
||||
if( (LOGGER).is_enabled( fc::log_level::debug ) ) { \
|
||||
(LOGGER).log( fc::log_message( fc::log_level::debug, __FILE__, __LINE__, __func__, FORMAT ) __VA_ARGS__ );\
|
||||
}
|
||||
|
||||
#define fc_ilog( LOGGER, FORMAT, ... ) \
|
||||
if( (LOGGER).is_enabled( fc::log_level::info ) ) { \
|
||||
(LOGGER).log( fc::log_message( fc::log_level::info, __FILE__, __LINE__, __func__, FORMAT ) __VA_ARGS__ );\
|
||||
}
|
||||
|
||||
#define fc_wlog( LOGGER, FORMAT, ... ) \
|
||||
if( (LOGGER).is_enabled( fc::log_level::warn ) ) { \
|
||||
(LOGGER).log( fc::log_message( fc::log_level::warn, __FILE__, __LINE__, __func__, FORMAT ) __VA_ARGS__ );\
|
||||
}
|
||||
|
||||
#define fc_elog( LOGGER, FORMAT, ... ) \
|
||||
if( (LOGGER).is_enabled( fc::log_level::error ) ) { \
|
||||
(LOGGER).log( fc::log_message( fc::log_level::error, __FILE__, __LINE__, __func__, FORMAT ) __VA_ARGS__ );\
|
||||
}
|
||||
|
||||
#define fc_flog( LOGGER, FORMAT, ... ) \
|
||||
if( (LOGGER).is_enabled( fc::log_level::fatal ) ) { \
|
||||
(LOGGER).log( fc::log_message( fc::log_level::fatal, __FILE__, __LINE__, __func__, FORMAT ) __VA_ARGS__ );\
|
||||
}
|
||||
|
||||
|
|
@ -4,23 +4,23 @@
|
|||
|
||||
namespace fc {
|
||||
template<typename R>
|
||||
fc::function<R, fc::tuple<> > make_fused( const fc::function<R>& f ) {
|
||||
std::function<R, fc::tuple<> > make_fused( const std::function<R>& f ) {
|
||||
return [=]( fc::tuple<> ){ return f(); };
|
||||
}
|
||||
template<typename R,typename A>
|
||||
fc::function<R(fc::tuple<A>) > make_fused( const fc::function<R(A)>& f ) {
|
||||
std::function<R(fc::tuple<A>) > make_fused( const std::function<R(A)>& f ) {
|
||||
return [f]( fc::tuple<A> t){ return f(t.a); };
|
||||
}
|
||||
template<typename R,typename A,typename B>
|
||||
fc::function<R(fc::tuple<A,B>) > make_fused( const fc::function<R(A,B)>& f ) {
|
||||
std::function<R(fc::tuple<A,B>) > make_fused( const std::function<R(A,B)>& f ) {
|
||||
return [f]( fc::tuple<A,B> t){ return f(t.a,t.b); };
|
||||
}
|
||||
template<typename R,typename A,typename B,typename C>
|
||||
fc::function<R(fc::tuple<A,B,C>) > make_fused( const fc::function<R(A,B,C)>& f ) {
|
||||
std::function<R(fc::tuple<A,B,C>) > make_fused( const std::function<R(A,B,C)>& f ) {
|
||||
return [f]( fc::tuple<A,B,C> t){ return f(t.a,t.b,t.c); };
|
||||
}
|
||||
template<typename R,typename A,typename B,typename C,typename D>
|
||||
fc::function<R(fc::tuple<A,B,C,D>) > make_fused( const fc::function<R(A,B,C,D)>& f ) {
|
||||
std::function<R(fc::tuple<A,B,C,D>) > make_fused( const std::function<R(A,B,C,D)>& f ) {
|
||||
return [f]( fc::tuple<A,B,C> t){ return f(t.a,t.b,t.c,t.d); };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef _FC_MAP_HPP_
|
||||
namespace fc {
|
||||
|
||||
namespace detail {
|
||||
class map_impl {
|
||||
public:
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
template<typename K, typename V>
|
||||
class map : public map_impl {
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
76
include/fc/network/http/connection.hpp
Normal file
76
include/fc/network/http/connection.hpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
#pragma once
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace fc {
|
||||
namespace ip { class endpoint; }
|
||||
class tcp_socket;
|
||||
|
||||
namespace http {
|
||||
|
||||
struct header
|
||||
{
|
||||
header( fc::string k, fc::string v )
|
||||
:key(fc::move(k)),val(fc::move(v)){}
|
||||
header(){}
|
||||
fc::string key;
|
||||
fc::string val;
|
||||
};
|
||||
|
||||
typedef fc::vector<header> headers;
|
||||
|
||||
struct reply
|
||||
{
|
||||
enum status_code {
|
||||
OK = 200,
|
||||
RecordCreated = 201,
|
||||
NotFound = 404,
|
||||
Found = 302,
|
||||
InternalServerError = 500
|
||||
};
|
||||
reply( status_code c = OK):status(c){}
|
||||
int status;
|
||||
fc::vector<header> headers;
|
||||
fc::vector<char> body;
|
||||
};
|
||||
|
||||
struct request
|
||||
{
|
||||
fc::string get_header( const fc::string& key )const;
|
||||
fc::string method;
|
||||
fc::string domain;
|
||||
fc::string path;
|
||||
fc::vector<header> headers;
|
||||
fc::vector<char> body;
|
||||
};
|
||||
|
||||
fc::vector<header> parse_urlencoded_params( const fc::string& f );
|
||||
|
||||
/**
|
||||
* Connections have reference semantics, all copies refer to the same
|
||||
* underlying socket.
|
||||
*/
|
||||
class connection
|
||||
{
|
||||
public:
|
||||
connection();
|
||||
~connection();
|
||||
// used for clients
|
||||
void connect_to( const fc::ip::endpoint& ep );
|
||||
http::reply request( const fc::string& method, const fc::string& url, const fc::string& body, const headers& = headers());
|
||||
|
||||
// used for servers
|
||||
fc::tcp_socket& get_socket()const;
|
||||
|
||||
http::request read_request()const;
|
||||
|
||||
class impl;
|
||||
private:
|
||||
std::unique_ptr<impl> my;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<connection> connection_ptr;
|
||||
|
||||
} } // fc::http
|
||||
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
#pragma once
|
||||
#include <fc/http/connection.hpp>
|
||||
#include <fc/network/http/connection.hpp>
|
||||
#include <fc/shared_ptr.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace fc { namespace http {
|
||||
|
||||
|
|
@ -11,18 +12,18 @@ namespace fc { namespace http {
|
|||
* function for every http request.
|
||||
*
|
||||
*/
|
||||
class server {
|
||||
class server
|
||||
{
|
||||
public:
|
||||
server();
|
||||
server( uint16_t port );
|
||||
server( const server& s );
|
||||
server( server&& s );
|
||||
~server();
|
||||
|
||||
server& operator=(const server& s);
|
||||
server& operator=(server&& s);
|
||||
|
||||
class response {
|
||||
class response
|
||||
{
|
||||
public:
|
||||
class impl;
|
||||
|
||||
|
|
@ -53,8 +54,8 @@ namespace fc { namespace http {
|
|||
|
||||
private:
|
||||
class impl;
|
||||
fc::shared_ptr<impl> my;
|
||||
|
||||
std::unique_ptr<impl> my;
|
||||
};
|
||||
typedef std::shared_ptr<server> server_ptr;
|
||||
|
||||
} }
|
||||
|
|
@ -46,7 +46,10 @@ namespace fc {
|
|||
address _ip;
|
||||
};
|
||||
}
|
||||
class value;
|
||||
void pack( fc::value& , const fc::ip::endpoint& );
|
||||
void unpack( const fc::value& , fc::ip::endpoint& );
|
||||
class variant;
|
||||
void to_variant( const ip::endpoint& var, variant& vo );
|
||||
void from_variant( const variant& var, ip::endpoint& vo );
|
||||
|
||||
void to_variant( const ip::address& var, variant& vo );
|
||||
void from_variant( const variant& var, ip::address& vo );
|
||||
}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
#pragma once
|
||||
#include <fc/utility.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/iostream.hpp>
|
||||
#include <fc/io/iostream.hpp>
|
||||
|
||||
namespace fc {
|
||||
namespace ip { class endpoint; }
|
||||
class tcp_socket : public iostream {
|
||||
class tcp_socket : public virtual iostream
|
||||
{
|
||||
public:
|
||||
tcp_socket();
|
||||
~tcp_socket();
|
||||
|
|
@ -15,13 +16,12 @@ namespace fc {
|
|||
/// istream interface
|
||||
/// @{
|
||||
virtual size_t readsome( char* buffer, size_t max );
|
||||
virtual istream& read( char* buffer, size_t s );
|
||||
virtual bool eof()const;
|
||||
/// @}
|
||||
|
||||
/// ostream interface
|
||||
/// @{
|
||||
virtual ostream& write( const char* buffer, size_t len );
|
||||
virtual size_t writesome( const char* buffer, size_t len );
|
||||
virtual void flush();
|
||||
virtual void close();
|
||||
/// @}
|
||||
|
|
@ -33,8 +33,11 @@ namespace fc {
|
|||
class impl;
|
||||
fc::fwd<impl,0x44> my;
|
||||
};
|
||||
typedef std::shared_ptr<tcp_socket> tcp_socket_ptr;
|
||||
|
||||
class tcp_server {
|
||||
|
||||
class tcp_server
|
||||
{
|
||||
public:
|
||||
tcp_server();
|
||||
~tcp_server();
|
||||
106
include/fc/network/url.hpp
Normal file
106
include/fc/network/url.hpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#pragma once
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <stdint.h>
|
||||
#include <fc/filesystem.hpp>
|
||||
#include <fc/variant_object.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace fc {
|
||||
|
||||
typedef fc::optional<fc::string> ostring;
|
||||
typedef fc::optional<fc::path> opath;
|
||||
typedef fc::optional<fc::variant_object> ovariant_object;
|
||||
|
||||
namespace detail { class url_impl; }
|
||||
|
||||
class mutable_url;
|
||||
|
||||
/**
|
||||
* Used to pass an immutable URL and
|
||||
* query its parts.
|
||||
*/
|
||||
class url
|
||||
{
|
||||
public:
|
||||
url();
|
||||
explicit url( const string& u );
|
||||
url( const url& c );
|
||||
url( url&& c );
|
||||
url( mutable_url&& c );
|
||||
url( const mutable_url& c );
|
||||
~url();
|
||||
|
||||
url& operator=( const url& c );
|
||||
url& operator=( url&& c );
|
||||
|
||||
url& operator=( const mutable_url& c );
|
||||
url& operator=( mutable_url&& c );
|
||||
|
||||
bool operator==( const url& cmp )const;
|
||||
|
||||
operator string()const;
|
||||
|
||||
//// file, ssh, tcp, http, ssl, etc...
|
||||
string proto()const;
|
||||
ostring host()const;
|
||||
ostring user()const;
|
||||
ostring pass()const;
|
||||
opath path()const;
|
||||
ovariant_object args()const;
|
||||
fc::optional<uint16_t> port()const;
|
||||
|
||||
private:
|
||||
friend class mutable_url;
|
||||
std::shared_ptr<detail::url_impl> my;
|
||||
};
|
||||
|
||||
void to_variant( const url& u, fc::variant& v );
|
||||
void from_variant( const fc::variant& v, url& u );
|
||||
|
||||
/**
|
||||
* Used to create / manipulate a URL
|
||||
*/
|
||||
class mutable_url
|
||||
{
|
||||
public:
|
||||
mutable_url();
|
||||
explicit mutable_url( const string& mutable_url );
|
||||
mutable_url( const mutable_url& c );
|
||||
mutable_url( const url& c );
|
||||
mutable_url( mutable_url&& c );
|
||||
~mutable_url();
|
||||
|
||||
mutable_url& operator=( const url& c );
|
||||
mutable_url& operator=( const mutable_url& c );
|
||||
mutable_url& operator=( mutable_url&& c );
|
||||
|
||||
bool operator==( const mutable_url& cmp )const;
|
||||
bool operator==( const url& cmp )const;
|
||||
|
||||
operator string()const;
|
||||
|
||||
//// file, ssh, tcp, http, ssl, etc...
|
||||
string proto()const;
|
||||
ostring host()const;
|
||||
ostring user()const;
|
||||
ostring pass()const;
|
||||
opath path()const;
|
||||
ovariant_object args()const;
|
||||
fc::optional<uint16_t> port()const;
|
||||
|
||||
void set_proto( string );
|
||||
void set_host( string );
|
||||
void set_user( string );
|
||||
void set_pass( string );
|
||||
void set_path( fc::path p );
|
||||
void set_args( variant_object );
|
||||
void set_port( uint16_t );
|
||||
|
||||
private:
|
||||
friend class url;
|
||||
std::unique_ptr<detail::url_impl> my;
|
||||
};
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
namespace fc {
|
||||
template<typename T, typename R>
|
||||
T numeric_cast( const R& v ) {
|
||||
// TODO: do something smarter here, check ranges, etc
|
||||
return static_cast<T>(v);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,12 @@ namespace fc {
|
|||
* Simply including boost::optional adds 35,000 lines to each object file, using
|
||||
* fc::optional adds less than 400.
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4521) /* multiple copy ctors */
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
class optional {
|
||||
public:
|
||||
|
|
@ -20,6 +26,12 @@ namespace fc {
|
|||
_valid = o._valid;
|
||||
}
|
||||
|
||||
optional( optional& o )
|
||||
:_valid(false) {
|
||||
if( o._valid ) new (&**this) T( *o );
|
||||
_valid = o._valid;
|
||||
}
|
||||
|
||||
optional( optional&& o )
|
||||
:_valid(false) {
|
||||
if( o._valid ) new (&**this) T( fc::move(*o) );
|
||||
|
|
@ -39,22 +51,35 @@ namespace fc {
|
|||
new (&**this) T( fc::forward<U>(u) );
|
||||
_valid = true;
|
||||
} else {
|
||||
**this = fc::forward<U>(u);
|
||||
**this = static_cast<T>(fc::forward<U>(u));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
optional& operator=( const optional& o ) {
|
||||
if( _valid && o._valid ) { **this = *o; }
|
||||
else if( !_valid && o._valid ) {
|
||||
*this = *o;
|
||||
} // else !_valid && !o._valid == same!
|
||||
if (this != &o) {
|
||||
if( _valid && o._valid ) {
|
||||
**this = *o;
|
||||
} else if( !_valid && o._valid ) {
|
||||
*this = *o;
|
||||
} else if (_valid) {
|
||||
(**this).~T();
|
||||
_valid = false;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
optional& operator=( optional&& o ) {
|
||||
if( _valid && o._valid ) { **this = fc::move(*o); }
|
||||
else if( !_valid && o._valid ) {
|
||||
*this = fc::move(*o);
|
||||
if (this != &o) {
|
||||
if( _valid && o._valid ) {
|
||||
**this = fc::move(*o);
|
||||
} else if ( !_valid && o._valid ) {
|
||||
*this = fc::move(*o);
|
||||
} else if (_valid) {
|
||||
(**this).~T();
|
||||
_valid = false;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -91,5 +116,9 @@ namespace fc {
|
|||
return !left || *left != u;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace fc
|
||||
|
||||
|
|
|
|||
|
|
@ -1,155 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/sha1.hpp>
|
||||
#include <fc/vector.hpp>
|
||||
#include <fc/reflect.hpp>
|
||||
|
||||
/**
|
||||
* Define common crypto methods and data types to abstract underlying implementation.
|
||||
*/
|
||||
namespace fc {
|
||||
|
||||
template<uint32_t KeySize=2048>
|
||||
struct signature {
|
||||
char data[KeySize/8];
|
||||
template<typename T,uint32_t KS>
|
||||
friend T& operator<<( T& ds, const fc::signature<KS>& sig )
|
||||
{
|
||||
ds.write(sig.data, KS/8 );
|
||||
return ds;
|
||||
}
|
||||
template<typename T,uint32_t KS>
|
||||
friend T& operator>>( T& ds, fc::signature<KS>& sig )
|
||||
{
|
||||
ds.read(sig.data, KS/8 );
|
||||
return ds;
|
||||
}
|
||||
bool operator != ( const signature& s )const {
|
||||
return memcmp( s.data, data, sizeof(data) ) != 0;
|
||||
}
|
||||
bool operator == ( const signature& s )const {
|
||||
return memcmp( s.data, data, sizeof(data) ) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
bool verify_data( const char* key, uint32_t key_size, uint32_t pe, const sha1& hc, const char* sig );
|
||||
bool sign_data( const fc::vector<char>& key, uint32_t key_size, uint32_t pe, const sha1& hc, char* sig );
|
||||
bool public_encrypt( const char* key, uint32_t key_size, uint32_t pe, const fc::vector<char>& in, fc::vector<char>& out );
|
||||
bool public_decrypt( const char* key, uint32_t key_size, uint32_t pe, const fc::vector<char>& in, fc::vector<char>& out );
|
||||
bool private_encrypt( const fc::vector<char>& key, uint32_t key_size, uint32_t pe, const fc::vector<char>& in, fc::vector<char>& out );
|
||||
bool private_decrypt( const fc::vector<char>& key, uint32_t key_size, uint32_t pe, const fc::vector<char>& in, fc::vector<char>& out );
|
||||
bool generate_keys( char* pubkey, fc::vector<char>& privkey, uint32_t key_size, uint32_t pe );
|
||||
|
||||
template<uint32_t KeySize = 2048, uint32_t PublicExponent = 65537>
|
||||
struct private_key;
|
||||
|
||||
template<uint32_t KeySize = 2048, uint32_t PublicExponent = 65537>
|
||||
struct public_key {
|
||||
public_key() { memset( key, 0, sizeof(key) ); }
|
||||
public_key( const public_key& pk ) { memcpy( key, pk.key, sizeof(key) ); }
|
||||
|
||||
bool verify( const sha1& digest, const signature<KeySize>& sig )const {
|
||||
return verify_data( key, sizeof(key), PublicExponent, digest, sig.data );
|
||||
}
|
||||
bool encrypt( const fc::vector<char>& in, fc::vector<char>& out )const {
|
||||
return public_encrypt( key, KeySize, PublicExponent, in, out );
|
||||
}
|
||||
bool decrypt( const fc::vector<char>& in, fc::vector<char>& out )const {
|
||||
return public_decrypt( key, KeySize, PublicExponent, in, out );
|
||||
}
|
||||
|
||||
public_key& operator = ( const public_key& pk ) {
|
||||
memcpy( key, pk.key, sizeof(key) );
|
||||
return *this;
|
||||
}
|
||||
bool operator == ( const public_key& pk )const {
|
||||
return 0 == memcmp( key, pk.key, sizeof(key) );
|
||||
}
|
||||
bool operator != ( const public_key& pk )const {
|
||||
return 0 != memcmp( key, pk.key, sizeof(key) );
|
||||
}
|
||||
bool operator > ( const public_key& pk )const {
|
||||
return memcmp( key, pk.key, sizeof(key) ) > 0;
|
||||
}
|
||||
bool operator < ( const public_key& pk )const {
|
||||
return memcmp( key, pk.key, sizeof(key) ) < 0;
|
||||
}
|
||||
|
||||
template<typename T,uint32_t KS, uint32_t PE>
|
||||
inline friend T& operator<<( T& ds, const fc::public_key<KS,PE>& pk ) {
|
||||
ds.write(pk.key, KS/8 );
|
||||
return ds;
|
||||
}
|
||||
template<typename T,uint32_t KS, uint32_t PE>
|
||||
inline friend T& operator>>( T& ds, fc::public_key<KS,PE>& pk ) {
|
||||
ds.read( pk.key, KS/8 );
|
||||
return ds;
|
||||
}
|
||||
|
||||
private:
|
||||
template<uint32_t KS, uint32_t PE>
|
||||
friend void generate_keys( public_key<KS,PE>& pub, private_key<KS,PE>& priv );
|
||||
|
||||
char key[KeySize/8];
|
||||
};
|
||||
|
||||
|
||||
template<uint32_t KeySize, uint32_t PublicExponent>
|
||||
struct private_key {
|
||||
bool encrypt( const fc::vector<char>& in, fc::vector<char>& out )const {
|
||||
return private_encrypt( key, KeySize, PublicExponent, in, out );
|
||||
}
|
||||
bool decrypt( const fc::vector<char>& in, fc::vector<char>& out )const {
|
||||
return private_decrypt( key, KeySize, PublicExponent, in, out );
|
||||
}
|
||||
bool sign( const sha1& digest, signature<KeySize>& sig )const {
|
||||
return sign_data( key, KeySize, PublicExponent, digest, sig.data );
|
||||
}
|
||||
|
||||
template<typename T,uint32_t KS, uint32_t PE>
|
||||
friend T& operator<<( T& ds, const fc::private_key<KS,PE>& pk ) {
|
||||
uint16_t s = pk.key.size();
|
||||
ds.write( (const char*)&s, sizeof(s) );
|
||||
ds.write( pk.key.data(), pk.key.size() );
|
||||
return ds;
|
||||
}
|
||||
template<typename T,uint32_t KS, uint32_t PE>
|
||||
friend T& operator>>( T& ds, fc::private_key<KS,PE>& pk ) {
|
||||
uint16_t s;
|
||||
ds.read((char*)&s,sizeof(s) );
|
||||
pk.key.resize(s);
|
||||
ds.read( pk.key.data(), pk.key.size() );
|
||||
return ds;
|
||||
}
|
||||
private:
|
||||
template<uint32_t KS, uint32_t PE>
|
||||
friend void generate_keys( public_key<KS,PE>& pub, private_key<KS,PE>& priv );
|
||||
fc::vector<char> key;
|
||||
};
|
||||
|
||||
template<uint32_t KeySize, uint32_t PublicExponent>
|
||||
void generate_keys( public_key<KeySize,PublicExponent>& pub, private_key<KeySize,PublicExponent>& priv ) {
|
||||
generate_keys( pub.key, priv.key, KeySize, PublicExponent );
|
||||
}
|
||||
/*
|
||||
template<uint32_t KeySize>
|
||||
inline std::ostream& operator<< ( std::ostream& os, const signature<KeySize>& s ) {
|
||||
for( uint32_t i = 0; i < KeySize; ++i )
|
||||
os << std::hex << int(s.data[i]) << ' ';
|
||||
return os;
|
||||
}
|
||||
*/
|
||||
|
||||
typedef public_key<> public_key_t;
|
||||
typedef private_key<> private_key_t;
|
||||
typedef signature<> signature_t;
|
||||
|
||||
class value;
|
||||
void pack( fc::value& , const fc::signature_t& );
|
||||
void unpack( const fc::value& , fc::signature_t& );
|
||||
void pack( fc::value& , const fc::public_key_t& );
|
||||
void unpack( const fc::value& , fc::private_key_t& );
|
||||
void pack( fc::value& , const fc::private_key_t& );
|
||||
void unpack( const fc::value& , fc::public_key_t& );
|
||||
} // namespace fc
|
||||
|
||||
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/shared_impl.hpp>
|
||||
#include <fc/future.hpp>
|
||||
#include <fc/string.hpp>
|
||||
|
||||
namespace fc {
|
||||
class istream;
|
||||
class ostream;
|
||||
class path;
|
||||
template<typename> class vector;
|
||||
|
||||
fc::path find_executable_in_path( const fc::string name );
|
||||
|
||||
/**
|
||||
* @brief start and manage an external process
|
||||
*
|
||||
* @note this class implements reference semantics.
|
||||
*/
|
||||
class process {
|
||||
public:
|
||||
enum exec_opts {
|
||||
open_none = 0,
|
||||
open_stdin = 0x01,
|
||||
open_stdout = 0x02,
|
||||
open_stderr = 0x04,
|
||||
open_all = open_stdin|open_stdout|open_stderr,
|
||||
};
|
||||
|
||||
/**
|
||||
* Return a new process executing the specified exe with the specified args.
|
||||
*/
|
||||
fc::future<int> exec( const fc::path& exe, int opt = open_all );
|
||||
fc::future<int> exec( const fc::path& exe, const fc::path& wd, int opt = open_all );
|
||||
fc::future<int> exec( const fc::path& exe, fc::vector<fc::string>&& args , int opt = open_all );
|
||||
fc::future<int> exec( const fc::path& exe, fc::vector<fc::string>&& args, const fc::path& wd, int opt = open_all );
|
||||
|
||||
/**
|
||||
* Forcefully kills the process.
|
||||
*/
|
||||
void kill();
|
||||
|
||||
/**
|
||||
* @brief returns a stream that writes to the process' stdin
|
||||
*/
|
||||
fc::ostream& in_stream();
|
||||
|
||||
/**
|
||||
* @brief returns a stream that reads from the process' stdout
|
||||
*/
|
||||
fc::istream& out_stream();
|
||||
/**
|
||||
* @brief returns a stream that reads from the process' stderr
|
||||
*/
|
||||
fc::istream& err_stream();
|
||||
|
||||
FC_REFERENCE_TYPE(process)
|
||||
};
|
||||
|
||||
} // namespace fc
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
#ifndef _FC_PROGRAM_OPTIONS_HPP_
|
||||
#define _FC_PROGRAM_OPTIONS_HPP_
|
||||
#include <fc/optional.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fc/fwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace program_options {
|
||||
class variables_map;
|
||||
}
|
||||
}
|
||||
|
||||
namespace fc {
|
||||
class ostream;
|
||||
|
||||
namespace program_options {
|
||||
template<typename T>
|
||||
class value {
|
||||
public:
|
||||
value( T* v ):_v(v){}
|
||||
value& default_value( const T& d ) { _default = d; }
|
||||
|
||||
T* get()const { return _v; }
|
||||
private:
|
||||
fc::optional<T> _default;
|
||||
T* _v;
|
||||
};
|
||||
|
||||
class options_description {
|
||||
public:
|
||||
options_description( const char* c );
|
||||
~options_description();
|
||||
|
||||
options_description& add_options();
|
||||
options_description& operator()( const char* o, const char* desc );
|
||||
options_description& operator()( const char* o, const value<fc::string>&, const char* desc );
|
||||
options_description& operator()( const char* o, const value<uint16_t>&, const char* desc );
|
||||
options_description& operator()( const char* o, const value<std::vector<std::string> >&, const char* desc );
|
||||
|
||||
private:
|
||||
class impl;
|
||||
fwd<impl,104> my;
|
||||
|
||||
friend class variables_map;
|
||||
friend fc::ostream& operator<<( fc::ostream& o, const options_description& );
|
||||
};
|
||||
|
||||
class variables_map {
|
||||
public:
|
||||
variables_map();
|
||||
~variables_map();
|
||||
|
||||
void parse_command_line( int argc, char** argv, const options_description& d );
|
||||
int count( const char* opt );
|
||||
private:
|
||||
class impl;
|
||||
fwd<impl,160> my;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif // _FC_PROGRAM_OPTIONS_HPP_
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
|
||||
#pragma once
|
||||
/**
|
||||
* @file fc/reflect.hpp
|
||||
*
|
||||
* @brief Defines types and macros used to provide reflection.
|
||||
*
|
||||
*/
|
||||
#ifndef _FC_REFLECT_HPP_
|
||||
#define _FC_REFLECT_HPP_
|
||||
|
||||
#include <fc/utility.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
|
|
@ -16,8 +14,7 @@
|
|||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <fc/exception.hpp>
|
||||
#include <fc/typename.hpp>
|
||||
#include <fc/reflect/typename.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
|
|
@ -41,7 +38,7 @@ struct reflector{
|
|||
*
|
||||
* @code
|
||||
* struct functor {
|
||||
* template<typename MemberPtr, MemberPtr m>
|
||||
* template<typename Member, class Class, Member (Class::*member)>
|
||||
* void operator()( const char* name )const;
|
||||
* };
|
||||
* @endcode
|
||||
|
|
@ -90,7 +87,7 @@ void throw_bad_enum_cast( const char* k, const char* e );
|
|||
|
||||
|
||||
#define FC_REFLECT_BASE_MEMBER_COUNT( r, OP, elem ) \
|
||||
OP fc::reflector<elem>::member_count
|
||||
OP fc::reflector<elem>::total_member_count
|
||||
|
||||
#define FC_REFLECT_DERIVED_IMPL_INLINE( TYPE, INHERITS, MEMBERS ) \
|
||||
template<typename Visitor>\
|
||||
|
|
@ -207,4 +204,3 @@ template<> struct reflector<TYPE> {\
|
|||
|
||||
|
||||
|
||||
#endif
|
||||
99
include/fc/reflect/variant.hpp
Normal file
99
include/fc/reflect/variant.hpp
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
#pragma once
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
#include <fc/variant_object.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
template<typename T>
|
||||
void to_variant( const T& o, variant& v );
|
||||
template<typename T>
|
||||
void from_variant( const variant& v, T& o );
|
||||
|
||||
|
||||
template<typename T>
|
||||
class to_variant_visitor
|
||||
{
|
||||
public:
|
||||
to_variant_visitor( mutable_variant_object& mvo, const T& v )
|
||||
:vo(mvo),val(v){}
|
||||
|
||||
template<typename Member, class Class, Member (Class::*member)>
|
||||
void operator()( const char* name )const
|
||||
{
|
||||
vo(name,(val.*member));
|
||||
}
|
||||
|
||||
mutable_variant_object& vo;
|
||||
const T& val;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class from_variant_visitor
|
||||
{
|
||||
public:
|
||||
from_variant_visitor( const variant_object& _vo, T& v )
|
||||
:vo(_vo),val(v){}
|
||||
|
||||
template<typename Member, class Class, Member (Class::*member)>
|
||||
void operator()( const char* name )const
|
||||
{
|
||||
auto itr = vo.find(name);
|
||||
if( itr != vo.end() )
|
||||
from_variant( itr->value(), val.*member );
|
||||
}
|
||||
|
||||
const variant_object& vo;
|
||||
T& val;
|
||||
};
|
||||
|
||||
template<typename IsReflected=fc::false_type>
|
||||
struct if_enum
|
||||
{
|
||||
template<typename T>
|
||||
static inline void to_variant( const T& v, fc::variant& vo )
|
||||
{
|
||||
mutable_variant_object mvo;
|
||||
fc::reflector<T>::visit( to_variant_visitor<T>( mvo, v ) );
|
||||
vo = fc::move(mvo);
|
||||
}
|
||||
template<typename T>
|
||||
static inline void from_variant( const fc::variant& v, T& o )
|
||||
{
|
||||
const variant_object& vo = v.get_object();
|
||||
fc::reflector<T>::visit( from_variant_visitor<T>( vo, o ) );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct if_enum<fc::true_type>
|
||||
{
|
||||
template<typename T>
|
||||
static inline void to_variant( const T& o, fc::variant& v )
|
||||
{
|
||||
v = fc::reflector<T>::to_string(o);
|
||||
}
|
||||
template<typename T>
|
||||
static inline void from_variant( const fc::variant& v, T& o )
|
||||
{
|
||||
if( v.is_string() )
|
||||
o = fc::reflector<T>::from_string( v.get_string().c_str() );
|
||||
else
|
||||
// throw if invalid int, by attempting to convert to string
|
||||
fc::reflector<T>::to_string( o = static_cast<T>(v.as_int64()) );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
void to_variant( const T& o, variant& v )
|
||||
{
|
||||
if_enum<typename fc::reflector<T>::is_enum>::to_variant( o, v );
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void from_variant( const variant& v, T& o )
|
||||
{
|
||||
if_enum<typename fc::reflector<T>::is_enum>::from_variant( v, o );
|
||||
}
|
||||
|
||||
}
|
||||
140
include/fc/rpc/json_connection.hpp
Normal file
140
include/fc/rpc/json_connection.hpp
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
#pragma once
|
||||
#include <fc/io/buffered_iostream.hpp>
|
||||
#include <fc/variant_object.hpp>
|
||||
#include <fc/thread/future.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace fc { namespace rpc {
|
||||
|
||||
namespace detail { class json_connection_impl; }
|
||||
|
||||
/**
|
||||
* @brief Implements JSON-RPC 2.0 over a set of io streams
|
||||
*
|
||||
* Each JSON RPC message is expected to be on its own line, violators
|
||||
* will be prosecuted to the fullest extent of the law.
|
||||
*/
|
||||
class json_connection
|
||||
{
|
||||
public:
|
||||
typedef std::function<variant(const variants&)> method;
|
||||
typedef std::function<variant(const variant_object&)> named_param_method;
|
||||
|
||||
json_connection( fc::buffered_istream_ptr in, fc::buffered_ostream_ptr out );
|
||||
~json_connection();
|
||||
|
||||
/**
|
||||
* Starts processing messages from input
|
||||
*/
|
||||
future<void> exec();
|
||||
|
||||
logger get_logger()const;
|
||||
void set_logger( const logger& l );
|
||||
|
||||
/**
|
||||
* @name server interface
|
||||
*
|
||||
* Adding methods to the interface allows the remote side
|
||||
* to call them.
|
||||
*/
|
||||
///@{
|
||||
void add_method( const fc::string& name, method );
|
||||
void add_method( const fc::string& name, named_param_method );
|
||||
void remove_method( const fc::string& name );
|
||||
//@}
|
||||
|
||||
/**
|
||||
* @name client interface
|
||||
*/
|
||||
///@{
|
||||
void notice( const fc::string& method );
|
||||
void notice( const fc::string& method, const variants& args );
|
||||
void notice( const fc::string& method, const variant_object& named_args );
|
||||
|
||||
/// args will be handled as named params
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variant_object& args );
|
||||
|
||||
future<variant> async_call( const fc::string& method, mutable_variant_object args );
|
||||
|
||||
/// Sending in an array of variants will be handled as positional arguments
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variants& args );
|
||||
|
||||
future<variant> async_call( const fc::string& method );
|
||||
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variant& a1 );
|
||||
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2 );
|
||||
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3 );
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
const variant& a1,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
variant_object a1,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, fc::move(a1) ).wait(timeout).as<Result>();
|
||||
}
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
mutable_variant_object a1,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, variant_object( fc::move(a1) ) ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method, microseconds timeout = microseconds::maximum() )
|
||||
{
|
||||
return async_call( method ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
/// Sending in a variant_object will be issued as named parameters
|
||||
variant call( const fc::string& method, const variant_object& named_args );
|
||||
///@}
|
||||
|
||||
private:
|
||||
std::unique_ptr<detail::json_connection_impl> my;
|
||||
};
|
||||
typedef std::shared_ptr<json_connection> json_connection_ptr;
|
||||
|
||||
}} // fc::rpc
|
||||
|
||||
|
||||
|
||||
140
include/fc/rpc/variant_connection.hpp
Normal file
140
include/fc/rpc/variant_connection.hpp
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
#pragma once
|
||||
#include <fc/io/buffered_iostream.hpp>
|
||||
#include <fc/variant_object.hpp>
|
||||
#include <fc/thread/future.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <functional>
|
||||
|
||||
namespace fc { namespace rpc {
|
||||
|
||||
namespace detail { class variant_connection_impl; }
|
||||
|
||||
/**
|
||||
* @brief Implements JSON-RPC 2.0 over a set of io streams
|
||||
*
|
||||
* Each JSON RPC message is expected to be on its own line, violators
|
||||
* will be prosecuted to the fullest extent of the law.
|
||||
*/
|
||||
class variant_connection
|
||||
{
|
||||
public:
|
||||
typedef std::function<variant(const variants&)> method;
|
||||
typedef std::function<variant(const variant_object&)> named_param_method;
|
||||
|
||||
variant_connection( fc::variant_stream::ptr in, fc::variant_stream::ptr out );
|
||||
~variant_connection();
|
||||
|
||||
/**
|
||||
* Starts processing messages from input
|
||||
*/
|
||||
future<void> exec();
|
||||
|
||||
logger get_logger()const;
|
||||
void set_logger( const logger& l );
|
||||
|
||||
/**
|
||||
* @name server interface
|
||||
*
|
||||
* Adding methods to the interface allows the remote side
|
||||
* to call them.
|
||||
*/
|
||||
///@{
|
||||
void add_method( const fc::string& name, method );
|
||||
void add_method( const fc::string& name, named_param_method );
|
||||
void remove_method( const fc::string& name );
|
||||
//@}
|
||||
|
||||
/**
|
||||
* @name client interface
|
||||
*/
|
||||
///@{
|
||||
void notice( const fc::string& method );
|
||||
void notice( const fc::string& method, const variants& args );
|
||||
void notice( const fc::string& method, const variant_object& named_args );
|
||||
|
||||
/// args will be handled as named params
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variant_object& args );
|
||||
|
||||
future<variant> async_call( const fc::string& method, mutable_variant_object args );
|
||||
|
||||
/// Sending in an array of variants will be handled as positional arguments
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variants& args );
|
||||
|
||||
future<variant> async_call( const fc::string& method );
|
||||
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variant& a1 );
|
||||
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2 );
|
||||
|
||||
future<variant> async_call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3 );
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
const variant& a3,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2, a3 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
const variant& a1,
|
||||
const variant& a2,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1, a2 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
const variant& a1,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, a1 ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
variant_object a1,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, fc::move(a1) ).wait(timeout).as<Result>();
|
||||
}
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method,
|
||||
mutable_variant_object a1,
|
||||
microseconds timeout = microseconds::maximum())
|
||||
{
|
||||
return async_call( method, variant_object( fc::move(a1) ) ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
|
||||
template<typename Result>
|
||||
Result call( const fc::string& method, microseconds timeout = microseconds::maximum() )
|
||||
{
|
||||
return async_call( method ).wait(timeout).as<Result>();
|
||||
}
|
||||
|
||||
/// Sending in a variant_object will be issued as named parameters
|
||||
variant call( const fc::string& method, const variant_object& named_args );
|
||||
///@}
|
||||
|
||||
private:
|
||||
std::unique_ptr<detail::variant_connection_impl> my;
|
||||
};
|
||||
typedef std::shared_ptr<variant_connection> variant_connection_ptr;
|
||||
|
||||
}} // fc::rpc
|
||||
|
||||
|
||||
|
||||
36
include/fc/rpc/variant_stream.hpp
Normal file
36
include/fc/rpc/variant_stream.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
namespace fc
|
||||
{
|
||||
|
||||
/**
|
||||
* Thread-safe, circular buffer for passing variants
|
||||
* between threads.
|
||||
*/
|
||||
class variant_stream
|
||||
{
|
||||
public:
|
||||
variant_stream( size_t s );
|
||||
~variant_stream();
|
||||
|
||||
/** producer api */
|
||||
int64_t free(); // number of spaces available
|
||||
int64_t claim( int64_t num );
|
||||
int64_t publish( int64_t pos );
|
||||
int64_t wait_free(); // wait for free space
|
||||
|
||||
// producer/consumer api
|
||||
variant& get( int64_t pos );
|
||||
|
||||
/** consumer api */
|
||||
int64_t begin(); // returns the first index ready to be read
|
||||
int64_t end(); // returns the first index that cannot be read
|
||||
int64_t wait(); // wait for variants to be posted
|
||||
|
||||
private:
|
||||
std::vector<variant> _variants;
|
||||
uint64_t _read_pos;
|
||||
uint64_t _write_pos;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
|
||||
|
||||
class istream {
|
||||
public:
|
||||
template<typename T>
|
||||
istream( T& s ) {
|
||||
|
||||
}
|
||||
|
||||
istream& read( char* buf, uint64_t s );
|
||||
int64_t readsome( char* buf, uint64_t s );
|
||||
bool eof()const;
|
||||
|
||||
private:
|
||||
struct vtable {
|
||||
void* (*read)(void*, char* buf, uint64_t s );
|
||||
int64_t (*readsome)(void*, char* buf, uint64_t s );
|
||||
bool (*eof)(void* )
|
||||
};
|
||||
|
||||
vtable& _vtable;
|
||||
void* _stream;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/reflect.hpp>
|
||||
|
||||
namespace fc {
|
||||
class path;
|
||||
|
||||
class sha1 {
|
||||
public:
|
||||
sha1();
|
||||
explicit sha1( const fc::string& hex_str );
|
||||
|
||||
fc::string str()const;
|
||||
|
||||
operator fc::string()const;
|
||||
|
||||
char* data()const;
|
||||
|
||||
static sha1 hash( const char* d, uint32_t dlen );
|
||||
static sha1 hash( const fc::string& );
|
||||
static sha1 hash( const fc::path& );
|
||||
|
||||
template<typename T>
|
||||
static sha1 hash( const T& t ) { sha1::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();
|
||||
sha1 result();
|
||||
|
||||
private:
|
||||
struct impl;
|
||||
fwd<impl,96> my;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator<<( T& ds, const sha1& ep ) {
|
||||
ds.write( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator>>( T& ds, sha1& ep ) {
|
||||
ds.read( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
friend sha1 operator << ( const sha1& h1, uint32_t i );
|
||||
friend bool operator == ( const sha1& h1, const sha1& h2 );
|
||||
friend bool operator != ( const sha1& h1, const sha1& h2 );
|
||||
friend sha1 operator ^ ( const sha1& h1, const sha1& h2 );
|
||||
friend bool operator >= ( const sha1& h1, const sha1& h2 );
|
||||
friend bool operator > ( const sha1& h1, const sha1& h2 );
|
||||
friend bool operator < ( const sha1& h1, const sha1& h2 );
|
||||
|
||||
uint32_t _hash[5];
|
||||
};
|
||||
|
||||
class value;
|
||||
void pack( fc::value& , const fc::sha1& );
|
||||
void unpack( const fc::value& , fc::sha1& );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/string.hpp>
|
||||
#include <fc/reflect.hpp>
|
||||
|
||||
namespace fc {
|
||||
class path;
|
||||
|
||||
class sha256 {
|
||||
public:
|
||||
sha256();
|
||||
explicit sha256( const fc::string& hex_str );
|
||||
|
||||
fc::string str()const;
|
||||
|
||||
operator fc::string()const;
|
||||
|
||||
char* data()const;
|
||||
|
||||
static sha256 hash( const char* d, uint32_t dlen );
|
||||
static sha256 hash( const fc::string& );
|
||||
static sha256 hash( const fc::path& );
|
||||
|
||||
template<typename T>
|
||||
static sha256 hash( const T& t ) { sha256::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();
|
||||
sha256 result();
|
||||
|
||||
private:
|
||||
struct impl;
|
||||
fwd<impl,96> my;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator<<( T& ds, const sha256& ep ) {
|
||||
ds.write( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline friend T& operator>>( T& ds, sha256& ep ) {
|
||||
ds.read( ep.data(), sizeof(ep) );
|
||||
return ds;
|
||||
}
|
||||
friend sha256 operator << ( const sha256& h1, uint32_t i );
|
||||
friend bool operator == ( const sha256& h1, const sha256& h2 );
|
||||
friend bool operator != ( const sha256& h1, const sha256& h2 );
|
||||
friend sha256 operator ^ ( const sha256& h1, const sha256& h2 );
|
||||
friend bool operator >= ( const sha256& h1, const sha256& h2 );
|
||||
friend bool operator > ( const sha256& h1, const sha256& h2 );
|
||||
friend bool operator < ( const sha256& h1, const sha256& h2 );
|
||||
|
||||
uint64_t _hash[4];
|
||||
};
|
||||
|
||||
class value;
|
||||
void pack( fc::value& , const fc::sha256& );
|
||||
void unpack( const fc::value& , fc::sha256& );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/shared_impl.hpp>
|
||||
|
||||
namespace fc {
|
||||
template<typename T>
|
||||
typename shared_impl<T>::impl& shared_impl<T>::operator* ()const { return *_impl; }
|
||||
|
||||
template<typename T>
|
||||
typename shared_impl<T>::impl* shared_impl<T>::operator-> ()const { return _impl.get(); }
|
||||
|
||||
template<typename T>
|
||||
template<typename U>
|
||||
shared_impl<T>::shared_impl( U&& u ):_impl(fc::forward<U>(u)){}
|
||||
|
||||
template<typename T>
|
||||
shared_impl<T>::shared_impl( const shared_impl<T>& u ):_impl(u._impl){}
|
||||
//template<typename T>
|
||||
//shared_impl<T>::shared_impl( shared_impl<T>& u ):_impl(u._impl){}
|
||||
|
||||
template<typename T>
|
||||
shared_impl<T>::shared_impl( shared_impl<T>&& u ):_impl(fc::move(u._impl)){}
|
||||
|
||||
template<typename T>
|
||||
shared_impl<T>& shared_impl<T>::operator=( shared_impl<T>&& u ) {
|
||||
fc_swap(_impl,u._impl);
|
||||
return *this;
|
||||
}
|
||||
template<typename T>
|
||||
shared_impl<T>& shared_impl<T>::operator=( const shared_impl<T>& u ) {
|
||||
_impl = u._impl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool shared_impl<T>::operator !()const { return !_impl; }
|
||||
|
||||
template<typename T>
|
||||
shared_impl<T>::~shared_impl(){}
|
||||
|
||||
}
|
||||
|
||||
#define FC_REFERENCE_TYPE_IMPL( TYPE ) \
|
||||
template<typename A1> \
|
||||
TYPE::TYPE( A1&& a1 ) \
|
||||
:my( new typename fc::shared_impl<TYPE>::impl( fc::forward<A1>(a1) ) ){}\
|
||||
template<typename A1,typename A2> \
|
||||
TYPE::TYPE( A1&& a1, A2&& a2 ) \
|
||||
:my( new typename fc::shared_impl<TYPE>::impl( fc::forward<A1>(a1), fc::forward<A2>(a2) ) ){}\
|
||||
template<typename A1,typename A2, typename A3> \
|
||||
TYPE::TYPE( A1&& a1, A2&& a2, A3&& a3 ) \
|
||||
:my( new fc::shared_impl<TYPE>::impl( fc::forward<A1>(a1), fc::forward<A2>(a2), fc::forward<A3>(a3) ) ){}\
|
||||
TYPE::TYPE( shared_impl<TYPE>::impl* m ) \
|
||||
:my(m){}\
|
||||
TYPE::TYPE( TYPE* c )\
|
||||
:my(fc::move(c->my)){ delete c; }\
|
||||
TYPE::TYPE( TYPE&& c )\
|
||||
:my(fc::move(c.my)){}\
|
||||
TYPE::TYPE( const TYPE& c )\
|
||||
:my(c.my){}\
|
||||
TYPE::TYPE() \
|
||||
:my( new fc::shared_impl<TYPE>::impl( ) ){}\
|
||||
TYPE::~TYPE(){}\
|
||||
bool TYPE::operator !()const { return !my; }\
|
||||
TYPE& TYPE::operator = ( const TYPE& c ) {\
|
||||
my = c.my;\
|
||||
return *this;\
|
||||
}\
|
||||
TYPE& TYPE::operator = ( TYPE&& c ) {\
|
||||
fc_swap( my._impl, c.my._impl );\
|
||||
return *this;\
|
||||
}\
|
||||
TYPE& TYPE::operator = ( TYPE* c ) {\
|
||||
fc_swap( my._impl, c->my._impl );\
|
||||
delete c;\
|
||||
return *this;\
|
||||
} \
|
||||
bool operator==( const TYPE& a, const TYPE& b ) {\
|
||||
return a.my._impl.get() == b.my._impl.get(); \
|
||||
} \
|
||||
bool operator!=( const TYPE& a, const TYPE& b ) {\
|
||||
return a.my._impl.get() != b.my._impl.get(); \
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
#pragma once
|
||||
#include <fc/shared_ptr.hpp>
|
||||
|
||||
namespace fc {
|
||||
/**
|
||||
* @class shared_impl<T>
|
||||
* @brief used to create types with reference semantics
|
||||
*
|
||||
* A type with reference semantics is effectively a shared pointer except that
|
||||
* it is used like a Java or C# type using '.' notation instead of -> notation.
|
||||
*
|
||||
* It is ideal for use with classes that almost always get managed by a shared
|
||||
* pointer (sockets and long-lived resources). These types are rarely, if ever
|
||||
* copied by value and often by-value copy or 'deep-copy' has no real meaning.
|
||||
*
|
||||
* An additional feature of shared_impl<T> is that your classes implementation
|
||||
* should be private and defined entirely in your source file. There should be
|
||||
* no member variables defined in your types header.
|
||||
*
|
||||
* To make this design pattern work requires a lot of 'boiler-plate' code for
|
||||
* handling assignments, moves, copies, etc that cannot be provided via tradtional
|
||||
* means such as templates or base classes.
|
||||
*
|
||||
* To create a new type with reference semantics you place FC_REFERENCE_TYPE(type)
|
||||
* inside the private section of 'type'. Then in your source file you will
|
||||
* need to define your 'private' data.
|
||||
*
|
||||
* @code
|
||||
* #include <your_type.hpp>
|
||||
*
|
||||
* FC_START_SHARED_IMPL( your_namespace::your_type )
|
||||
* impl( int x, int y ); // custom constructor
|
||||
*
|
||||
* ...
|
||||
* int member_variable;
|
||||
* your private member variables / methods go here.
|
||||
* ...
|
||||
* FC_END_SHARED_IMPL
|
||||
* #include <fc/shared_impl.cpp>
|
||||
* @endcode
|
||||
*
|
||||
*
|
||||
* Lastly, you will need to provide the implementation your class below. This
|
||||
* implementation will need to provide the matching implementations for the
|
||||
* methods declared by FC_REFERENCE_TYPE(type) in your header. To do this
|
||||
* use the FC_REFERENCE_TYPE_IMPL(type)
|
||||
*
|
||||
* @code
|
||||
* namespace your_namespace {
|
||||
* FC_REFERENCE_TYPE(your_type)
|
||||
* ... your methods here...
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* Within the body of your methods you can access your private data and members
|
||||
* via using 'my->member_variable'
|
||||
*
|
||||
* If you want to define custom constructors for your reference type, you will
|
||||
* need to implement them inside the FC_START_SHARED_IMPL block using the pattern:
|
||||
*
|
||||
* @code
|
||||
* FC_START_SHARED_IMPL( your_namespace::your_type )
|
||||
* impl( int x, int y ){} // custom constructor
|
||||
* FC_END_SHARED_IMPL
|
||||
* @code
|
||||
*
|
||||
* A limited number (3) of arguments are supported for custom constructors.
|
||||
*
|
||||
* Once you have defined your reference type you can use it like so:
|
||||
*
|
||||
* @code
|
||||
* your_type val = nullptr; // create a null type
|
||||
* your_type val2 = new your_type(...); // construct a new instance, unnecessary temporary heap alloc
|
||||
* your_type val3(...); // constructs a new instance, more effecient
|
||||
*
|
||||
* val2.your_method();
|
||||
* val2 = nullptr; // reset val2 to a null object
|
||||
*
|
||||
* val2 = val3; // val2 and val3 now reference the same data
|
||||
* if( !!val2 ){} // val2 is not null
|
||||
* else{} // val2 is null
|
||||
* @endcode
|
||||
*
|
||||
* As you can see, when creating types with this method your code will
|
||||
* look and act like a Java or C# garbage collected type.
|
||||
*
|
||||
* Often times your private methods will need to call your public methods, to achieve
|
||||
* this you can use the following techinque:
|
||||
*
|
||||
* @code
|
||||
* FC_START_SHARED_IMPL( your_namespace::your_type )
|
||||
* void private_method( int x, int y ){
|
||||
* auto s = self();
|
||||
* s.public_method();
|
||||
* }
|
||||
* FC_END_SHARED_IMPL
|
||||
* @code
|
||||
*
|
||||
* For performance reasons, it is best to only call 'self()' once and save the
|
||||
* result to avoid unnecessary copies of shared pointers which require atomic
|
||||
* operations.
|
||||
*
|
||||
*/
|
||||
template<typename T>
|
||||
struct shared_impl {
|
||||
class impl;
|
||||
impl& operator* ()const;
|
||||
impl* operator-> ()const;
|
||||
|
||||
bool operator !()const;
|
||||
|
||||
template<typename U>
|
||||
explicit shared_impl( U&& u );
|
||||
|
||||
shared_impl( const shared_impl& u );
|
||||
// shared_impl( shared_impl& u );
|
||||
shared_impl( shared_impl&& u );
|
||||
shared_impl& operator=( shared_impl&& u );
|
||||
shared_impl& operator=( const shared_impl& u );
|
||||
|
||||
~shared_impl();
|
||||
|
||||
fc::shared_ptr<typename shared_impl<T>::impl> _impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#define FC_REFERENCE_TYPE( TYPE ) \
|
||||
public:\
|
||||
TYPE(); \
|
||||
TYPE( std::nullptr_t ); \
|
||||
TYPE( TYPE* ); \
|
||||
TYPE( TYPE&& ); \
|
||||
TYPE( const TYPE& ); \
|
||||
template<typename A1> \
|
||||
TYPE( A1&& ); \
|
||||
template<typename A1,typename A2> \
|
||||
TYPE( A1&&, A2&& ); \
|
||||
template<typename A1,typename A2, typename A3> \
|
||||
TYPE( A1&&, A2&&, A3&& ); \
|
||||
~TYPE(); \
|
||||
bool operator !()const; \
|
||||
friend bool operator==( const TYPE& a, const TYPE& b ); \
|
||||
friend bool operator!=( const TYPE& a, const TYPE& b ); \
|
||||
TYPE& operator = ( const TYPE& ); \
|
||||
TYPE& operator = ( TYPE&& );\
|
||||
TYPE& operator = ( TYPE* );\
|
||||
TYPE& operator = ( std::nullptr_t );\
|
||||
private: \
|
||||
friend class shared_impl<TYPE>::impl; \
|
||||
TYPE( shared_impl<TYPE>::impl* m ); \
|
||||
shared_impl<TYPE> my;
|
||||
|
||||
#define FC_START_SHARED_IMPL( SCOPED_TYPE ) \
|
||||
namespace fc { \
|
||||
template<> \
|
||||
class fc::shared_impl<SCOPED_TYPE>::impl : public fc::retainable { \
|
||||
public:\
|
||||
SCOPED_TYPE self() { return SCOPED_TYPE(this); } \
|
||||
|
||||
|
||||
#define FC_END_SHARED_IMPL }; }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue