diff --git a/CMakeLists.txt b/CMakeLists.txt index a217780..fdf7fc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ set( sources src/log.cpp src/time.cpp src/iostream.cpp + src/fstream.cpp src/sstream.cpp src/exception.cpp src/thread.cpp diff --git a/include/fc/filesystem.hpp b/include/fc/filesystem.hpp index b7e5235..551dc42 100644 --- a/include/fc/filesystem.hpp +++ b/include/fc/filesystem.hpp @@ -64,6 +64,8 @@ namespace fc { void create_directories( const path& p ); 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 ); } #endif // _FC_FILESYSTEM_HPP_ diff --git a/include/fc/fstream.hpp b/include/fc/fstream.hpp index 349d6f9..1704e1e 100644 --- a/include/fc/fstream.hpp +++ b/include/fc/fstream.hpp @@ -1,16 +1,17 @@ #pragma once -#include +#include +#include namespace fc { - - class ofstream //: virtual public ostream { + class path; + class ofstream : virtual public ostream { public: enum mode { out, binary }; ofstream(); - ofstream( const fc::string& file, int m ); + ofstream( const fc::path& file, int m = binary ); ~ofstream(); - void open( const fc::string& file, int m ); + void open( const fc::path& file, int m = binary ); ofstream& write( const char* buf, size_t len ); void put( char c ); void close(); @@ -18,26 +19,23 @@ namespace fc { private: class impl; - fwd my; + fc::shared_ptr my; }; - class ifstream //: virtual public istream { + class ifstream : virtual public istream { public: enum mode { in, binary }; ifstream(); - ifstream( const fc::string& file, int m ); + ifstream( const fc::path& file, int m ); ~ifstream(); - void open( const fc::string& file, int m ); + void open( const fc::path& file, int m ); ifstream& read( char* buf, size_t len ); void close(); - void flush(); - bool eof()const; - private: class impl; - fwd my; + fc::shared_ptr my; }; } // namespace fc diff --git a/include/fc/json_rpc_connection.hpp b/include/fc/json_rpc_connection.hpp index a2d4ff0..f8369f3 100644 --- a/include/fc/json_rpc_connection.hpp +++ b/include/fc/json_rpc_connection.hpp @@ -115,7 +115,7 @@ namespace fc { namespace json { template void add_interface( const fc::ptr& it ) { - it->template visit( detail::add_method_visitor( it, *this ) ); + it->template visit( detail::add_method_visitor( it, *this ) ); } void add_method( const fc::string& name, const fc::json::rpc_server_method::ptr& func ); diff --git a/include/fc/sha1.hpp b/include/fc/sha1.hpp index cef850f..7d95e5b 100644 --- a/include/fc/sha1.hpp +++ b/include/fc/sha1.hpp @@ -4,6 +4,7 @@ #include namespace fc { + class path; class sha1 { public: @@ -18,6 +19,7 @@ namespace fc { static sha1 hash( const char* d, uint32_t dlen ); static sha1 hash( const fc::string& ); + static sha1 hash( const fc::path& ); template static sha1 hash( const T& t ) { sha1::encoder e; e << t; return e.result(); } diff --git a/include/fc/value.hpp b/include/fc/value.hpp index 11d1354..120d9f8 100644 --- a/include/fc/value.hpp +++ b/include/fc/value.hpp @@ -127,6 +127,14 @@ namespace fc { bool is_null()const; void visit( const_visitor&& v )const; + + /* sets the subkey key with v and return *this */ + value& set( const char* key, fc::value v ); + value& set( const fc::string& key, fc::value v ); + + template + value& set( S&& key, T&& v ) { return set( fc::forward(key), fc::value( fc::forward(v) ) ); } + private: /** throws exceptions on errors * diff --git a/src/filesystem.cpp b/src/filesystem.cpp index 10236b8..d56fa0e 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -75,4 +75,7 @@ namespace fc { bool is_directory( const path& p ) { return boost::filesystem::is_directory(p); } bool is_regular_file( const path& p ) { return boost::filesystem::is_regular_file(p); } uint64_t file_size( const path& p ) { return boost::filesystem::file_size(p); } + void copy( const path& f, const path& t ) { boost::filesystem::copy( f, t ); } + bool remove( const path& f ) { return boost::filesystem::remove( f ); } + fc::path canonical( const fc::path& p ) { return boost::filesystem::canonical(p); } } diff --git a/src/fstream.cpp b/src/fstream.cpp new file mode 100644 index 0000000..3295fdc --- /dev/null +++ b/src/fstream.cpp @@ -0,0 +1,60 @@ +#include +#include +#include + +namespace fc { + class ofstream::impl : public fc::retainable { + public: + std::ofstream ofs; + }; + class ifstream::impl : public fc::retainable { + public: + std::ifstream ifs; + }; + + ofstream::ofstream() + :my( new impl() ){} + + ofstream::ofstream( const fc::path& file, int m ) + :my( new impl() ) { this->open( file, m ); } + ofstream::~ofstream(){} + + void ofstream::open( const fc::path& file, int m ) { + my->ofs.open( file.string().c_str(), std::ios::binary ); + } + ofstream& ofstream::write( const char* buf, size_t len ) { + my->ofs.write(buf,len); + return *this; + } + void ofstream::put( char c ) { + my->ofs.put(c); + } + void ofstream::close() { + my->ofs.close(); + } + void ofstream::flush() { + my->ofs.flush(); + } + + ifstream::ifstream() + :my(new impl()){} + ifstream::ifstream( const fc::path& file, int m ) + :my(new impl()) + { + this->open( file, m ); + } + ifstream::~ifstream(){} + + void ifstream::open( const fc::path& file, int m ) { + my->ifs.open( file.string().c_str(), std::ios::binary ); + } + ifstream& ifstream::read( char* buf, size_t len ) { + my->ifs.read(buf,len); + return *this; + } + void ifstream::close() { return my->ifs.close(); } + + bool ifstream::eof()const { return my->ifs.eof(); } + + +} // namespace fc diff --git a/src/sha1.cpp b/src/sha1.cpp index 613e7e7..74ba66b 100644 --- a/src/sha1.cpp +++ b/src/sha1.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include namespace fc { @@ -36,6 +38,14 @@ namespace fc { sha1 sha1::hash( const fc::string& s ) { return hash( s.c_str(), s.size() ); } + sha1 sha1::hash( const fc::path& s ) { + file_mapping fmap( s.string().c_str(), read_only ); + size_t fsize = file_size(s); + mapped_region mr( fmap, fc::read_only, 0, fsize ); + + const char* pos = reinterpret_cast(mr.get_address()); + return hash( pos, fsize ); + } void sha1::encoder::write( const char* d, uint32_t dlen ) { SHA1_Update( &my->ctx, d, dlen); diff --git a/src/value.cpp b/src/value.cpp index a1c8a18..c29ac2a 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -48,6 +48,7 @@ namespace fc { struct value_holder_impl : value_holder { value_holder_impl(){}; // typedef void_t T; + /* virtual const char* type()const { return "void"; } virtual void visit( value::const_visitor&& v )const{ v(); } virtual void visit( value_visitor&& v ) { v(); } @@ -56,6 +57,7 @@ namespace fc { virtual value_holder* move_helper( char* c ){ return new(c) value_holder_impl(); } virtual value_holder* copy_helper( char* c )const{ return new(c) value_holder_impl();} + */ }; @@ -121,7 +123,10 @@ namespace fc { }; value_holder::~value_holder(){} - const char* value_holder::type()const { return "null"; } + const char* value_holder::type()const { return "void"; } + value_holder* value_holder::move_helper( char* c ) { return new(c) value_holder(); } + value_holder* value_holder::copy_helper( char* c )const { return new(c) value_holder(); } + void value_holder::visit( value::const_visitor&& v )const { v(); } void value_holder::visit( value_visitor&& v ) { v(); } @@ -133,8 +138,8 @@ namespace fc { const value& value_holder::at( size_t )const { FC_THROW_MSG("value type '%s' not an array", type()); return *((const value*)0); } void value_holder::push_back( value&& v ) { FC_THROW_MSG("value type '%s' not an array", type()); } - value_holder* value_holder::move_helper( char* c ) { return new(c) value_holder(); } - value_holder* value_holder::copy_helper( char* c )const{ return new(c) value_holder(); } + // value_holder* value_holder::move_helper( char* c ) = 0; + // value_holder* value_holder::copy_helper( char* c )const = 0; void value_holder_impl::resize( size_t s ) { val.fields.resize(s); } void value_holder_impl::reserve( size_t s ) { val.fields.reserve(s); } @@ -168,7 +173,7 @@ static const detail::value_holder* gh( const aligned<24>& h ) { } value::value() { - new (holder) detail::value_holder(); + new (holder) detail::value_holder_impl(); } value::value( value&& m ) { gh(m.holder)->move_helper(holder._store._data); @@ -271,7 +276,7 @@ value& value::operator=( const value& v ){ return *this; } bool value::is_null()const { - return strcmp(gh(holder)->type(), "null") == 0; + return strcmp(gh(holder)->type(), "void") == 0; } @@ -314,7 +319,7 @@ value& value::operator[]( const char* key ) { } o->val.fields.push_back( key_val(key) ); return o->val.fields.back().val; - } else if (strcmp(gh(holder)->type(), "null" ) == 0 ) { + } else if (strcmp(gh(holder)->type(), "void" ) == 0 ) { new (holder) detail::value_holder_impl(value::object()); return (*this)[key]; } @@ -359,5 +364,14 @@ void value::visit( value::const_visitor&& v )const { auto h = ((detail::value_holder*)&holder[0]); h->visit( fc::move(v) ); } +/* sets the subkey key with v and return *this */ +value& value::set( const char* key, fc::value v ) { + (*this)[key] = fc::move(v); + return *this; +} +value& value::set( const fc::string& key, fc::value v ) { + (*this)[key.c_str()] = fc::move(v); + return *this; +} } // namepace fc