From 74b904ecbd700b6d0e482ca9b59e4c47893d8bab Mon Sep 17 00:00:00 2001 From: Vladimir Stackov Date: Tue, 20 Jan 2015 17:55:58 +0300 Subject: [PATCH] Storable variables validator done --- compression.cc | 9 ++++---- compression.hh | 44 +++++++++++++++++------------------ config.cc | 63 ++++++++++++++++++++++++++++++++++---------------- config.hh | 4 ++-- 4 files changed, 72 insertions(+), 48 deletions(-) diff --git a/compression.cc b/compression.cc index f4cf934..151a240 100644 --- a/compression.cc +++ b/compression.cc @@ -584,10 +584,9 @@ bool LZO1X_1_Encoder::doProcessNoSize( const char* dataIn, size_t availIn, #endif // HAVE_LIBLZO - // register them -static const_sptr const compressions[] = { +const_sptr< CompressionMethod > const CompressionMethod::compressions[] = { new LZMACompression(), # ifdef HAVE_LIBLZO new LZO1X_1_Compression(), @@ -596,9 +595,11 @@ static const_sptr const compressions[] = { NULL }; -const_sptr CompressionMethod::selectedCompression = compressions[0]; +const_sptr< CompressionMethod > CompressionMethod::selectedCompression = + compressions[0]; -const_sptr CompressionMethod::findCompression( const std::string& name, bool optional ) +const_sptr< CompressionMethod > CompressionMethod::findCompression( + const std::string& name, bool optional ) { for ( const const_sptr* c = compressions+0; *c; ++c ) { diff --git a/compression.hh b/compression.hh index 66718b4..c7c17f3 100644 --- a/compression.hh +++ b/compression.hh @@ -8,12 +8,10 @@ #include "ex.hh" #include "nocopy.hh" - namespace Compression { DEF_EX( Ex, "Compression exception", std::exception ) -DEF_EX_STR( exUnsupportedCompressionMethod, "Unsupported compression method: ", Ex ) - +DEF_EX_STR( exUnsupportedCompressionMethod, "Unsupported compression method:", Ex ) // used for encoding or decoding class EnDecoder: NoCopy @@ -24,20 +22,20 @@ public: virtual ~EnDecoder(); // encoder can read up to size bytes from data - virtual void setInput ( const void* data, size_t size ) =0; + virtual void setInput ( const void * data, size_t size ) = 0; // how many bytes of the last input haven't been used, yet? - virtual size_t getAvailableInput() =0; + virtual size_t getAvailableInput() = 0; // encoder can write up to size bytes to output - virtual void setOutput( void* data, size_t size ) =0; + virtual void setOutput( void * data, size_t size ) = 0; // how many bytes of free space are remaining in the output buffer - virtual size_t getAvailableOutput() =0; + virtual size_t getAvailableOutput() = 0; // process some bytes // finish: will you pass more data to the encoder via setOutput? // NOTE You must eventually set finish to true. // returns, whether all output bytes have been written - virtual bool process( bool finish ) =0; + virtual bool process( bool finish ) = 0; }; // compression method @@ -48,38 +46,40 @@ public: // returns name of compression method // This name is saved in the file header of the compressed file. - virtual std::string getName() const =0; + virtual std::string getName() const = 0; - virtual sptr createEncoder() const =0; - virtual sptr createDecoder() const =0; + virtual sptr< EnDecoder > createEncoder() const = 0; + virtual sptr< EnDecoder > createDecoder() const = 0; // find a compression by name // If optional is false, it will either return a valid CompressionMethod // object or abort the program. If optional is true, it will return // NULL, if it cannot find the a compression with that name. - static const_sptr findCompression( - const std::string& name, bool optional = false ); + static const_sptr< CompressionMethod > findCompression( + const std::string & name, bool optional = false ); - static const_sptr selectedCompression; + static const_sptr< CompressionMethod > selectedCompression; + + static const_sptr< CompressionMethod > const compressions[]; class iterator { friend class CompressionMethod; - const const_sptr* ptr; - iterator( const const_sptr* ptr ); + const const_sptr< CompressionMethod > * ptr; + iterator( const const_sptr< CompressionMethod > * ptr ); public: - iterator( const iterator& it ); - iterator& operator =( const iterator& it ); + iterator( const iterator & it ); + iterator & operator =( const iterator & it ); - bool operator ==( const iterator& other ) const; - bool operator !=( const iterator& other ) const; + bool operator == ( const iterator & other ) const; + bool operator != ( const iterator & other ) const; bool atEnd() const; - iterator& operator ++(); + iterator & operator ++(); - const_sptr operator *(); + const_sptr< CompressionMethod > operator * (); }; static iterator begin(); static iterator end(); diff --git a/config.cc b/config.cc index c8ca48f..54c10e1 100644 --- a/config.cc +++ b/config.cc @@ -16,6 +16,21 @@ "MB - multiply by 1000*1000 (megabytes)\n" \ "GB - multiply by 1000*1000*1000 (gigabytes)\n" \ +#define SKIP_ON_VALIDATION \ +{ \ + if ( validate ) \ + return true; \ +} + +#define REQUIRE_VALUE \ +{ \ + if ( !hasValue && !validate ) \ + return false; \ +} + +#define PARSE_OR_VALIDATE( parse_src, validate_src ) \ + ( !validate && ( parse_src ) ) || ( validate && ( validate_src ) ) + DEF_EX_STR( exInvalidThreadsValue, "Invalid threads value specified:", std::exception ) namespace ConfigHelper { @@ -189,8 +204,8 @@ bool Config::parseOrValidate( const char * option, const OptionType type, switch ( opcode ) { case oChunk_max_size: - if ( !hasValue ) - return false; + SKIP_ON_VALIDATION; + REQUIRE_VALUE; if ( sscanf( optionValue, "%zu %n", &uint32Value, &n ) == 1 && !optionValue[ n ] ) @@ -207,8 +222,8 @@ bool Config::parseOrValidate( const char * option, const OptionType type, break; case oBundle_max_payload_size: - if ( !hasValue ) - return false; + SKIP_ON_VALIDATION; + REQUIRE_VALUE; if ( sscanf( optionValue, "%zu %n", &uint32Value, &n ) == 1 && !optionValue[ n ] ) @@ -225,10 +240,10 @@ bool Config::parseOrValidate( const char * option, const OptionType type, break; case oBundle_compression_method: - if ( !hasValue ) - return false; + REQUIRE_VALUE; - if ( strcmp( optionValue, "lzma" ) == 0 ) + if ( PARSE_OR_VALIDATE( strcmp( optionValue, "lzma" ) == 0, + GET_STORABLE( bundle, compression_method ) == "lzma" ) ) { const_sptr< Compression::CompressionMethod > lzma = Compression::CompressionMethod::findCompression( "lzma" ); @@ -242,7 +257,9 @@ bool Config::parseOrValidate( const char * option, const OptionType type, Compression::CompressionMethod::selectedCompression = lzma; } else - if ( strcmp( optionValue, "lzo1x_1" ) == 0 || strcmp( optionValue, "lzo" ) == 0 ) + if ( PARSE_OR_VALIDATE( + strcmp( optionValue, "lzo1x_1" ) == 0 || strcmp( optionValue, "lzo" ) == 0, + GET_STORABLE( bundle, compression_method ) == "lzo1x_1" ) ) { const_sptr< Compression::CompressionMethod > lzo = Compression::CompressionMethod::findCompression( "lzo1x_1" ); @@ -259,10 +276,20 @@ bool Config::parseOrValidate( const char * option, const OptionType type, { fprintf( stderr, "ZBackup doesn't support %s compression.\n" - "You probably need a newer version.\n", optionValue ); + "You probably need a newer version.\n", validate ? + GET_STORABLE( bundle, compression_method ).c_str() : optionValue ); + fprintf( stderr, "Supported compression methods:\n" ); + for ( const const_sptr< Compression::CompressionMethod > * c = + Compression::CompressionMethod::compressions; *c; ++c ) + { + fprintf( stderr, "%s\n", (*c)->getName().c_str() ); + } + fprintf( stderr, "\n" ); + return false; } + SKIP_ON_VALIDATION; SET_STORABLE( bundle, compression_method, Compression::CompressionMethod::selectedCompression->getName() ); dPrintf( "storable[bundle][compression_method] = %s\n", @@ -273,8 +300,7 @@ bool Config::parseOrValidate( const char * option, const OptionType type, break; case oRuntime_threads: - if ( !hasValue ) - return false; + REQUIRE_VALUE; sizeValue = runtime.threads; if ( sscanf( optionValue, "%zu %n", &sizeValue, &n ) != 1 || @@ -289,8 +315,7 @@ bool Config::parseOrValidate( const char * option, const OptionType type, break; case oRuntime_cacheSize: - if ( !hasValue ) - return false; + REQUIRE_VALUE; sizeValue = runtime.cacheSize; if ( sscanf( optionValue, "%zu %15s %n", @@ -358,8 +383,7 @@ bool Config::parseOrValidate( const char * option, const OptionType type, break; case oRuntime_exchange: - if ( !hasValue ) - return false; + REQUIRE_VALUE; if ( strcmp( optionValue, "backups" ) == 0 ) runtime.exchange.set( BackupExchanger::backups ); @@ -427,11 +451,11 @@ string Config::toString( google::protobuf::Message const & message ) return str; } -bool Config::validateProto( const string & configData, const string & newConfigData ) +bool Config::validateProto( const string & oldConfigData, const string & configData ) { Config config; dPrintf( "Validating proto...\n" ); - if ( !parseProto( newConfigData, config.storable ) ) + if ( !parseProto( configData, config.storable ) ) return false; const ::google::protobuf::Descriptor * configDescriptor = @@ -495,13 +519,12 @@ void Config::show( const ConfigInfo & config ) bool Config::editInteractively( ZBackupBase * zbb ) { string configData( toString( *zbb->config.storable ) ); - string newConfigData( configData ); - if ( !zbb->spawnEditor( newConfigData, &validateProto ) ) + if ( !zbb->spawnEditor( configData, &validateProto ) ) return false; ConfigInfo newConfig; - parseProto( newConfigData, &newConfig ); + parseProto( configData, &newConfig ); if ( toString( *zbb->config.storable ) == toString( newConfig ) ) { verbosePrintf( "No changes made to config\n" ); diff --git a/config.hh b/config.hh index 4a3ce39..3a871e5 100644 --- a/config.hh +++ b/config.hh @@ -12,8 +12,8 @@ #include "backup_exchanger.hh" // TODO: make *_storable to be variadic -#define SET_STORABLE( storage, property, value ) (\ -{\ +#define SET_STORABLE( storage, property, value ) \ +({ \ dPrintf( "storable->mutable_"#storage"()->set_"#property"( "#value" )\n" ); \ storable->mutable_##storage()->set_##property( value ); \ })