Browse Source

Rewritten Option. Introduced Pref.

Now preference key is Pref instead of just string.  It has Option
ID. Now option lookup and setting takes O(1) using Pref object.
Tatsuhiro Tsujikawa 14 years ago
parent
commit
3832ed97c6

+ 1 - 1
src/AbstractCommand.cc

@@ -545,7 +545,7 @@ void AbstractCommand::setWriteCheckSocketIf
 namespace {
 // Returns proxy option value for the given protocol.
 const std::string& getProxyOptionFor
-(const std::string& proxyPref, const SharedHandle<Option>& option)
+(const Pref* proxyPref, const SharedHandle<Option>& option)
 {
   if(option->defined(proxyPref)) {
     return option->get(proxyPref);

+ 2 - 2
src/DHTSetup.cc

@@ -212,11 +212,11 @@ void DHTSetup::setup
       taskQueue->addPeriodicTask1(task);
     }
 
-    const std::string& prefEntryPointHost =
+    const Pref* prefEntryPointHost =
       family == AF_INET?PREF_DHT_ENTRY_POINT_HOST:PREF_DHT_ENTRY_POINT_HOST6;
     if(!e->getOption()->get(prefEntryPointHost).empty()) {
       {
-        const std::string& prefEntryPointPort =
+        const Pref* prefEntryPointPort =
           family == AF_INET?PREF_DHT_ENTRY_POINT_PORT:
           PREF_DHT_ENTRY_POINT_PORT6;
         std::pair<std::string, uint16_t> addr

+ 10 - 4
src/NameMatchOptionHandler.cc

@@ -39,16 +39,17 @@
 #include "OptionHandlerException.h"
 #include "a2functional.h"
 #include "Option.h"
+#include "prefs.h"
 
 namespace aria2 {
 
 NameMatchOptionHandler::NameMatchOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  ARG_TYPE argType,
  char shortName)
-  : optName_(optName),
+  : pref_(pref),
     description_(description),
     defaultValue_(defaultValue),
     id_(0),
@@ -62,7 +63,7 @@ NameMatchOptionHandler::~NameMatchOptionHandler() {}
   
 bool NameMatchOptionHandler::canHandle(const std::string& optName)
 {
-  return optName_ == optName;
+  return pref_->k == optName;
 }
 
 void NameMatchOptionHandler::parse(Option& option, const std::string& arg)
@@ -70,7 +71,7 @@ void NameMatchOptionHandler::parse(Option& option, const std::string& arg)
   try {
     parseArg(option, arg);
   } catch(Exception& e) {
-    throw OPTION_HANDLER_EXCEPTION2(optName_, e);
+    throw OPTION_HANDLER_EXCEPTION2(pref_, e);
   }
 }
 
@@ -89,4 +90,9 @@ std::string NameMatchOptionHandler::toTagString() const
   return strjoin(tags_.begin(), tags_.end(), ", ");
 }
 
+const std::string& NameMatchOptionHandler::getName() const
+{
+  return pref_->k;
+}
+
 } // namespace aria2

+ 4 - 6
src/NameMatchOptionHandler.h

@@ -44,10 +44,11 @@
 namespace aria2 {
 
 class Option;
+class Pref;
 
 class NameMatchOptionHandler : public OptionHandler {
 protected:
-  std::string optName_;
+  const Pref* pref_;
 
   std::string description_;
 
@@ -67,7 +68,7 @@ protected:
 
   virtual void parseArg(Option& option, const std::string& arg) = 0;
 public:
-  NameMatchOptionHandler(const std::string& optName,
+  NameMatchOptionHandler(const Pref* pref,
                          const std::string& description = NO_DESCRIPTION,
                          const std::string& defaultValue = NO_DEFAULT_VALUE,
                          ARG_TYPE argType = REQ_ARG,
@@ -85,10 +86,7 @@ public:
 
   virtual std::string toTagString() const;
 
-  virtual const std::string& getName() const
-  {
-    return optName_;
-  }
+  virtual const std::string& getName() const;
 
   virtual const std::string& getDescription() const
   {

+ 61 - 51
src/Option.cc

@@ -33,43 +33,74 @@
  */
 /* copyright --> */
 #include "Option.h"
-#include "prefs.h"
-#include "A2STR.h"
+
 #include <cstdlib>
 #include <cstring>
 
+#include "prefs.h"
+#include "bitfield.h"
+
 namespace aria2 {
 
-Option::Option() {}
+Option::Option()
+  : table_(option::countOption()),
+    use_((option::countOption()+7)/8)
+{}
 
 Option::~Option() {}
 
-void Option::put(const std::string& name, const std::string& value) {
-  table_[name] = value;
+Option::Option(const Option& option)
+  : table_(option.table_),
+    use_(option.use_)
+{}
+
+Option& Option::operator=(const Option& option)
+{
+  if(this != &option) {
+    table_ = option.table_;
+    use_ = option.use_;
+  }
+  return *this;
 }
 
-bool Option::defined(const std::string& name) const
+namespace {
+
+template<typename V>
+void setBit(V& b, const Pref* pref)
 {
-  return table_.count(name) == 1;
+  b[pref->i/8] |= 128 >> (pref->i%8);
 }
 
-bool Option::blank(const std::string& name) const
+template<typename V>
+void unsetBit(V& b, const Pref* pref)
 {
-  std::map<std::string, std::string>::const_iterator i = table_.find(name);
-  return i == table_.end() || (*i).second.empty();
+  b[pref->i/8] &= ~(128 >> (pref->i%8));
 }
 
-const std::string& Option::get(const std::string& name) const {
-  std::map<std::string, std::string>::const_iterator itr = table_.find(name);
-  if(itr == table_.end()) {
-    return A2STR::NIL;
-  } else {
-    return (*itr).second;
-  }
+} // namespace
+
+void Option::put(const Pref* pref, const std::string& value) {
+  setBit(use_, pref);
+  table_[pref->i] = value;
+}
+
+bool Option::defined(const Pref* pref) const
+{
+  return bitfield::test(use_, use_.size()*8, pref->i);
+}
+
+bool Option::blank(const Pref* pref) const
+{
+  return !defined(pref) || table_[pref->i].empty();
 }
 
-int32_t Option::getAsInt(const std::string& name) const {
-  const std::string& value = get(name);
+const std::string& Option::get(const Pref* pref) const
+{
+  return table_[pref->i];
+}
+
+int32_t Option::getAsInt(const Pref* pref) const {
+  const std::string& value = get(pref);
   if(value.empty()) {
     return 0;
   } else {
@@ -77,8 +108,8 @@ int32_t Option::getAsInt(const std::string& name) const {
   }
 }
 
-int64_t Option::getAsLLInt(const std::string& name) const {
-  const std::string& value = get(name);
+int64_t Option::getAsLLInt(const Pref* pref) const {
+  const std::string& value = get(pref);
   if(value.empty()) {
     return 0;
   } else {
@@ -86,12 +117,12 @@ int64_t Option::getAsLLInt(const std::string& name) const {
   }
 }
 
-bool Option::getAsBool(const std::string& name) const {
-  return get(name) == A2_V_TRUE;
+bool Option::getAsBool(const Pref* pref) const {
+  return get(pref) == A2_V_TRUE;
 }
 
-double Option::getAsDouble(const std::string& name) const {
-  const std::string& value = get(name);
+double Option::getAsDouble(const Pref* pref) const {
+  const std::string& value = get(pref);
   if(value.empty()) {
     return 0.0;
   } else {
@@ -99,37 +130,16 @@ double Option::getAsDouble(const std::string& name) const {
   }
 }
 
-void Option::remove(const std::string& name)
+void Option::remove(const Pref* pref)
 {
-  std::map<std::string, std::string>::iterator i = table_.find(name);
-  if(i != table_.end()) {
-    table_.erase(i);
-  }
+  unsetBit(use_, pref);
+  table_[pref->i].clear();
 }
 
 void Option::clear()
 {
-  table_.clear();
-}
-
-std::map<std::string, std::string>::const_iterator Option::begin() const
-{
-  return table_.begin();
-}
-
-std::map<std::string, std::string>::const_iterator Option::end() const
-{
-  return table_.end();
-}
-
-std::map<std::string, std::string>::iterator Option::begin()
-{
-  return table_.begin();
-}
-
-std::map<std::string, std::string>::iterator Option::end()
-{
-  return table_.end();
+  std::fill(use_.begin(), use_.end(), 0);
+  std::fill(table_.begin(), table_.end(), "");
 }
 
 } // namespace aria2

+ 21 - 18
src/Option.h

@@ -36,42 +36,45 @@
 #define D_OPTION_H
 
 #include "common.h"
+
 #include <string>
-#include <map>
+#include <vector>
 
 namespace aria2 {
 
+class Pref;
+
 class Option {
 private:
-  std::map<std::string, std::string> table_;
+  std::vector<std::string> table_;
+  std::vector<unsigned char> use_;
 public:
   Option();
   ~Option();
+  Option(const Option& option);
+  Option& operator=(const Option& option);
 
-  void put(const std::string& name, const std::string& value);
+  void put(const Pref* pref, const std::string& value);
   // Returns true if name is defined. Otherwise returns false.
   // Note that even if the value is a empty string, this method returns true.
-  bool defined(const std::string& name) const;
+  bool defined(const Pref* pref) const;
   // Returns true if name is not defined or the value is a empty string.
   // Otherwise returns false.
-  bool blank(const std::string& name) const;
-  const std::string& get(const std::string& name) const;
-  int32_t getAsInt(const std::string& name) const;
-  int64_t getAsLLInt(const std::string& name) const;
-  bool getAsBool(const std::string& name) const;
-  double getAsDouble(const std::string& name) const;
+  bool blank(const Pref* pref) const;
+  const std::string& get(const Pref* pref) const;
+  int32_t getAsInt(const Pref* pref) const;
+  int64_t getAsLLInt(const Pref* pref) const;
+  bool getAsBool(const Pref* pref) const;
+  double getAsDouble(const Pref* pref) const;
   
-  void remove(const std::string& name);
+  void remove(const Pref* pref);
 
   void clear();
 
-  std::map<std::string, std::string>::const_iterator begin() const;
-
-  std::map<std::string, std::string>::const_iterator end() const;
-
-  std::map<std::string, std::string>::iterator begin();
-
-  std::map<std::string, std::string>::iterator end();
+  const std::vector<std::string>& getTable()
+  {
+    return table_;
+  }
 };
 
 } // namespace aria2

+ 20 - 13
src/OptionHandlerException.cc

@@ -34,31 +34,38 @@
 /* copyright --> */
 #include "OptionHandlerException.h"
 #include "fmt.h"
+#include "prefs.h"
 
 namespace aria2 {
 
 const std::string OptionHandlerException::MESSAGE
 ("We encountered a problem while processing the option '--%s'.");
 
-OptionHandlerException::OptionHandlerException(const char* file, int line,
-                                               const std::string& optName):
-  RecoverableException
-  (file, line, fmt(MESSAGE.c_str(), optName.c_str()), error_code::OPTION_ERROR),
-  optName_(optName) {}
+OptionHandlerException::OptionHandlerException
+(const char* file, int line,
+ const Pref* pref)
+  : RecoverableException
+    (file, line, fmt(MESSAGE.c_str(), pref->k.c_str()),
+     error_code::OPTION_ERROR),
+    pref_(pref)
+{}
 
-OptionHandlerException::OptionHandlerException(const char* file, int line,
-                                               const std::string& optName,
-                                               const Exception& cause):
-  RecoverableException
-  (file, line, fmt(MESSAGE.c_str(), optName.c_str()), error_code::OPTION_ERROR,
-   cause),
-  optName_(optName) {}
+OptionHandlerException::OptionHandlerException
+(const char* file, int line,
+ const Pref* pref,
+ const Exception& cause)
+  : RecoverableException
+    (file, line, fmt(MESSAGE.c_str(), pref->k.c_str()),
+     error_code::OPTION_ERROR,
+     cause),
+    pref_(pref)
+{}
 
 OptionHandlerException::~OptionHandlerException() throw() {}
 
 const std::string& OptionHandlerException::getOptionName() const throw()
 {
-  return optName_;
+  return pref_->k;
 }
 
 SharedHandle<Exception> OptionHandlerException::copy() const

+ 6 - 3
src/OptionHandlerException.h

@@ -38,18 +38,21 @@
 
 namespace aria2 {
 
+class Pref;
+
 class OptionHandlerException:public RecoverableException {
 private:
-  std::string optName_;
+  const Pref* pref_;
 
   static const std::string MESSAGE;
 protected:
   virtual SharedHandle<Exception> copy() const;
 public:
   OptionHandlerException(const char* file, int line,
-                         const std::string& optName);
+                         const Pref* pref);
 
-  OptionHandlerException(const char* file, int line, const std::string& optName,
+  OptionHandlerException(const char* file, int line,
+                         const Pref* pref,
                          const Exception& cause);
 
   virtual ~OptionHandlerException() throw();

+ 2 - 2
src/OptionHandlerFactory.cc

@@ -1781,7 +1781,7 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
   // Version Option
   {
     SharedHandle<OptionHandler> op(new DefaultOptionHandler
-                                   ("version",
+                                   (PREF_VERSION,
                                     TEXT_VERSION,
                                     NO_DEFAULT_VALUE,
                                     A2STR::NIL,
@@ -1812,7 +1812,7 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
     };
     static std::string tagsStr = strjoin(vbegin(tags), vend(tags), ", ");
     SharedHandle<OptionHandler> op(new DefaultOptionHandler
-                                   ("help",
+                                   (PREF_HELP,
                                     TEXT_HELP,
                                     TAG_BASIC,
                                     tagsStr,

+ 71 - 71
src/OptionHandlerImpl.cc

@@ -127,12 +127,12 @@ bool NullOptionHandler::getEraseAfterParse() const
 void NullOptionHandler::setEraseAfterParse(bool eraseAfterParse) {}
 
 BooleanOptionHandler::BooleanOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  OptionHandler::ARG_TYPE argType,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            argType, shortName)
 {}
 
@@ -144,11 +144,11 @@ void BooleanOptionHandler::parseArg(Option& option, const std::string& optarg)
      ((argType_ == OptionHandler::OPT_ARG ||
        argType_ == OptionHandler::NO_ARG)
       && optarg.empty())) {
-    option.put(optName_, A2_V_TRUE);
+    option.put(pref_, A2_V_TRUE);
   } else if(optarg == "false") {
-    option.put(optName_, A2_V_FALSE);
+    option.put(pref_, A2_V_FALSE);
   } else {
-    std::string msg = optName_;
+    std::string msg = pref_->k;
     strappend(msg, " ", _("must be either 'true' or 'false'."));
     throw DL_ABORT_EX(msg);
   }
@@ -160,12 +160,12 @@ std::string BooleanOptionHandler::createPossibleValuesString() const
 }
 
 IntegerRangeOptionHandler::IntegerRangeOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  int32_t min, int32_t max,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName),
     min_(min),
     max_(max)
@@ -180,13 +180,13 @@ void IntegerRangeOptionHandler::parseArg
   while(seq.hasNext()) {
     int32_t v = seq.next();
     if(v < min_ || max_ < v) {
-      std::string msg = optName_;
+      std::string msg = pref_->k;
       strappend(msg, " ", _("must be between %s and %s."));
       throw DL_ABORT_EX
         (fmt(msg.c_str(), util::itos(min_).c_str(),
              util::itos(max_).c_str()));
     }
-    option.put(optName_, optarg);
+    option.put(pref_, optarg);
   }
 }
 
@@ -196,13 +196,13 @@ std::string IntegerRangeOptionHandler::createPossibleValuesString() const
 }
 
 NumberOptionHandler::NumberOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  int64_t min,
  int64_t max,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName),
     min_(min),
     max_(max)
@@ -219,9 +219,9 @@ void NumberOptionHandler::parseArg(Option& option, const std::string& optarg)
 void NumberOptionHandler::parseArg(Option& option, int64_t number)
 {
   if((min_ == -1 || min_ <= number) && (max_ ==  -1 || number <= max_)) {
-    option.put(optName_, util::itos(number));
+    option.put(pref_, util::itos(number));
   } else {
-    std::string msg = optName_;
+    std::string msg = pref_->k;
     msg += " ";
     if(min_ == -1 && max_ != -1) {
       msg += fmt(_("must be smaller than or equal to %s."),
@@ -258,13 +258,13 @@ std::string NumberOptionHandler::createPossibleValuesString() const
 }
 
 UnitNumberOptionHandler::UnitNumberOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  int64_t min,
  int64_t max,
  char shortName)
-  : NumberOptionHandler(optName, description, defaultValue, min, max,
+  : NumberOptionHandler(pref, description, defaultValue, min, max,
                         shortName)
 {}
 
@@ -278,13 +278,13 @@ void UnitNumberOptionHandler::parseArg
 }
 
 FloatNumberOptionHandler::FloatNumberOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  double min,
  double max,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName),
     min_(min),
     max_(max)
@@ -297,9 +297,9 @@ void FloatNumberOptionHandler::parseArg
 {
   double number = strtod(optarg.c_str(), 0);
   if((min_ < 0 || min_ <= number) && (max_ < 0 || number <= max_)) {
-    option.put(optName_, optarg);
+    option.put(pref_, optarg);
   } else {
-    std::string msg = optName_;
+    std::string msg = pref_->k;
     msg += " ";
     if(min_ < 0 && max_ >= 0) {
       msg += fmt(_("must be smaller than or equal to %.1f."), max_);
@@ -336,13 +336,13 @@ std::string FloatNumberOptionHandler::createPossibleValuesString() const
 }
 
 DefaultOptionHandler::DefaultOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  const std::string& possibleValuesString,
  OptionHandler::ARG_TYPE argType,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue, argType,
+  : NameMatchOptionHandler(pref, description, defaultValue, argType,
                            shortName),
     possibleValuesString_(possibleValuesString)
 {}
@@ -351,7 +351,7 @@ DefaultOptionHandler::~DefaultOptionHandler() {}
 
 void DefaultOptionHandler::parseArg(Option& option, const std::string& optarg)
 {
-  option.put(optName_, optarg);
+  option.put(pref_, optarg);
 }
 
 std::string DefaultOptionHandler::createPossibleValuesString() const
@@ -360,14 +360,14 @@ std::string DefaultOptionHandler::createPossibleValuesString() const
 }
 
 CumulativeOptionHandler::CumulativeOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  const std::string& delim,
  const std::string& possibleValuesString,
  OptionHandler::ARG_TYPE argType,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue, argType,
+  : NameMatchOptionHandler(pref, description, defaultValue, argType,
                            shortName),
     delim_(delim),
     possibleValuesString_(possibleValuesString)
@@ -378,9 +378,9 @@ CumulativeOptionHandler::~CumulativeOptionHandler() {}
 void CumulativeOptionHandler::parseArg
 (Option& option, const std::string& optarg)
 {
-  std::string value = option.get(optName_);
+  std::string value = option.get(pref_);
   strappend(value, optarg, delim_);
-  option.put(optName_, value);
+  option.put(pref_, value);
 }
 
 std::string CumulativeOptionHandler::createPossibleValuesString() const
@@ -389,10 +389,10 @@ std::string CumulativeOptionHandler::createPossibleValuesString() const
 }
 
 IndexOutOptionHandler::IndexOutOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  char shortName)
-  : NameMatchOptionHandler(optName, description, NO_DEFAULT_VALUE,
+  : NameMatchOptionHandler(pref, description, NO_DEFAULT_VALUE,
                            OptionHandler::REQ_ARG, shortName)
 {}
 
@@ -402,9 +402,9 @@ void IndexOutOptionHandler::parseArg(Option& option, const std::string& optarg)
 {
   // See optarg is in the fomrat of "INDEX=PATH"
   util::parseIndexPath(optarg);
-  std::string value = option.get(optName_);
+  std::string value = option.get(pref_);
   strappend(value, optarg, "\n");
-  option.put(optName_, value);
+  option.put(pref_, value);
 }
 
 std::string IndexOutOptionHandler::createPossibleValuesString() const
@@ -413,10 +413,10 @@ std::string IndexOutOptionHandler::createPossibleValuesString() const
 }
 
 ChecksumOptionHandler::ChecksumOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  char shortName)
-  : NameMatchOptionHandler(optName, description, NO_DEFAULT_VALUE,
+  : NameMatchOptionHandler(pref, description, NO_DEFAULT_VALUE,
                            OptionHandler::REQ_ARG, shortName)
 {}
 
@@ -431,7 +431,7 @@ void ChecksumOptionHandler::parseArg(Option& option, const std::string& optarg)
   if(!MessageDigest::isValidHash(p.first, p.second)) {
     throw DL_ABORT_EX(_("Unrecognized checksum"));
   }
-  option.put(optName_, optarg);
+  option.put(pref_, optarg);
 }
 
 std::string ChecksumOptionHandler::createPossibleValuesString() const
@@ -440,36 +440,36 @@ std::string ChecksumOptionHandler::createPossibleValuesString() const
 }
 
 ParameterOptionHandler::ParameterOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  const std::vector<std::string>& validParamValues,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName),
     validParamValues_(validParamValues)
 {}
 
 ParameterOptionHandler::ParameterOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  const std::string& validParamValue,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName)
 {
   validParamValues_.push_back(validParamValue);
 }
 
 ParameterOptionHandler::ParameterOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  const std::string& validParamValue1,
  const std::string& validParamValue2,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName)
 {
   validParamValues_.push_back(validParamValue1);
@@ -477,14 +477,14 @@ ParameterOptionHandler::ParameterOptionHandler
 }
 
 ParameterOptionHandler::ParameterOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  const std::string& validParamValue1,
  const std::string& validParamValue2,
  const std::string& validParamValue3,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName)
 {
   validParamValues_.push_back(validParamValue1);
@@ -499,7 +499,7 @@ void ParameterOptionHandler::parseArg(Option& option, const std::string& optarg)
   std::vector<std::string>::const_iterator itr =
     std::find(validParamValues_.begin(), validParamValues_.end(), optarg);
   if(itr == validParamValues_.end()) {
-    std::string msg = optName_;
+    std::string msg = pref_->k;
     strappend(msg, " ", _("must be one of the following:"));
     if(validParamValues_.size() == 0) {
       msg += "''";
@@ -512,7 +512,7 @@ void ParameterOptionHandler::parseArg(Option& option, const std::string& optarg)
     }
     throw DL_ABORT_EX(msg);
   } else {
-    option.put(optName_, optarg);
+    option.put(pref_, optarg);
   }
 }
 
@@ -525,13 +525,13 @@ std::string ParameterOptionHandler::createPossibleValuesString() const
 }
 
 HostPortOptionHandler::HostPortOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
- const std::string& hostOptionName,
- const std::string& portOptionName,
+ const Pref* hostOptionName,
+ const Pref* portOptionName,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName),
     hostOptionName_(hostOptionName),
     portOptionName_(portOptionName)
@@ -547,7 +547,7 @@ void HostPortOptionHandler::parseArg(Option& option, const std::string& optarg)
   if(!req.setUri(uri)) {
     throw DL_ABORT_EX(_("Unrecognized format"));
   }
-  option.put(optName_, optarg);
+  option.put(pref_, optarg);
   setHostAndPort(option, req.getHost(), req.getPort());
 }
 
@@ -564,19 +564,19 @@ std::string HostPortOptionHandler::createPossibleValuesString() const
 }
 
 HttpProxyUserOptionHandler::HttpProxyUserOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName)
 {}
 
 void HttpProxyUserOptionHandler::parseArg
 (Option& option, const std::string& optarg)
 {
-  if(util::endsWith(optName_, "-user")) {
-    const std::string proxyPref = optName_.substr(0, optName_.size()-5);
+  if(util::endsWith(pref_->k, "-user")) {
+    const Pref* proxyPref = option::k2p(pref_->k.substr(0, pref_->k.size()-5));
     const std::string& olduri = option.get(proxyPref);
     if(!olduri.empty()) {
       Request req;
@@ -597,7 +597,7 @@ void HttpProxyUserOptionHandler::parseArg
       option.put(proxyPref, uri);
     }
   }
-  option.put(optName_, optarg);
+  option.put(pref_, optarg);
 }
 
 std::string HttpProxyUserOptionHandler::createPossibleValuesString() const
@@ -606,19 +606,19 @@ std::string HttpProxyUserOptionHandler::createPossibleValuesString() const
 }
 
 HttpProxyPasswdOptionHandler::HttpProxyPasswdOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName)
 {}
 
 void HttpProxyPasswdOptionHandler::parseArg
 (Option& option, const std::string& optarg)
 {
-  if(util::endsWith(optName_, "-passwd")) {
-    const std::string proxyPref = optName_.substr(0, optName_.size()-7);
+  if(util::endsWith(pref_->k, "-passwd")) {
+    const Pref* proxyPref = option::k2p(pref_->k.substr(0, pref_->k.size()-7));
     const std::string& olduri = option.get(proxyPref);
     if(!olduri.empty()) {
       Request req;
@@ -639,7 +639,7 @@ void HttpProxyPasswdOptionHandler::parseArg
       option.put(proxyPref, uri);
     }
   }
-  option.put(optName_, optarg);
+  option.put(pref_, optarg);
 }
 
 std::string HttpProxyPasswdOptionHandler::createPossibleValuesString() const
@@ -648,14 +648,14 @@ std::string HttpProxyPasswdOptionHandler::createPossibleValuesString() const
 }
 
 HttpProxyOptionHandler::HttpProxyOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName),
-    proxyUserPref_(optName_+"-user"),
-    proxyPasswdPref_(optName_+"-passwd")
+    proxyUserPref_(option::k2p(pref->k+"-user")),
+    proxyPasswdPref_(option::k2p(pref->k+"-passwd"))
 {}
 
 HttpProxyOptionHandler::~HttpProxyOptionHandler() {}
@@ -663,7 +663,7 @@ HttpProxyOptionHandler::~HttpProxyOptionHandler() {}
 void HttpProxyOptionHandler::parseArg(Option& option, const std::string& optarg)
 {
   if(optarg.empty()) {
-    option.put(optName_, optarg);
+    option.put(pref_, optarg);
   } else {
     Request req;
     std::string uri;
@@ -691,7 +691,7 @@ void HttpProxyOptionHandler::parseArg(Option& option, const std::string& optarg)
         us.hasPassword = true;
       }
     }
-    option.put(optName_, uri::construct(us));
+    option.put(pref_, uri::construct(us));
   }
 }
 
@@ -701,12 +701,12 @@ std::string HttpProxyOptionHandler::createPossibleValuesString() const
 }
 
 LocalFilePathOptionHandler::LocalFilePathOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  bool acceptStdin,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName),
     acceptStdin_(acceptStdin)
 {}
@@ -715,13 +715,13 @@ void LocalFilePathOptionHandler::parseArg
 (Option& option, const std::string& optarg)
 {
   if(acceptStdin_ && optarg == "-") {
-    option.put(optName_, DEV_STDIN);
+    option.put(pref_, DEV_STDIN);
   } else {
     File f(optarg);
     if(!f.exists() || f.isDir()) {
       throw DL_ABORT_EX(fmt(MSG_NOT_FILE, optarg.c_str()));
     }
-    option.put(optName_, optarg);
+    option.put(pref_, optarg);
   }
 }
   
@@ -735,11 +735,11 @@ std::string LocalFilePathOptionHandler::createPossibleValuesString() const
 }
 
 PrioritizePieceOptionHandler::PrioritizePieceOptionHandler
-(const std::string& optName,
+(const Pref* pref,
  const std::string& description,
  const std::string& defaultValue,
  char shortName)
-  : NameMatchOptionHandler(optName, description, defaultValue,
+  : NameMatchOptionHandler(pref, description, defaultValue,
                            OptionHandler::REQ_ARG, shortName)
 {}
 
@@ -751,7 +751,7 @@ void PrioritizePieceOptionHandler::parseArg
   std::vector<size_t> result;
   util::parsePrioritizePieceRange
     (result, optarg, std::vector<SharedHandle<FileEntry> >(), 1024);
-  option.put(optName_, optarg);
+  option.put(pref_, optarg);
 }
 
 std::string PrioritizePieceOptionHandler::createPossibleValuesString() const

+ 26 - 27
src/OptionHandlerImpl.h

@@ -44,6 +44,7 @@
 namespace aria2 {
 
 class Option;
+class Pref;
 
 class NullOptionHandler : public OptionHandler {
 private:
@@ -71,7 +72,7 @@ public:
 
 class BooleanOptionHandler : public NameMatchOptionHandler {
 public:
-  BooleanOptionHandler(const std::string& optName,
+  BooleanOptionHandler(const Pref* pref,
                        const std::string& description = NO_DESCRIPTION,
                        const std::string& defaultValue = NO_DEFAULT_VALUE,
                        OptionHandler::ARG_TYPE argType = OptionHandler::REQ_ARG,
@@ -86,7 +87,7 @@ private:
   int32_t min_;
   int32_t max_;
 public:
-  IntegerRangeOptionHandler(const std::string& optName,
+  IntegerRangeOptionHandler(const Pref* pref,
                             const std::string& description,
                             const std::string& defaultValue,
                             int32_t min, int32_t max,
@@ -101,7 +102,7 @@ private:
   int64_t min_;
   int64_t max_;
 public:
-  NumberOptionHandler(const std::string& optName,
+  NumberOptionHandler(const Pref* pref,
                       const std::string& description = NO_DESCRIPTION,
                       const std::string& defaultValue = NO_DEFAULT_VALUE,
                       int64_t min = -1,
@@ -116,7 +117,7 @@ public:
 
 class UnitNumberOptionHandler : public NumberOptionHandler {
 public:
-  UnitNumberOptionHandler(const std::string& optName,
+  UnitNumberOptionHandler(const Pref* pref,
                           const std::string& description = NO_DESCRIPTION,
                           const std::string& defaultValue = NO_DEFAULT_VALUE,
                           int64_t min = -1,
@@ -131,7 +132,7 @@ private:
   double min_;
   double max_;
 public:
-  FloatNumberOptionHandler(const std::string& optName,
+  FloatNumberOptionHandler(const Pref* pref,
                            const std::string& description = NO_DESCRIPTION,
                            const std::string& defaultValue = NO_DEFAULT_VALUE,
                            double min = -1, double max = -1,
@@ -145,7 +146,7 @@ class DefaultOptionHandler : public NameMatchOptionHandler {
 private:
   std::string possibleValuesString_;
 public:
-  DefaultOptionHandler(const std::string& optName,
+  DefaultOptionHandler(const Pref* pref,
                        const std::string& description = NO_DESCRIPTION,
                        const std::string& defaultValue = NO_DEFAULT_VALUE,
                        const std::string& possibleValuesString = A2STR::NIL,
@@ -161,7 +162,7 @@ private:
   std::string delim_;
   std::string possibleValuesString_;
 public:
-  CumulativeOptionHandler(const std::string& optName,
+  CumulativeOptionHandler(const Pref* pref,
                           const std::string& description,
                           const std::string& defaultValue,
                           const std::string& delim,
@@ -175,9 +176,8 @@ public:
 };
 
 class IndexOutOptionHandler : public NameMatchOptionHandler {
-private:
 public:
-  IndexOutOptionHandler(const std::string& optName,
+  IndexOutOptionHandler(const Pref* pref,
                         const std::string& description,
                         char shortName = 0);
   virtual ~IndexOutOptionHandler();
@@ -186,9 +186,8 @@ public:
 };
 
 class ChecksumOptionHandler : public NameMatchOptionHandler {
-private:
 public:
-  ChecksumOptionHandler(const std::string& optName,
+  ChecksumOptionHandler(const Pref* pref,
                         const std::string& description,
                         char shortName = 0);
   virtual ~ChecksumOptionHandler();
@@ -200,23 +199,23 @@ class ParameterOptionHandler : public NameMatchOptionHandler {
 private:
   std::vector<std::string> validParamValues_;
 public:
-  ParameterOptionHandler(const std::string& optName,
+  ParameterOptionHandler(const Pref* pref,
                          const std::string& description,
                          const std::string& defaultValue,
                          const std::vector<std::string>& validParamValues,
                          char shortName = 0);
-  ParameterOptionHandler(const std::string& optName,
+  ParameterOptionHandler(const Pref* pref,
                          const std::string& description,
                          const std::string& defaultValue,
                          const std::string& validParamValue,
                          char shortName = 0);
-  ParameterOptionHandler(const std::string& optName,
+  ParameterOptionHandler(const Pref* pref,
                          const std::string& description,
                          const std::string& defaultValue,
                          const std::string& validParamValue1,
                          const std::string& validParamValue2,
                          char shortName = 0);
-  ParameterOptionHandler(const std::string& optName,
+  ParameterOptionHandler(const Pref* pref,
                          const std::string& description,
                          const std::string& defaultValue,
                          const std::string& validParamValue1,
@@ -230,14 +229,14 @@ public:
 
 class HostPortOptionHandler : public NameMatchOptionHandler {
 private:
-  std::string hostOptionName_;
-  std::string portOptionName_;
+  const Pref* hostOptionName_;
+  const Pref* portOptionName_;
 public:
-  HostPortOptionHandler(const std::string& optName,
+  HostPortOptionHandler(const Pref* pref,
                         const std::string& description,
                         const std::string& defaultValue,
-                        const std::string& hostOptionName,
-                        const std::string& portOptionName,
+                        const Pref* hostOptionName,
+                        const Pref* portOptionName,
                         char shortName = 0);
   virtual ~HostPortOptionHandler();
   virtual void parseArg(Option& option, const std::string& optarg);
@@ -248,7 +247,7 @@ public:
 
 class HttpProxyUserOptionHandler:public NameMatchOptionHandler {
 public:
-  HttpProxyUserOptionHandler(const std::string& optName,
+  HttpProxyUserOptionHandler(const Pref* pref,
                              const std::string& description,
                              const std::string& defaultValue,
                              char shortName = 0);
@@ -258,7 +257,7 @@ public:
 
 class HttpProxyPasswdOptionHandler:public NameMatchOptionHandler {
 public:
-  HttpProxyPasswdOptionHandler(const std::string& optName,
+  HttpProxyPasswdOptionHandler(const Pref* pref,
                                const std::string& description,
                                const std::string& defaultValue,
                                char shortName = 0);
@@ -268,10 +267,10 @@ public:
 
 class HttpProxyOptionHandler : public NameMatchOptionHandler {
 private:
-  std::string proxyUserPref_;
-  std::string proxyPasswdPref_;
+  const Pref* proxyUserPref_;
+  const Pref* proxyPasswdPref_;
 public:
-  HttpProxyOptionHandler(const std::string& optName,
+  HttpProxyOptionHandler(const Pref* pref,
                          const std::string& description,
                          const std::string& defaultValue,
                          char shortName = 0);
@@ -285,7 +284,7 @@ private:
   bool acceptStdin_;
 public:
   LocalFilePathOptionHandler
-  (const std::string& optName,
+  (const Pref* pref,
    const std::string& description = NO_DESCRIPTION,
    const std::string& defaultValue = NO_DEFAULT_VALUE,
    bool acceptStdin = false,
@@ -297,7 +296,7 @@ public:
 class PrioritizePieceOptionHandler:public NameMatchOptionHandler {
 public:
   PrioritizePieceOptionHandler
-  (const std::string& optName,
+  (const Pref* pref,
    const std::string& description = NO_DESCRIPTION,
    const std::string& defaultValue = NO_DEFAULT_VALUE,
    char shortName = 0);

+ 10 - 4
src/OptionParser.cc

@@ -50,6 +50,7 @@
 #include "OptionHandlerFactory.h"
 #include "DlAbortEx.h"
 #include "error_code.h"
+#include "prefs.h"
 
 namespace aria2 {
 
@@ -196,16 +197,21 @@ void OptionParser::parse(Option& option, std::istream& is)
 }
 
 namespace {
-class DummyOptionHandler:public NameMatchOptionHandler {
+class DummyOptionHandler:public NullOptionHandler {
 protected:
   virtual void parseArg(Option& option, const std::string& arg) {}
 public:
-  DummyOptionHandler(const std::string& name):NameMatchOptionHandler(name) {}
+  DummyOptionHandler(const std::string& optName)
+    : NullOptionHandler(),
+      optName_(optName)
+  {}
 
-  virtual std::string createPossibleValuesString() const
+  virtual const std::string& getName() const
   {
-    return A2STR::NIL;
+    return optName_;
   }
+private:
+  std::string optName_;
 };
 } // namespace
 

+ 13 - 12
src/RpcMethod.cc

@@ -107,7 +107,7 @@ void gatherOption
         // header and index-out option can take array as value
         const List* oplist = downcast<List>((*first).second);
         if(oplist &&
-           (optionName == PREF_HEADER || optionName == PREF_INDEX_OUT)) {
+           (optionName == PREF_HEADER->k || optionName == PREF_INDEX_OUT->k)) {
           for(List::ValueType::const_iterator argiter = oplist->begin(),
                 eoi = oplist->end(); argiter != eoi; ++argiter) {
             const String* opval = downcast<String>(*argiter);
@@ -142,8 +142,9 @@ void applyOption(InputIterator optNameFirst,
                  Option* src)
 {
   for(; optNameFirst != optNameLast; ++optNameFirst) {
-    if(src->defined(*optNameFirst)) {
-      dest->put(*optNameFirst, src->get(*optNameFirst));
+    const Pref* pref = option::k2p(*optNameFirst);
+    if(src->defined(pref)) {
+      dest->put(pref, src->get(pref));
     }
   }
 }
@@ -152,10 +153,10 @@ void applyOption(InputIterator optNameFirst,
 const std::set<std::string>& listChangeableOptions()
 {
   static const std::string OPTIONS[] = {
-    PREF_BT_MAX_PEERS,
-    PREF_BT_REQUEST_PEER_SPEED_LIMIT,
-    PREF_MAX_DOWNLOAD_LIMIT,
-    PREF_MAX_UPLOAD_LIMIT
+    PREF_BT_MAX_PEERS->k,
+    PREF_BT_REQUEST_PEER_SPEED_LIMIT->k,
+    PREF_MAX_DOWNLOAD_LIMIT->k,
+    PREF_MAX_UPLOAD_LIMIT->k
   };
   static std::set<std::string> options(vbegin(OPTIONS), vend(OPTIONS));
   return options;
@@ -180,11 +181,11 @@ void RpcMethod::applyChangeableOption(Option* dest, Option* src) const
 const std::set<std::string>& listChangeableGlobalOptions()
 {
   static const std::string OPTIONS[] = {
-    PREF_MAX_OVERALL_UPLOAD_LIMIT,
-    PREF_MAX_OVERALL_DOWNLOAD_LIMIT,
-    PREF_MAX_CONCURRENT_DOWNLOADS,
-    PREF_LOG,
-    PREF_LOG_LEVEL
+    PREF_MAX_OVERALL_UPLOAD_LIMIT->k,
+    PREF_MAX_OVERALL_DOWNLOAD_LIMIT->k,
+    PREF_MAX_CONCURRENT_DOWNLOADS->k,
+    PREF_LOG->k,
+    PREF_LOG_LEVEL->k
   };
   static std::set<std::string> options(vbegin(OPTIONS), vend(OPTIONS));
   return options;

+ 13 - 11
src/RpcMethodImpl.cc

@@ -1203,15 +1203,14 @@ SharedHandle<ValueBase> GetVersionRpcMethod::process
 }
 
 namespace {
-template<typename InputIterator>
 void pushRequestOption
-(const SharedHandle<Dict>& dict,
- InputIterator optionFirst, InputIterator optionLast)
+(const SharedHandle<Dict>& dict, const SharedHandle<Option>& option)
 {
   const std::set<std::string>& requestOptions = listRequestOptions();
-  for(; optionFirst != optionLast; ++optionFirst) {
-    if(requestOptions.count((*optionFirst).first)) {
-      dict->put((*optionFirst).first, (*optionFirst).second);
+  for(size_t i = 0, len = option->getTable().size(); i < len; ++i) {
+    const Pref* pref = option::i2p(i);
+    if(requestOptions.count(pref->k) && option->defined(pref)) {
+      dict->put(pref->k, option->get(pref));
     }
   }
 }
@@ -1232,7 +1231,7 @@ SharedHandle<ValueBase> GetOptionRpcMethod::process
   }
   SharedHandle<Dict> result = Dict::g();
   SharedHandle<Option> option = group->getOption();
-  pushRequestOption(result, option->begin(), option->end());
+  pushRequestOption(result, option);
   return result;
 }
 
@@ -1240,11 +1239,14 @@ SharedHandle<ValueBase> GetGlobalOptionRpcMethod::process
 (const RpcRequest& req, DownloadEngine* e)
 {
   SharedHandle<Dict> result = Dict::g();
-  for(std::map<std::string, std::string>::const_iterator i =
-        e->getOption()->begin(), eoi = e->getOption()->end(); i != eoi; ++i) {
-    SharedHandle<OptionHandler> h = getOptionParser()->findByName((*i).first);
+  for(size_t i = 0, len = e->getOption()->getTable().size(); i < len; ++i) {
+    const Pref* pref = option::i2p(i);
+    if(!e->getOption()->defined(pref)) {
+      continue;
+    }
+    SharedHandle<OptionHandler> h = getOptionParser()->findByName(pref->k);
     if(h && !h->isHidden()) {
-      result->put((*i).first, (*i).second);
+      result->put(pref->k, e->getOption()->get(pref));
     }
   }
   return result;

+ 8 - 6
src/SessionSerializer.cc

@@ -78,7 +78,7 @@ bool SessionSerializer::save(const std::string& filename) const
 namespace {
 const std::vector<std::string>& getCumulativeOpts()
 {
-  static std::string cumulativeOpts[] = { PREF_INDEX_OUT, PREF_HEADER };
+  static std::string cumulativeOpts[] = { PREF_INDEX_OUT->k, PREF_HEADER->k };
   static std::vector<std::string> opts
     (vbegin(cumulativeOpts), vend(cumulativeOpts));
   return opts;
@@ -108,8 +108,9 @@ bool writeOption(BufferedFile& fp, const SharedHandle<Option>& op)
     if(inCumulativeOpts(*itr)) {
       continue;
     }
-    if(op->defined(*itr)) {
-      if(fp.printf(" %s=%s\n", (*itr).c_str(), op->get(*itr).c_str()) < 0) {
+    const Pref* pref = option::k2p(*itr);
+    if(op->defined(pref)) {
+      if(fp.printf(" %s=%s\n", (*itr).c_str(), op->get(pref).c_str()) < 0) {
         return false;
       }
     }
@@ -117,9 +118,10 @@ bool writeOption(BufferedFile& fp, const SharedHandle<Option>& op)
   const std::vector<std::string>& cumopts = getCumulativeOpts();
   for(std::vector<std::string>::const_iterator opitr = cumopts.begin(),
         eoi = cumopts.end(); opitr != eoi; ++opitr) {
-    if(op->defined(*opitr)) {
+    const Pref* pref = option::k2p(*opitr);
+    if(op->defined(pref)) {
       std::vector<std::string> v;
-      util::split(op->get(*opitr), std::back_inserter(v), "\n",
+      util::split(op->get(pref), std::back_inserter(v), "\n",
                   false, false);
       for(std::vector<std::string>::const_iterator i = v.begin(), eoi = v.end();
           i != eoi; ++i) {
@@ -213,7 +215,7 @@ bool SessionSerializer::save(BufferedFile& fp) const
       // PREF_PAUSE was removed from option, so save it here looking
       // property separately.
       if((*itr)->isPauseRequested()) {
-        if(fp.printf(" %s=true\n", PREF_PAUSE.c_str()) < 0) {
+        if(fp.printf(" %s=true\n", PREF_PAUSE->k.c_str()) < 0) {
           return false;
         }
       }

+ 103 - 102
src/download_helper.cc

@@ -72,106 +72,106 @@ namespace aria2 {
 const std::set<std::string>& listRequestOptions()
 {
   static const std::string REQUEST_OPTIONS[] = {
-    PREF_DIR,
-    PREF_CHECK_INTEGRITY,
-    PREF_CONTINUE,
-    PREF_ALL_PROXY,
-    PREF_ALL_PROXY_USER,
-    PREF_ALL_PROXY_PASSWD,
-    PREF_CONNECT_TIMEOUT,
-    PREF_DRY_RUN,
-    PREF_LOWEST_SPEED_LIMIT,
-    PREF_MAX_FILE_NOT_FOUND,
-    PREF_MAX_TRIES,
-    PREF_NO_PROXY,
-    PREF_OUT,
-    PREF_PROXY_METHOD,
-    PREF_REMOTE_TIME,
-    PREF_SPLIT,
-    PREF_TIMEOUT,
-    PREF_HTTP_AUTH_CHALLENGE,
-    PREF_HTTP_NO_CACHE,
-    PREF_HTTP_USER,
-    PREF_HTTP_PASSWD,
-    PREF_HTTP_PROXY,
-    PREF_HTTP_PROXY_USER,
-    PREF_HTTP_PROXY_PASSWD,
-    PREF_HTTPS_PROXY,
-    PREF_HTTPS_PROXY_USER,
-    PREF_HTTPS_PROXY_PASSWD,
-    PREF_REFERER,
-    PREF_ENABLE_HTTP_KEEP_ALIVE,
-    PREF_ENABLE_HTTP_PIPELINING,
-    PREF_HEADER,
-    PREF_USE_HEAD,
-    PREF_USER_AGENT,
-    PREF_FTP_USER,
-    PREF_FTP_PASSWD,
-    PREF_FTP_PASV,
-    PREF_FTP_PROXY,
-    PREF_FTP_PROXY_USER,
-    PREF_FTP_PROXY_PASSWD,
-    PREF_FTP_TYPE,
-    PREF_FTP_REUSE_CONNECTION,
-    PREF_NO_NETRC,
-    PREF_REUSE_URI,
-    PREF_SELECT_FILE,
-    PREF_BT_ENABLE_LPD,
-    PREF_BT_EXTERNAL_IP,
-    PREF_BT_HASH_CHECK_SEED,
-    PREF_BT_MAX_OPEN_FILES,
-    PREF_BT_MAX_PEERS,
-    PREF_BT_METADATA_ONLY,
-    PREF_BT_MIN_CRYPTO_LEVEL,
-    PREF_BT_PRIORITIZE_PIECE,
-    PREF_BT_REQUIRE_CRYPTO,
-    PREF_BT_REQUEST_PEER_SPEED_LIMIT,
-    PREF_BT_SAVE_METADATA,
-    PREF_BT_SEED_UNVERIFIED,
-    PREF_BT_STOP_TIMEOUT,
-    PREF_BT_TRACKER_INTERVAL,
-    PREF_BT_TRACKER_TIMEOUT,
-    PREF_BT_TRACKER_CONNECT_TIMEOUT,
-    PREF_ENABLE_PEER_EXCHANGE,
-    PREF_FOLLOW_TORRENT,
-    PREF_INDEX_OUT,
-    PREF_MAX_UPLOAD_LIMIT,
-    PREF_SEED_RATIO,
-    PREF_SEED_TIME,
-    PREF_FOLLOW_METALINK,
-    PREF_METALINK_SERVERS,
-    PREF_METALINK_LANGUAGE,
-    PREF_METALINK_LOCATION,
-    PREF_METALINK_OS,
-    PREF_METALINK_VERSION,
-    PREF_METALINK_PREFERRED_PROTOCOL,
-    PREF_METALINK_ENABLE_UNIQUE_PROTOCOL,
-    PREF_ALLOW_OVERWRITE,
-    PREF_ALLOW_PIECE_LENGTH_CHANGE,
-    PREF_ASYNC_DNS,
-    PREF_AUTO_FILE_RENAMING,
-    PREF_FILE_ALLOCATION,
-    PREF_MAX_DOWNLOAD_LIMIT,
-    PREF_NO_FILE_ALLOCATION_LIMIT,
-    PREF_PARAMETERIZED_URI,
-    PREF_REALTIME_CHUNK_CHECKSUM,
-    PREF_REMOVE_CONTROL_FILE,
-    PREF_ALWAYS_RESUME,
-    PREF_MAX_RESUME_FAILURE_TRIES,
-    PREF_HTTP_ACCEPT_GZIP,
-    PREF_MAX_CONNECTION_PER_SERVER,
-    PREF_MIN_SPLIT_SIZE,
-    PREF_CONDITIONAL_GET,
-    PREF_ENABLE_ASYNC_DNS6,
-    PREF_BT_TRACKER,
-    PREF_BT_EXCLUDE_TRACKER,
-    PREF_RETRY_WAIT,
-    PREF_METALINK_BASE_URI,
-    PREF_PAUSE,
-    PREF_STREAM_PIECE_SELECTOR,
-    PREF_HASH_CHECK_ONLY,
-    PREF_CHECKSUM,
-    PREF_PIECE_LENGTH
+    PREF_DIR->k,
+    PREF_CHECK_INTEGRITY->k,
+    PREF_CONTINUE->k,
+    PREF_ALL_PROXY->k,
+    PREF_ALL_PROXY_USER->k,
+    PREF_ALL_PROXY_PASSWD->k,
+    PREF_CONNECT_TIMEOUT->k,
+    PREF_DRY_RUN->k,
+    PREF_LOWEST_SPEED_LIMIT->k,
+    PREF_MAX_FILE_NOT_FOUND->k,
+    PREF_MAX_TRIES->k,
+    PREF_NO_PROXY->k,
+    PREF_OUT->k,
+    PREF_PROXY_METHOD->k,
+    PREF_REMOTE_TIME->k,
+    PREF_SPLIT->k,
+    PREF_TIMEOUT->k,
+    PREF_HTTP_AUTH_CHALLENGE->k,
+    PREF_HTTP_NO_CACHE->k,
+    PREF_HTTP_USER->k,
+    PREF_HTTP_PASSWD->k,
+    PREF_HTTP_PROXY->k,
+    PREF_HTTP_PROXY_USER->k,
+    PREF_HTTP_PROXY_PASSWD->k,
+    PREF_HTTPS_PROXY->k,
+    PREF_HTTPS_PROXY_USER->k,
+    PREF_HTTPS_PROXY_PASSWD->k,
+    PREF_REFERER->k,
+    PREF_ENABLE_HTTP_KEEP_ALIVE->k,
+    PREF_ENABLE_HTTP_PIPELINING->k,
+    PREF_HEADER->k,
+    PREF_USE_HEAD->k,
+    PREF_USER_AGENT->k,
+    PREF_FTP_USER->k,
+    PREF_FTP_PASSWD->k,
+    PREF_FTP_PASV->k,
+    PREF_FTP_PROXY->k,
+    PREF_FTP_PROXY_USER->k,
+    PREF_FTP_PROXY_PASSWD->k,
+    PREF_FTP_TYPE->k,
+    PREF_FTP_REUSE_CONNECTION->k,
+    PREF_NO_NETRC->k,
+    PREF_REUSE_URI->k,
+    PREF_SELECT_FILE->k,
+    PREF_BT_ENABLE_LPD->k,
+    PREF_BT_EXTERNAL_IP->k,
+    PREF_BT_HASH_CHECK_SEED->k,
+    PREF_BT_MAX_OPEN_FILES->k,
+    PREF_BT_MAX_PEERS->k,
+    PREF_BT_METADATA_ONLY->k,
+    PREF_BT_MIN_CRYPTO_LEVEL->k,
+    PREF_BT_PRIORITIZE_PIECE->k,
+    PREF_BT_REQUIRE_CRYPTO->k,
+    PREF_BT_REQUEST_PEER_SPEED_LIMIT->k,
+    PREF_BT_SAVE_METADATA->k,
+    PREF_BT_SEED_UNVERIFIED->k,
+    PREF_BT_STOP_TIMEOUT->k,
+    PREF_BT_TRACKER_INTERVAL->k,
+    PREF_BT_TRACKER_TIMEOUT->k,
+    PREF_BT_TRACKER_CONNECT_TIMEOUT->k,
+    PREF_ENABLE_PEER_EXCHANGE->k,
+    PREF_FOLLOW_TORRENT->k,
+    PREF_INDEX_OUT->k,
+    PREF_MAX_UPLOAD_LIMIT->k,
+    PREF_SEED_RATIO->k,
+    PREF_SEED_TIME->k,
+    PREF_FOLLOW_METALINK->k,
+    PREF_METALINK_SERVERS->k,
+    PREF_METALINK_LANGUAGE->k,
+    PREF_METALINK_LOCATION->k,
+    PREF_METALINK_OS->k,
+    PREF_METALINK_VERSION->k,
+    PREF_METALINK_PREFERRED_PROTOCOL->k,
+    PREF_METALINK_ENABLE_UNIQUE_PROTOCOL->k,
+    PREF_ALLOW_OVERWRITE->k,
+    PREF_ALLOW_PIECE_LENGTH_CHANGE->k,
+    PREF_ASYNC_DNS->k,
+    PREF_AUTO_FILE_RENAMING->k,
+    PREF_FILE_ALLOCATION->k,
+    PREF_MAX_DOWNLOAD_LIMIT->k,
+    PREF_NO_FILE_ALLOCATION_LIMIT->k,
+    PREF_PARAMETERIZED_URI->k,
+    PREF_REALTIME_CHUNK_CHECKSUM->k,
+    PREF_REMOVE_CONTROL_FILE->k,
+    PREF_ALWAYS_RESUME->k,
+    PREF_MAX_RESUME_FAILURE_TRIES->k,
+    PREF_HTTP_ACCEPT_GZIP->k,
+    PREF_MAX_CONNECTION_PER_SERVER->k,
+    PREF_MIN_SPLIT_SIZE->k,
+    PREF_CONDITIONAL_GET->k,
+    PREF_ENABLE_ASYNC_DNS6->k,
+    PREF_BT_TRACKER->k,
+    PREF_BT_EXCLUDE_TRACKER->k,
+    PREF_RETRY_WAIT->k,
+    PREF_METALINK_BASE_URI->k,
+    PREF_PAUSE->k,
+    PREF_STREAM_PIECE_SELECTOR->k,
+    PREF_HASH_CHECK_ONLY->k,
+    PREF_CHECKSUM->k,
+    PREF_PIECE_LENGTH->k
   };
   static std::set<std::string> requestOptions
     (vbegin(REQUEST_OPTIONS), vend(REQUEST_OPTIONS));
@@ -534,8 +534,9 @@ void createRequestGroupForUriList
     for(std::set<std::string>::const_iterator i =
           listRequestOptions().begin(), eoi = listRequestOptions().end();
         i != eoi; ++i) {
-      if(tempOption->defined(*i)) {
-        requestOption->put(*i, tempOption->get(*i));
+      const Pref* pref = option::k2p(*i);
+      if(tempOption->defined(pref)) {
+        requestOption->put(pref, tempOption->get(pref));
       }
     }
 

+ 7 - 7
src/option_processing.cc

@@ -68,13 +68,13 @@ extern void showUsage(const std::string& keyword, const OptionParser& oparser);
 
 namespace {
 void overrideWithEnv(Option& op, const OptionParser& optionParser,
-                     const std::string& pref,
+                     const Pref* pref,
                      const std::string& envName)
 {
   char* value = getenv(envName.c_str());
   if(value) {
     try {
-      optionParser.findByName(pref)->parse(op, value);
+      optionParser.findByName(pref->k)->parse(op, value);
     } catch(Exception& e) {
       global::cerr()->printf
         ("Caught Error while parsing environment variable '%s'\n%s\n",
@@ -102,16 +102,16 @@ void option_processing(Option& op, std::vector<std::string>& uris,
       noConf = op.getAsBool(PREF_NO_CONF);
       ucfname = op.get(PREF_CONF_PATH);
 
-      if(op.defined("version")) {
+      if(op.defined(PREF_VERSION)) {
         showVersion();
         exit(error_code::FINISHED);
       }
-      if(op.defined("help")) {
+      if(op.defined(PREF_HELP)) {
         std::string keyword;
-        if(op.get("help").empty()) {
+        if(op.get(PREF_HELP).empty()) {
           keyword = TAG_BASIC;
         } else {
-          keyword = op.get("help");
+          keyword = op.get(PREF_HELP);
           if(util::startsWith(keyword, "--")) {
             keyword = keyword.substr(2);
           }
@@ -130,7 +130,7 @@ void option_processing(Option& op, std::vector<std::string>& uris,
     if(!noConf) {
       std::string cfname = 
         ucfname.empty() ?
-        oparser.findByName(PREF_CONF_PATH)->getDefaultValue():
+        oparser.findByName(PREF_CONF_PATH->k)->getDefaultValue():
         ucfname;
 
       if(File(cfname).isFile()) {

+ 292 - 206
src/prefs.cc

@@ -34,8 +34,91 @@
 /* copyright --> */
 #include "prefs.h"
 
+#include <cassert>
+#include <vector>
+#include <map>
+
 namespace aria2 {
 
+Pref::Pref(const std::string& k, size_t i):k(k), i(i) {}
+
+namespace {
+
+class PrefFactory {
+public:
+  PrefFactory():count_(0)
+  {
+    // We add special null pref whose ID is 0.
+    makePref("");
+  }
+  size_t nextId()
+  {
+    return count_++;
+  }
+  Pref* makePref(const std::string& key)
+  {
+    size_t id = nextId();
+    Pref* pref = new Pref(key, id);
+    i2p_.push_back(pref);
+    k2p_[key] = pref;
+    return pref;
+  }
+  size_t getCount() const
+  {
+    return count_;
+  }
+  const Pref* i2p(size_t id) const
+  {
+    assert(id < count_);
+    return i2p_[id];
+  }
+  const Pref* k2p(const std::string& k) const
+  {
+    std::map<std::string, const Pref*>::const_iterator i = k2p_.find(k);
+    if(i == k2p_.end()) {
+      return i2p_[0];
+    } else {
+      return (*i).second;
+    }
+  }
+private:
+  size_t count_;
+  std::vector<const Pref*> i2p_;
+  std::map<std::string, const Pref*> k2p_;
+};
+
+PrefFactory* getPrefFactory()
+{
+  static PrefFactory* pf = new PrefFactory();
+  return pf;
+}
+
+Pref* makePref(const std::string& key)
+{
+  return getPrefFactory()->makePref(key);
+}
+
+} // namespace
+
+namespace option {
+
+size_t countOption()
+{
+  return getPrefFactory()->getCount();
+}
+
+const Pref* i2p(size_t id)
+{
+  return getPrefFactory()->i2p(id);
+}
+
+const Pref* k2p(const std::string& key)
+{
+  return getPrefFactory()->k2p(key);
+}
+
+} // namespace option
+
 /**
  * Constants
  */
@@ -47,388 +130,391 @@ const std::string V_MEM("mem");
 const std::string V_ALL("all");
 const std::string A2_V_FULL("full");
 const std::string A2_V_GEOM("geom");
+const std::string V_PREALLOC("prealloc");
+const std::string V_FALLOC("falloc");
+const std::string V_DEBUG("debug");
+const std::string V_INFO("info");
+const std::string V_NOTICE("notice");
+const std::string V_WARN("warn");
+const std::string V_ERROR("error");
+const std::string V_INORDER("inorder");
+const std::string V_FEEDBACK("feedback");
+const std::string V_ADAPTIVE("adaptive");
+const std::string V_EPOLL("epoll");
+const std::string V_KQUEUE("kqueue");
+const std::string V_PORT("port");
+const std::string V_POLL("poll");
+const std::string V_SELECT("select");
+const std::string V_BINARY("binary");
+const std::string V_ASCII("ascii");
+const std::string V_GET("get");
+const std::string V_TUNNEL("tunnel");
+const std::string V_PLAIN("plain");
+const std::string V_ARC4("arc4");
+const std::string V_HTTP("http");
+const std::string V_HTTPS("https");
+const std::string V_FTP("ftp");
+
+const Pref* PREF_VERSION = makePref("version");
+const Pref* PREF_HELP = makePref("help");
 
 /**
  * General preferences
  */
 // values: 1*digit
-const std::string PREF_TIMEOUT("timeout");
+const Pref* PREF_TIMEOUT = makePref("timeout");
 // values: 1*digit
-const std::string PREF_DNS_TIMEOUT("dns-timeout");
+const Pref* PREF_DNS_TIMEOUT = makePref("dns-timeout");
 // values: 1*digit
-const std::string PREF_CONNECT_TIMEOUT("connect-timeout");
+const Pref* PREF_CONNECT_TIMEOUT = makePref("connect-timeout");
 // values: 1*digit
-const std::string PREF_MAX_TRIES("max-tries");
+const Pref* PREF_MAX_TRIES = makePref("max-tries");
 // values: 1*digit
-const std::string PREF_AUTO_SAVE_INTERVAL("auto-save-interval");
+const Pref* PREF_AUTO_SAVE_INTERVAL = makePref("auto-save-interval");
 // values: a string that your file system recognizes as a file name.
-const std::string PREF_LOG("log");
+const Pref* PREF_LOG = makePref("log");
 // values: a string that your file system recognizes as a directory.
-const std::string PREF_DIR("dir");
+const Pref* PREF_DIR = makePref("dir");
 // values: a string that your file system recognizes as a file name.
-const std::string PREF_OUT("out");
+const Pref* PREF_OUT = makePref("out");
 // values: 1*digit
-const std::string PREF_SPLIT("split");
+const Pref* PREF_SPLIT = makePref("split");
 // value: true | false
-const std::string PREF_DAEMON("daemon");
+const Pref* PREF_DAEMON = makePref("daemon");
 // value: a string
-const std::string PREF_REFERER("referer");
+const Pref* PREF_REFERER = makePref("referer");
 // value: 1*digit
-const std::string PREF_LOWEST_SPEED_LIMIT("lowest-speed-limit");
+const Pref* PREF_LOWEST_SPEED_LIMIT = makePref("lowest-speed-limit");
 // value: 1*digit
-const std::string PREF_PIECE_LENGTH("piece-length");
+const Pref* PREF_PIECE_LENGTH = makePref("piece-length");
 // value: 1*digit
-const std::string PREF_MAX_OVERALL_DOWNLOAD_LIMIT("max-overall-download-limit");
+const Pref* PREF_MAX_OVERALL_DOWNLOAD_LIMIT = makePref("max-overall-download-limit");
 // value: 1*digit
-const std::string PREF_MAX_DOWNLOAD_LIMIT("max-download-limit");
+const Pref* PREF_MAX_DOWNLOAD_LIMIT = makePref("max-download-limit");
 // value: 1*digit
-const std::string PREF_STARTUP_IDLE_TIME("startup-idle-time");
+const Pref* PREF_STARTUP_IDLE_TIME = makePref("startup-idle-time");
 // value: prealloc | fallc | none
-const std::string PREF_FILE_ALLOCATION("file-allocation");
-const std::string V_PREALLOC("prealloc");
-const std::string V_FALLOC("falloc");
+const Pref* PREF_FILE_ALLOCATION = makePref("file-allocation");
 // value: 1*digit
-const std::string PREF_NO_FILE_ALLOCATION_LIMIT("no-file-allocation-limit");
+const Pref* PREF_NO_FILE_ALLOCATION_LIMIT = makePref("no-file-allocation-limit");
 // value: true | false
-const std::string PREF_ALLOW_OVERWRITE("allow-overwrite");
+const Pref* PREF_ALLOW_OVERWRITE = makePref("allow-overwrite");
 // value: true | false
-const std::string PREF_REALTIME_CHUNK_CHECKSUM("realtime-chunk-checksum");
+const Pref* PREF_REALTIME_CHUNK_CHECKSUM = makePref("realtime-chunk-checksum");
 // value: true | false
-const std::string PREF_CHECK_INTEGRITY("check-integrity");
+const Pref* PREF_CHECK_INTEGRITY = makePref("check-integrity");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_NETRC_PATH("netrc-path");
+const Pref* PREF_NETRC_PATH = makePref("netrc-path");
 // value:
-const std::string PREF_CONTINUE("continue");
+const Pref* PREF_CONTINUE = makePref("continue");
 // value:
-const std::string PREF_NO_NETRC("no-netrc");
+const Pref* PREF_NO_NETRC = makePref("no-netrc");
 // value: 1*digit
-const std::string PREF_MAX_DOWNLOADS("max-downloads");
+const Pref* PREF_MAX_DOWNLOADS = makePref("max-downloads");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_INPUT_FILE("input-file");
+const Pref* PREF_INPUT_FILE = makePref("input-file");
 // value: 1*digit
-const std::string PREF_MAX_CONCURRENT_DOWNLOADS("max-concurrent-downloads");
+const Pref* PREF_MAX_CONCURRENT_DOWNLOADS = makePref("max-concurrent-downloads");
 // value: true | false
-const std::string PREF_FORCE_SEQUENTIAL("force-sequential");
+const Pref* PREF_FORCE_SEQUENTIAL = makePref("force-sequential");
 // value: true | false
-const std::string PREF_AUTO_FILE_RENAMING("auto-file-renaming");
+const Pref* PREF_AUTO_FILE_RENAMING = makePref("auto-file-renaming");
 // value: true | false
-const std::string PREF_PARAMETERIZED_URI("parameterized-uri");
+const Pref* PREF_PARAMETERIZED_URI = makePref("parameterized-uri");
 // value: true | false
-const std::string PREF_ENABLE_DIRECT_IO("enable-direct-io");
+const Pref* PREF_ENABLE_DIRECT_IO = makePref("enable-direct-io");
 // value: true | false
-const std::string PREF_ALLOW_PIECE_LENGTH_CHANGE("allow-piece-length-change");
+const Pref* PREF_ALLOW_PIECE_LENGTH_CHANGE = makePref("allow-piece-length-change");
 // value: true | false
-const std::string PREF_NO_CONF("no-conf");
+const Pref* PREF_NO_CONF = makePref("no-conf");
 // value: string
-const std::string PREF_CONF_PATH("conf-path");
+const Pref* PREF_CONF_PATH = makePref("conf-path");
 // value: 1*digit
-const std::string PREF_STOP("stop");
+const Pref* PREF_STOP = makePref("stop");
 // value: true | false
-const std::string PREF_QUIET("quiet");
+const Pref* PREF_QUIET = makePref("quiet");
 // value: true | false
-const std::string PREF_ASYNC_DNS("async-dns");
+const Pref* PREF_ASYNC_DNS = makePref("async-dns");
 // value: 1*digit
-const std::string PREF_SUMMARY_INTERVAL("summary-interval");
+const Pref* PREF_SUMMARY_INTERVAL = makePref("summary-interval");
 // value: debug, info, notice, warn, error
-const std::string PREF_LOG_LEVEL("log-level");
-const std::string V_DEBUG("debug");
-const std::string V_INFO("info");
-const std::string V_NOTICE("notice");
-const std::string V_WARN("warn");
-const std::string V_ERROR("error");
+const Pref* PREF_LOG_LEVEL = makePref("log-level");
 // value: inorder | feedback | adaptive
-const std::string PREF_URI_SELECTOR("uri-selector");
-const std::string V_INORDER("inorder");
-const std::string V_FEEDBACK("feedback");
-const std::string V_ADAPTIVE("adaptive");
+const Pref* PREF_URI_SELECTOR = makePref("uri-selector");
 // value: 1*digit
-const std::string PREF_SERVER_STAT_TIMEOUT("server-stat-timeout");
+const Pref* PREF_SERVER_STAT_TIMEOUT = makePref("server-stat-timeout");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_SERVER_STAT_IF("server-stat-if");
+const Pref* PREF_SERVER_STAT_IF = makePref("server-stat-if");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_SERVER_STAT_OF("server-stat-of");
+const Pref* PREF_SERVER_STAT_OF = makePref("server-stat-of");
 // value: true | false
-const std::string PREF_REMOTE_TIME("remote-time");
+const Pref* PREF_REMOTE_TIME = makePref("remote-time");
 // value: 1*digit
-const std::string PREF_MAX_FILE_NOT_FOUND("max-file-not-found");
+const Pref* PREF_MAX_FILE_NOT_FOUND = makePref("max-file-not-found");
 // value: epoll | select
-const std::string PREF_EVENT_POLL("event-poll");
-const std::string V_EPOLL("epoll");
-const std::string V_KQUEUE("kqueue");
-const std::string V_PORT("port");
-const std::string V_POLL("poll");
-const std::string V_SELECT("select");
+const Pref* PREF_EVENT_POLL = makePref("event-poll");
 // value: true | false
-const std::string PREF_ENABLE_RPC("enable-rpc");
+const Pref* PREF_ENABLE_RPC = makePref("enable-rpc");
 // value: 1*digit
-const std::string PREF_RPC_LISTEN_PORT("rpc-listen-port");
+const Pref* PREF_RPC_LISTEN_PORT = makePref("rpc-listen-port");
 // value: string
-const std::string PREF_RPC_USER("rpc-user");
+const Pref* PREF_RPC_USER = makePref("rpc-user");
 // value: string
-const std::string PREF_RPC_PASSWD("rpc-passwd");
+const Pref* PREF_RPC_PASSWD = makePref("rpc-passwd");
 // value: 1*digit
-const std::string PREF_RPC_MAX_REQUEST_SIZE("rpc-max-request-size");
+const Pref* PREF_RPC_MAX_REQUEST_SIZE = makePref("rpc-max-request-size");
 // value: true | false
-const std::string PREF_RPC_LISTEN_ALL("rpc-listen-all");
+const Pref* PREF_RPC_LISTEN_ALL = makePref("rpc-listen-all");
 // value: true | false
-const std::string PREF_RPC_ALLOW_ORIGIN_ALL("rpc-allow-origin-all");
+const Pref* PREF_RPC_ALLOW_ORIGIN_ALL = makePref("rpc-allow-origin-all");
 // value: true | false
-const std::string PREF_DRY_RUN("dry-run");
+const Pref* PREF_DRY_RUN = makePref("dry-run");
 // value: true | false
-const std::string PREF_REUSE_URI("reuse-uri");
+const Pref* PREF_REUSE_URI = makePref("reuse-uri");
 // value: string
-const std::string PREF_ON_DOWNLOAD_START("on-download-start");
-const std::string PREF_ON_DOWNLOAD_PAUSE("on-download-pause");
-const std::string PREF_ON_DOWNLOAD_STOP("on-download-stop");
-const std::string PREF_ON_DOWNLOAD_COMPLETE("on-download-complete");
-const std::string PREF_ON_DOWNLOAD_ERROR("on-download-error");
+const Pref* PREF_ON_DOWNLOAD_START = makePref("on-download-start");
+const Pref* PREF_ON_DOWNLOAD_PAUSE = makePref("on-download-pause");
+const Pref* PREF_ON_DOWNLOAD_STOP = makePref("on-download-stop");
+const Pref* PREF_ON_DOWNLOAD_COMPLETE = makePref("on-download-complete");
+const Pref* PREF_ON_DOWNLOAD_ERROR = makePref("on-download-error");
 // value: string
-const std::string PREF_INTERFACE("interface");
+const Pref* PREF_INTERFACE = makePref("interface");
 // value: true | false
-const std::string PREF_DISABLE_IPV6("disable-ipv6");
+const Pref* PREF_DISABLE_IPV6 = makePref("disable-ipv6");
 // value: true | false
-const std::string PREF_HUMAN_READABLE("human-readable");
+const Pref* PREF_HUMAN_READABLE = makePref("human-readable");
 // value: true | false
-const std::string PREF_REMOVE_CONTROL_FILE("remove-control-file");
+const Pref* PREF_REMOVE_CONTROL_FILE = makePref("remove-control-file");
 // value: true | false
-const std::string PREF_ALWAYS_RESUME("always-resume");
+const Pref* PREF_ALWAYS_RESUME = makePref("always-resume");
 // value: 1*digit
-const std::string PREF_MAX_RESUME_FAILURE_TRIES("max-resume-failure-tries");
+const Pref* PREF_MAX_RESUME_FAILURE_TRIES = makePref("max-resume-failure-tries");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_SAVE_SESSION("save-session");
+const Pref* PREF_SAVE_SESSION = makePref("save-session");
 // value: 1*digit
-const std::string PREF_MAX_CONNECTION_PER_SERVER("max-connection-per-server");
+const Pref* PREF_MAX_CONNECTION_PER_SERVER = makePref("max-connection-per-server");
 // value: 1*digit
-const std::string PREF_MIN_SPLIT_SIZE("min-split-size");
+const Pref* PREF_MIN_SPLIT_SIZE = makePref("min-split-size");
 // value: true | false
-const std::string PREF_CONDITIONAL_GET("conditional-get");
+const Pref* PREF_CONDITIONAL_GET = makePref("conditional-get");
 // value: true | false
-const std::string PREF_SELECT_LEAST_USED_HOST("select-least-used-host");
+const Pref* PREF_SELECT_LEAST_USED_HOST = makePref("select-least-used-host");
 // value: true | false
-const std::string PREF_ENABLE_ASYNC_DNS6("enable-async-dns6");
+const Pref* PREF_ENABLE_ASYNC_DNS6 = makePref("enable-async-dns6");
 // value: 1*digit
-const std::string PREF_MAX_DOWNLOAD_RESULT("max-download-result");
+const Pref* PREF_MAX_DOWNLOAD_RESULT = makePref("max-download-result");
 // value: 1*digit
-const std::string PREF_RETRY_WAIT("retry-wait");
+const Pref* PREF_RETRY_WAIT = makePref("retry-wait");
 // value: string
-const std::string PREF_ASYNC_DNS_SERVER("async-dns-server");
+const Pref* PREF_ASYNC_DNS_SERVER = makePref("async-dns-server");
 // value: true | false
-const std::string PREF_SHOW_CONSOLE_READOUT("show-console-readout");
+const Pref* PREF_SHOW_CONSOLE_READOUT = makePref("show-console-readout");
 // value: default | inorder
-const std::string PREF_STREAM_PIECE_SELECTOR("stream-piece-selector");
+const Pref* PREF_STREAM_PIECE_SELECTOR = makePref("stream-piece-selector");
 // value: true | false
-const std::string PREF_TRUNCATE_CONSOLE_READOUT("truncate-console-readout");
+const Pref* PREF_TRUNCATE_CONSOLE_READOUT = makePref("truncate-console-readout");
 // value: true | false
-const std::string PREF_PAUSE("pause");
+const Pref* PREF_PAUSE = makePref("pause");
 // value: default | full
-const std::string PREF_DOWNLOAD_RESULT("download-result");
+const Pref* PREF_DOWNLOAD_RESULT = makePref("download-result");
 // value: true | false
-const std::string PREF_HASH_CHECK_ONLY("hash-check-only");
+const Pref* PREF_HASH_CHECK_ONLY = makePref("hash-check-only");
 // values: hashType=digest
-const std::string PREF_CHECKSUM("checksum");
+const Pref* PREF_CHECKSUM = makePref("checksum");
 
 /**
  * FTP related preferences
  */
-const std::string PREF_FTP_USER("ftp-user");
-const std::string PREF_FTP_PASSWD("ftp-passwd");
+const Pref* PREF_FTP_USER = makePref("ftp-user");
+const Pref* PREF_FTP_PASSWD = makePref("ftp-passwd");
 // values: binary | ascii
-const std::string PREF_FTP_TYPE("ftp-type");
-const std::string V_BINARY("binary");
-const std::string V_ASCII("ascii");
+const Pref* PREF_FTP_TYPE = makePref("ftp-type");
 // values: true | false
-const std::string PREF_FTP_PASV("ftp-pasv");
+const Pref* PREF_FTP_PASV = makePref("ftp-pasv");
 // values: true | false
-const std::string PREF_FTP_REUSE_CONNECTION("ftp-reuse-connection");
+const Pref* PREF_FTP_REUSE_CONNECTION = makePref("ftp-reuse-connection");
 
 /**
  * HTTP related preferences
  */
-const std::string PREF_HTTP_USER("http-user");
-const std::string PREF_HTTP_PASSWD("http-passwd");
+const Pref* PREF_HTTP_USER = makePref("http-user");
+const Pref* PREF_HTTP_PASSWD = makePref("http-passwd");
 // values: string
-const std::string PREF_USER_AGENT("user-agent");
+const Pref* PREF_USER_AGENT = makePref("user-agent");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_LOAD_COOKIES("load-cookies");
+const Pref* PREF_LOAD_COOKIES = makePref("load-cookies");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_SAVE_COOKIES("save-cookies");
+const Pref* PREF_SAVE_COOKIES = makePref("save-cookies");
 // values: true | false
-const std::string PREF_ENABLE_HTTP_KEEP_ALIVE("enable-http-keep-alive");
+const Pref* PREF_ENABLE_HTTP_KEEP_ALIVE = makePref("enable-http-keep-alive");
 // values: true | false
-const std::string PREF_ENABLE_HTTP_PIPELINING("enable-http-pipelining");
+const Pref* PREF_ENABLE_HTTP_PIPELINING = makePref("enable-http-pipelining");
 // value: 1*digit
-const std::string PREF_MAX_HTTP_PIPELINING("max-http-pipelining");
+const Pref* PREF_MAX_HTTP_PIPELINING = makePref("max-http-pipelining");
 // value: string
-const std::string PREF_HEADER("header");
+const Pref* PREF_HEADER = makePref("header");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_CERTIFICATE("certificate");
+const Pref* PREF_CERTIFICATE = makePref("certificate");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_PRIVATE_KEY("private-key");
+const Pref* PREF_PRIVATE_KEY = makePref("private-key");
 // value: string that your file system recognizes as a file name.
-const std::string PREF_CA_CERTIFICATE("ca-certificate");
+const Pref* PREF_CA_CERTIFICATE = makePref("ca-certificate");
 // value: true | false
-const std::string PREF_CHECK_CERTIFICATE("check-certificate");
+const Pref* PREF_CHECK_CERTIFICATE = makePref("check-certificate");
 // value: true | false
-const std::string PREF_USE_HEAD("use-head");
+const Pref* PREF_USE_HEAD = makePref("use-head");
 // value: true | false
-const std::string PREF_HTTP_AUTH_CHALLENGE("http-auth-challenge");
+const Pref* PREF_HTTP_AUTH_CHALLENGE = makePref("http-auth-challenge");
 // value: true | false
-const std::string PREF_HTTP_NO_CACHE("http-no-cache");
+const Pref* PREF_HTTP_NO_CACHE = makePref("http-no-cache");
 // value: true | false
-const std::string PREF_HTTP_ACCEPT_GZIP("http-accept-gzip");
+const Pref* PREF_HTTP_ACCEPT_GZIP = makePref("http-accept-gzip");
 
 /** 
  * Proxy related preferences
  */
-const std::string PREF_HTTP_PROXY("http-proxy");
-const std::string PREF_HTTPS_PROXY("https-proxy");
-const std::string PREF_FTP_PROXY("ftp-proxy");
-const std::string PREF_ALL_PROXY("all-proxy");
+const Pref* PREF_HTTP_PROXY = makePref("http-proxy");
+const Pref* PREF_HTTPS_PROXY = makePref("https-proxy");
+const Pref* PREF_FTP_PROXY = makePref("ftp-proxy");
+const Pref* PREF_ALL_PROXY = makePref("all-proxy");
 // values: comma separeted hostname or domain
-const std::string PREF_NO_PROXY("no-proxy");
+const Pref* PREF_NO_PROXY = makePref("no-proxy");
 // values: get | tunnel
-const std::string PREF_PROXY_METHOD("proxy-method");
-const std::string V_GET("get");
-const std::string V_TUNNEL("tunnel");
-const std::string PREF_HTTP_PROXY_USER("http-proxy-user");
-const std::string PREF_HTTP_PROXY_PASSWD("http-proxy-passwd");
-const std::string PREF_HTTPS_PROXY_USER("https-proxy-user");
-const std::string PREF_HTTPS_PROXY_PASSWD("https-proxy-passwd");
-const std::string PREF_FTP_PROXY_USER("ftp-proxy-user");
-const std::string PREF_FTP_PROXY_PASSWD("ftp-proxy-passwd");
-const std::string PREF_ALL_PROXY_USER("all-proxy-user");
-const std::string PREF_ALL_PROXY_PASSWD("all-proxy-passwd");
+const Pref* PREF_PROXY_METHOD = makePref("proxy-method");
+const Pref* PREF_HTTP_PROXY_USER = makePref("http-proxy-user");
+const Pref* PREF_HTTP_PROXY_PASSWD = makePref("http-proxy-passwd");
+const Pref* PREF_HTTPS_PROXY_USER = makePref("https-proxy-user");
+const Pref* PREF_HTTPS_PROXY_PASSWD = makePref("https-proxy-passwd");
+const Pref* PREF_FTP_PROXY_USER = makePref("ftp-proxy-user");
+const Pref* PREF_FTP_PROXY_PASSWD = makePref("ftp-proxy-passwd");
+const Pref* PREF_ALL_PROXY_USER = makePref("all-proxy-user");
+const Pref* PREF_ALL_PROXY_PASSWD = makePref("all-proxy-passwd");
 
 /**
  * BitTorrent related preferences
  */
 // values: 1*digit
-const std::string PREF_PEER_CONNECTION_TIMEOUT("peer-connection-timeout");
+const Pref* PREF_PEER_CONNECTION_TIMEOUT = makePref("peer-connection-timeout");
 // values: 1*digit
-const std::string PREF_BT_TIMEOUT("bt-timeout");
+const Pref* PREF_BT_TIMEOUT = makePref("bt-timeout");
 // values: 1*digit
-const std::string PREF_BT_REQUEST_TIMEOUT("bt-request-timeout");
+const Pref* PREF_BT_REQUEST_TIMEOUT = makePref("bt-request-timeout");
 // values: true | false
-const std::string PREF_SHOW_FILES("show-files");
+const Pref* PREF_SHOW_FILES = makePref("show-files");
 // values: 1*digit
-const std::string PREF_MAX_OVERALL_UPLOAD_LIMIT("max-overall-upload-limit");
+const Pref* PREF_MAX_OVERALL_UPLOAD_LIMIT = makePref("max-overall-upload-limit");
 // values: 1*digit
-const std::string PREF_MAX_UPLOAD_LIMIT("max-upload-limit");
+const Pref* PREF_MAX_UPLOAD_LIMIT = makePref("max-upload-limit");
 // values: a string that your file system recognizes as a file name.
-const std::string PREF_TORRENT_FILE("torrent-file");
+const Pref* PREF_TORRENT_FILE = makePref("torrent-file");
 // values: 1*digit
-const std::string PREF_LISTEN_PORT("listen-port");
+const Pref* PREF_LISTEN_PORT = makePref("listen-port");
 // values: true | false | mem
-const std::string PREF_FOLLOW_TORRENT("follow-torrent");
-// values: 1*digit *( (,|-) 1*digit);
-const std::string PREF_SELECT_FILE("select-file");
+const Pref* PREF_FOLLOW_TORRENT = makePref("follow-torrent");
+// values: 1*digit * = makePref(  = makePref(,|-) 1*digit);
+const Pref* PREF_SELECT_FILE = makePref("select-file");
 // values: 1*digit
-const std::string PREF_SEED_TIME("seed-time");
+const Pref* PREF_SEED_TIME = makePref("seed-time");
 // values: 1*digit ['.' [ 1*digit ] ]
-const std::string PREF_SEED_RATIO("seed-ratio");
+const Pref* PREF_SEED_RATIO = makePref("seed-ratio");
 // values: 1*digit
-const std::string PREF_BT_KEEP_ALIVE_INTERVAL("bt-keep-alive-interval");
+const Pref* PREF_BT_KEEP_ALIVE_INTERVAL = makePref("bt-keep-alive-interval");
 // values: a string, less than or equals to 20 bytes length
-const std::string PREF_PEER_ID_PREFIX("peer-id-prefix");
+const Pref* PREF_PEER_ID_PREFIX = makePref("peer-id-prefix");
 // values: true | false
-const std::string PREF_ENABLE_PEER_EXCHANGE("enable-peer-exchange");
+const Pref* PREF_ENABLE_PEER_EXCHANGE = makePref("enable-peer-exchange");
 // values: true | false
-const std::string PREF_ENABLE_DHT("enable-dht");
+const Pref* PREF_ENABLE_DHT = makePref("enable-dht");
 // values: a string
-const std::string PREF_DHT_LISTEN_ADDR("dht-listen-addr");
+const Pref* PREF_DHT_LISTEN_ADDR = makePref("dht-listen-addr");
 // values: 1*digit
-const std::string PREF_DHT_LISTEN_PORT("dht-listen-port");
+const Pref* PREF_DHT_LISTEN_PORT = makePref("dht-listen-port");
 // values: a string
-const std::string PREF_DHT_ENTRY_POINT_HOST("dht-entry-point-host");
+const Pref* PREF_DHT_ENTRY_POINT_HOST = makePref("dht-entry-point-host");
 // values: 1*digit
-const std::string PREF_DHT_ENTRY_POINT_PORT("dht-entry-point-port");
-// values: a string (hostname:port);
-const std::string PREF_DHT_ENTRY_POINT("dht-entry-point");
+const Pref* PREF_DHT_ENTRY_POINT_PORT = makePref("dht-entry-point-port");
+// values: a string  = makePref(hostname:port);
+const Pref* PREF_DHT_ENTRY_POINT = makePref("dht-entry-point");
 // values: a string
-const std::string PREF_DHT_FILE_PATH("dht-file-path");
+const Pref* PREF_DHT_FILE_PATH = makePref("dht-file-path");
 // values: true | false
-const std::string PREF_ENABLE_DHT6("enable-dht6");
+const Pref* PREF_ENABLE_DHT6 = makePref("enable-dht6");
 // values: a string
-const std::string PREF_DHT_LISTEN_ADDR6("dht-listen-addr6");
+const Pref* PREF_DHT_LISTEN_ADDR6 = makePref("dht-listen-addr6");
 // values: a string
-const std::string PREF_DHT_ENTRY_POINT_HOST6("dht-entry-point-host6");
+const Pref* PREF_DHT_ENTRY_POINT_HOST6 = makePref("dht-entry-point-host6");
 // values: 1*digit
-const std::string PREF_DHT_ENTRY_POINT_PORT6("dht-entry-point-port6");
-// values: a string (hostname:port)
-const std::string PREF_DHT_ENTRY_POINT6("dht-entry-point6");
+const Pref* PREF_DHT_ENTRY_POINT_PORT6 = makePref("dht-entry-point-port6");
+// values: a string  = makePref(hostname:port)
+const Pref* PREF_DHT_ENTRY_POINT6 = makePref("dht-entry-point6");
 // values: a string
-const std::string PREF_DHT_FILE_PATH6("dht-file-path6");
+const Pref* PREF_DHT_FILE_PATH6 = makePref("dht-file-path6");
 // values: plain | arc4
-const std::string PREF_BT_MIN_CRYPTO_LEVEL("bt-min-crypto-level");
-const std::string V_PLAIN("plain");
-const std::string V_ARC4("arc4");
+const Pref* PREF_BT_MIN_CRYPTO_LEVEL = makePref("bt-min-crypto-level");
 // values:: true | false
-const std::string PREF_BT_REQUIRE_CRYPTO("bt-require-crypto");
+const Pref* PREF_BT_REQUIRE_CRYPTO = makePref("bt-require-crypto");
 // values: 1*digit
-const std::string PREF_BT_REQUEST_PEER_SPEED_LIMIT("bt-request-peer-speed-limit");
+const Pref* PREF_BT_REQUEST_PEER_SPEED_LIMIT = makePref("bt-request-peer-speed-limit");
 // values: 1*digit
-const std::string PREF_BT_MAX_OPEN_FILES("bt-max-open-files");
+const Pref* PREF_BT_MAX_OPEN_FILES = makePref("bt-max-open-files");
 // values: true | false
-const std::string PREF_BT_SEED_UNVERIFIED("bt-seed-unverified");
+const Pref* PREF_BT_SEED_UNVERIFIED = makePref("bt-seed-unverified");
 // values: true | false
-const std::string PREF_BT_HASH_CHECK_SEED("bt-hash-check-seed");
+const Pref* PREF_BT_HASH_CHECK_SEED = makePref("bt-hash-check-seed");
 // values: 1*digit
-const std::string PREF_BT_MAX_PEERS("bt-max-peers");
-// values: a string (IP address)
-const std::string PREF_BT_EXTERNAL_IP("bt-external-ip");
+const Pref* PREF_BT_MAX_PEERS = makePref("bt-max-peers");
+// values: a string  = makePref(IP address)
+const Pref* PREF_BT_EXTERNAL_IP = makePref("bt-external-ip");
 // values: 1*digit '=' a string that your file system recognizes as a file name.
-const std::string PREF_INDEX_OUT("index-out");
+const Pref* PREF_INDEX_OUT = makePref("index-out");
 // values: 1*digit
-const std::string PREF_BT_TRACKER_INTERVAL("bt-tracker-interval");
+const Pref* PREF_BT_TRACKER_INTERVAL = makePref("bt-tracker-interval");
 // values: 1*digit
-const std::string PREF_BT_STOP_TIMEOUT("bt-stop-timeout");
+const Pref* PREF_BT_STOP_TIMEOUT = makePref("bt-stop-timeout");
 // values: head[=SIZE]|tail[=SIZE], ...
-const std::string PREF_BT_PRIORITIZE_PIECE("bt-prioritize-piece");
+const Pref* PREF_BT_PRIORITIZE_PIECE = makePref("bt-prioritize-piece");
 // values: true | false
-const std::string PREF_BT_SAVE_METADATA("bt-save-metadata");
+const Pref* PREF_BT_SAVE_METADATA = makePref("bt-save-metadata");
 // values: true | false
-const std::string PREF_BT_METADATA_ONLY("bt-metadata-only");
+const Pref* PREF_BT_METADATA_ONLY = makePref("bt-metadata-only");
 // values: true | false
-const std::string PREF_BT_ENABLE_LPD("bt-enable-lpd");
+const Pref* PREF_BT_ENABLE_LPD = makePref("bt-enable-lpd");
 // values: string
-const std::string PREF_BT_LPD_INTERFACE("bt-lpd-interface");
+const Pref* PREF_BT_LPD_INTERFACE = makePref("bt-lpd-interface");
 // values: 1*digit
-const std::string PREF_BT_TRACKER_TIMEOUT("bt-tracker-timeout");
+const Pref* PREF_BT_TRACKER_TIMEOUT = makePref("bt-tracker-timeout");
 // values: 1*digit
-const std::string PREF_BT_TRACKER_CONNECT_TIMEOUT("bt-tracker-connect-timeout");
+const Pref* PREF_BT_TRACKER_CONNECT_TIMEOUT = makePref("bt-tracker-connect-timeout");
 // values: 1*digit
-const std::string PREF_DHT_MESSAGE_TIMEOUT("dht-message-timeout");
+const Pref* PREF_DHT_MESSAGE_TIMEOUT = makePref("dht-message-timeout");
 // values: string
-const std::string PREF_ON_BT_DOWNLOAD_COMPLETE("on-bt-download-complete");
+const Pref* PREF_ON_BT_DOWNLOAD_COMPLETE = makePref("on-bt-download-complete");
 // values: string
-const std::string PREF_BT_TRACKER("bt-tracker");
+const Pref* PREF_BT_TRACKER = makePref("bt-tracker");
 // values: string
-const std::string PREF_BT_EXCLUDE_TRACKER("bt-exclude-tracker");
+const Pref* PREF_BT_EXCLUDE_TRACKER = makePref("bt-exclude-tracker");
 
 /**
  * Metalink related preferences
  */
 // values: a string that your file system recognizes as a file name.
-const std::string PREF_METALINK_FILE("metalink-file");
+const Pref* PREF_METALINK_FILE = makePref("metalink-file");
 // values: a string
-const std::string PREF_METALINK_VERSION("metalink-version");
+const Pref* PREF_METALINK_VERSION = makePref("metalink-version");
 // values: a string
-const std::string PREF_METALINK_LANGUAGE("metalink-language");
+const Pref* PREF_METALINK_LANGUAGE = makePref("metalink-language");
 // values: a string
-const std::string PREF_METALINK_OS("metalink-os");
+const Pref* PREF_METALINK_OS = makePref("metalink-os");
 // values: a string
-const std::string PREF_METALINK_LOCATION("metalink-location");
+const Pref* PREF_METALINK_LOCATION = makePref("metalink-location");
 // values: 1*digit
-const std::string PREF_METALINK_SERVERS("metalink-servers");
+const Pref* PREF_METALINK_SERVERS = makePref("metalink-servers");
 // values: true | false | mem
-const std::string PREF_FOLLOW_METALINK("follow-metalink");
+const Pref* PREF_FOLLOW_METALINK = makePref("follow-metalink");
 // values: http | https | ftp | none
-const std::string PREF_METALINK_PREFERRED_PROTOCOL("metalink-preferred-protocol");
-const std::string V_HTTP("http");
-const std::string V_HTTPS("https");
-const std::string V_FTP("ftp");
+const Pref* PREF_METALINK_PREFERRED_PROTOCOL = makePref("metalink-preferred-protocol");
 // values: true | false
-const std::string PREF_METALINK_ENABLE_UNIQUE_PROTOCOL("metalink-enable-unique-protocol");
-const std::string PREF_METALINK_BASE_URI("metalink-base-uri");
+const Pref* PREF_METALINK_ENABLE_UNIQUE_PROTOCOL = makePref("metalink-enable-unique-protocol");
+const Pref* PREF_METALINK_BASE_URI = makePref("metalink-base-uri");
 
 } // namespace aria2

+ 227 - 202
src/prefs.h

@@ -40,6 +40,28 @@
 
 namespace aria2 {
 
+struct Pref {
+  Pref(const std::string& k, size_t i);
+  // Keyword, aka Option Name
+  std::string k;
+  // Option ID
+  size_t i;
+};
+
+namespace option {
+
+// Returns the number of options.
+size_t countOption();
+
+// Returns Pref whose ID is id. id must be less than countOption().
+const Pref* i2p(size_t id);
+
+// Returns Pref whose keyword is k. If no such Pref is found, returns
+// special null Pref whose ID is 0.
+const Pref* k2p(const std::string& k);
+
+} // namespace option
+
 /**
  * Constants
  */
@@ -51,390 +73,393 @@ extern const std::string V_MEM;
 extern const std::string V_ALL;
 extern const std::string A2_V_FULL;
 extern const std::string A2_V_GEOM;
+extern const std::string V_PREALLOC;
+extern const std::string V_FALLOC;
+extern const std::string V_DEBUG;
+extern const std::string V_INFO;
+extern const std::string V_NOTICE;
+extern const std::string V_WARN;
+extern const std::string V_ERROR;
+extern const std::string V_INORDER;
+extern const std::string V_FEEDBACK;
+extern const std::string V_ADAPTIVE;
+extern const std::string V_EPOLL;
+extern const std::string V_KQUEUE;
+extern const std::string V_PORT;
+extern const std::string V_POLL;
+extern const std::string V_SELECT;
+extern const std::string V_BINARY;
+extern const std::string V_ASCII;
+extern const std::string V_GET;
+extern const std::string V_TUNNEL;
+extern const std::string V_PLAIN;
+extern const std::string V_ARC4;
+extern const std::string V_HTTP;
+extern const std::string V_HTTPS;
+extern const std::string V_FTP;
+
+extern const Pref* PREF_VERSION;
+extern const Pref* PREF_HELP;
 
 /**
  * General preferences
  */
 // values: 1*digit
-extern const std::string PREF_TIMEOUT;
+extern const Pref* PREF_TIMEOUT;
 // values: 1*digit
-extern const std::string PREF_DNS_TIMEOUT;
+extern const Pref* PREF_DNS_TIMEOUT;
 // values: 1*digit
-extern const std::string PREF_CONNECT_TIMEOUT;
+extern const Pref* PREF_CONNECT_TIMEOUT;
 // values: 1*digit
-extern const std::string PREF_MAX_TRIES;
+extern const Pref* PREF_MAX_TRIES;
 // values: 1*digit
-extern const std::string PREF_AUTO_SAVE_INTERVAL;
+extern const Pref* PREF_AUTO_SAVE_INTERVAL;
 // values: a string that your file system recognizes as a file name.
-extern const std::string PREF_LOG;
+extern const Pref* PREF_LOG;
 // values: a string that your file system recognizes as a directory.
-extern const std::string PREF_DIR;
+extern const Pref* PREF_DIR;
 // values: a string that your file system recognizes as a file name.
-extern const std::string PREF_OUT;
+extern const Pref* PREF_OUT;
 // values: 1*digit
-extern const std::string PREF_SPLIT;
+extern const Pref* PREF_SPLIT;
 // value: true | false
-extern const std::string PREF_DAEMON;
+extern const Pref* PREF_DAEMON;
 // value: a string
-extern const std::string PREF_REFERER;
+extern const Pref* PREF_REFERER;
 // value: 1*digit
-extern const std::string PREF_LOWEST_SPEED_LIMIT;
+extern const Pref* PREF_LOWEST_SPEED_LIMIT;
 // value: 1*digit
-extern const std::string PREF_PIECE_LENGTH;
+extern const Pref* PREF_PIECE_LENGTH;
 // value: 1*digit
-extern const std::string PREF_MAX_DOWNLOAD_LIMIT;
+extern const Pref* PREF_MAX_DOWNLOAD_LIMIT;
 // value: 1*digit
-extern const std::string PREF_STARTUP_IDLE_TIME;
+extern const Pref* PREF_STARTUP_IDLE_TIME;
 // value: prealloc | falloc | none
-extern const std::string PREF_FILE_ALLOCATION;
-extern const std::string V_PREALLOC;
-extern const std::string V_FALLOC;
+extern const Pref* PREF_FILE_ALLOCATION;
 // value: 1*digit
-extern const std::string PREF_NO_FILE_ALLOCATION_LIMIT;
+extern const Pref* PREF_NO_FILE_ALLOCATION_LIMIT;
 // value: true | false
-extern const std::string PREF_ALLOW_OVERWRITE;
+extern const Pref* PREF_ALLOW_OVERWRITE;
 // value: true | false
-extern const std::string PREF_REALTIME_CHUNK_CHECKSUM;
+extern const Pref* PREF_REALTIME_CHUNK_CHECKSUM;
 // value: true | false
-extern const std::string PREF_CHECK_INTEGRITY;
+extern const Pref* PREF_CHECK_INTEGRITY;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_NETRC_PATH;
+extern const Pref* PREF_NETRC_PATH;
 // value:
-extern const std::string PREF_CONTINUE;
+extern const Pref* PREF_CONTINUE;
 // value:
-extern const std::string PREF_NO_NETRC;
+extern const Pref* PREF_NO_NETRC;
 // value: 1*digit
-extern const std::string PREF_MAX_OVERALL_DOWNLOAD_LIMIT;
+extern const Pref* PREF_MAX_OVERALL_DOWNLOAD_LIMIT;
 // value: 1*digit
-extern const std::string PREF_MAX_DOWNLOADS;
+extern const Pref* PREF_MAX_DOWNLOADS;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_INPUT_FILE;
+extern const Pref* PREF_INPUT_FILE;
 // value: 1*digit
-extern const std::string PREF_MAX_CONCURRENT_DOWNLOADS;
+extern const Pref* PREF_MAX_CONCURRENT_DOWNLOADS;
 // value: true | false
-extern const std::string PREF_FORCE_SEQUENTIAL;
+extern const Pref* PREF_FORCE_SEQUENTIAL;
 // value: true | false
-extern const std::string PREF_AUTO_FILE_RENAMING;
+extern const Pref* PREF_AUTO_FILE_RENAMING;
 // value: true | false
-extern const std::string PREF_PARAMETERIZED_URI;
+extern const Pref* PREF_PARAMETERIZED_URI;
 // value: true | false
-extern const std::string PREF_ENABLE_DIRECT_IO;
+extern const Pref* PREF_ENABLE_DIRECT_IO;
 // value: true | false
-extern const std::string PREF_ALLOW_PIECE_LENGTH_CHANGE;
+extern const Pref* PREF_ALLOW_PIECE_LENGTH_CHANGE;
 // value: true | false
-extern const std::string PREF_NO_CONF;
+extern const Pref* PREF_NO_CONF;
 // value: string
-extern const std::string PREF_CONF_PATH;
+extern const Pref* PREF_CONF_PATH;
 // value: 1*digit
-extern const std::string PREF_STOP;
+extern const Pref* PREF_STOP;
 // value: true | false
-extern const std::string PREF_QUIET;
+extern const Pref* PREF_QUIET;
 // value: true | false
-extern const std::string PREF_ASYNC_DNS;
+extern const Pref* PREF_ASYNC_DNS;
 // value: 1*digit
-extern const std::string PREF_SUMMARY_INTERVAL;
+extern const Pref* PREF_SUMMARY_INTERVAL;
 // value: debug, info, notice, warn, error
-extern const std::string PREF_LOG_LEVEL;
-extern const std::string V_DEBUG;
-extern const std::string V_INFO;
-extern const std::string V_NOTICE;
-extern const std::string V_WARN;
-extern const std::string V_ERROR;
+extern const Pref* PREF_LOG_LEVEL;
 // value: inorder | feedback | adaptive
-extern const std::string PREF_URI_SELECTOR;
-extern const std::string V_INORDER;
-extern const std::string V_FEEDBACK;
-extern const std::string V_ADAPTIVE;
+extern const Pref* PREF_URI_SELECTOR;
 // value: 1*digit
-extern const std::string PREF_SERVER_STAT_TIMEOUT;
+extern const Pref* PREF_SERVER_STAT_TIMEOUT;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_SERVER_STAT_IF;
+extern const Pref* PREF_SERVER_STAT_IF;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_SERVER_STAT_OF;
+extern const Pref* PREF_SERVER_STAT_OF;
 // value: true | false
-extern const std::string PREF_REMOTE_TIME;
+extern const Pref* PREF_REMOTE_TIME;
 // value: 1*digit
-extern const std::string PREF_MAX_FILE_NOT_FOUND;
+extern const Pref* PREF_MAX_FILE_NOT_FOUND;
 // value: epoll | select
-extern const std::string PREF_EVENT_POLL;
-extern const std::string V_EPOLL;
-extern const std::string V_KQUEUE;
-extern const std::string V_PORT;
-extern const std::string V_POLL;
-extern const std::string V_SELECT;
+extern const Pref* PREF_EVENT_POLL;
 // value: true | false
-extern const std::string PREF_ENABLE_RPC;
+extern const Pref* PREF_ENABLE_RPC;
 // value: 1*digit
-extern const std::string PREF_RPC_LISTEN_PORT;
+extern const Pref* PREF_RPC_LISTEN_PORT;
 // value: string
-extern const std::string PREF_RPC_USER;
+extern const Pref* PREF_RPC_USER;
 // value: string
-extern const std::string PREF_RPC_PASSWD;
+extern const Pref* PREF_RPC_PASSWD;
 // value: 1*digit
-extern const std::string PREF_RPC_MAX_REQUEST_SIZE;
+extern const Pref* PREF_RPC_MAX_REQUEST_SIZE;
 // value: true | false
-extern const std::string PREF_RPC_LISTEN_ALL;
+extern const Pref* PREF_RPC_LISTEN_ALL;
 // value: true | false
-extern const std::string PREF_RPC_ALLOW_ORIGIN_ALL;
+extern const Pref* PREF_RPC_ALLOW_ORIGIN_ALL;
 // value: true | false
-extern const std::string PREF_DRY_RUN;
+extern const Pref* PREF_DRY_RUN;
 // value: true | false
-extern const std::string PREF_REUSE_URI;
+extern const Pref* PREF_REUSE_URI;
 // value: string
-extern const std::string PREF_ON_DOWNLOAD_START;
-extern const std::string PREF_ON_DOWNLOAD_PAUSE;
-extern const std::string PREF_ON_DOWNLOAD_STOP;
-extern const std::string PREF_ON_DOWNLOAD_COMPLETE;
-extern const std::string PREF_ON_DOWNLOAD_ERROR;
+extern const Pref* PREF_ON_DOWNLOAD_START;
+extern const Pref* PREF_ON_DOWNLOAD_PAUSE;
+extern const Pref* PREF_ON_DOWNLOAD_STOP;
+extern const Pref* PREF_ON_DOWNLOAD_COMPLETE;
+extern const Pref* PREF_ON_DOWNLOAD_ERROR;
 // value: string
-extern const std::string PREF_INTERFACE;
+extern const Pref* PREF_INTERFACE;
 // value: true | false
-extern const std::string PREF_DISABLE_IPV6;
+extern const Pref* PREF_DISABLE_IPV6;
 // value: true | false
-extern const std::string PREF_HUMAN_READABLE;
+extern const Pref* PREF_HUMAN_READABLE;
 // value: true | false
-extern const std::string PREF_REMOVE_CONTROL_FILE;
+extern const Pref* PREF_REMOVE_CONTROL_FILE;
 // value: true | false
-extern const std::string PREF_ALWAYS_RESUME;
+extern const Pref* PREF_ALWAYS_RESUME;
 // value: 1*digit
-extern const std::string PREF_MAX_RESUME_FAILURE_TRIES;
+extern const Pref* PREF_MAX_RESUME_FAILURE_TRIES;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_SAVE_SESSION;
+extern const Pref* PREF_SAVE_SESSION;
 // value: 1*digit
-extern const std::string PREF_MAX_CONNECTION_PER_SERVER;
+extern const Pref* PREF_MAX_CONNECTION_PER_SERVER;
 // value: 1*digit
-extern const std::string PREF_MIN_SPLIT_SIZE;
+extern const Pref* PREF_MIN_SPLIT_SIZE;
 // value: true | false
-extern const std::string PREF_CONDITIONAL_GET;
+extern const Pref* PREF_CONDITIONAL_GET;
 // value: true | false
-extern const std::string PREF_SELECT_LEAST_USED_HOST;
+extern const Pref* PREF_SELECT_LEAST_USED_HOST;
 // value: true | false
-extern const std::string PREF_ENABLE_ASYNC_DNS6;
+extern const Pref* PREF_ENABLE_ASYNC_DNS6;
 // value: 1*digit
-extern const std::string PREF_MAX_DOWNLOAD_RESULT;
+extern const Pref* PREF_MAX_DOWNLOAD_RESULT;
 // value: 1*digit
-extern const std::string PREF_RETRY_WAIT;
+extern const Pref* PREF_RETRY_WAIT;
 // value: string
-extern const std::string PREF_ASYNC_DNS_SERVER;
+extern const Pref* PREF_ASYNC_DNS_SERVER;
 // value: true | false
-extern const std::string PREF_SHOW_CONSOLE_READOUT;
+extern const Pref* PREF_SHOW_CONSOLE_READOUT;
 // value: default | inorder | geom
-extern const std::string PREF_STREAM_PIECE_SELECTOR;
+extern const Pref* PREF_STREAM_PIECE_SELECTOR;
 // value: true | false
-extern const std::string PREF_TRUNCATE_CONSOLE_READOUT;
+extern const Pref* PREF_TRUNCATE_CONSOLE_READOUT;
 // value: true | false
-extern const std::string PREF_PAUSE;
+extern const Pref* PREF_PAUSE;
 // value: default | full
-extern const std::string PREF_DOWNLOAD_RESULT;
+extern const Pref* PREF_DOWNLOAD_RESULT;
 // value: true | false
-extern const std::string PREF_HASH_CHECK_ONLY;
+extern const Pref* PREF_HASH_CHECK_ONLY;
 
 /**
  * FTP related preferences
  */
-extern const std::string PREF_FTP_USER;
-extern const std::string PREF_FTP_PASSWD;
+extern const Pref* PREF_FTP_USER;
+extern const Pref* PREF_FTP_PASSWD;
 // values: binary | ascii
-extern const std::string PREF_FTP_TYPE;
-extern const std::string V_BINARY;
-extern const std::string V_ASCII;
+extern const Pref* PREF_FTP_TYPE;
 // values: true | false
-extern const std::string PREF_FTP_PASV;
+extern const Pref* PREF_FTP_PASV;
 // values: true | false
-extern const std::string PREF_FTP_REUSE_CONNECTION;
+extern const Pref* PREF_FTP_REUSE_CONNECTION;
 // values: hashType=digest
-extern const std::string PREF_CHECKSUM;
+extern const Pref* PREF_CHECKSUM;
 
 /**
  * HTTP related preferences
  */
-extern const std::string PREF_HTTP_USER;
-extern const std::string PREF_HTTP_PASSWD;
+extern const Pref* PREF_HTTP_USER;
+extern const Pref* PREF_HTTP_PASSWD;
 // values: string
-extern const std::string PREF_USER_AGENT;
+extern const Pref* PREF_USER_AGENT;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_LOAD_COOKIES;
+extern const Pref* PREF_LOAD_COOKIES;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_SAVE_COOKIES;
+extern const Pref* PREF_SAVE_COOKIES;
 // values: true | false
-extern const std::string PREF_ENABLE_HTTP_KEEP_ALIVE;
+extern const Pref* PREF_ENABLE_HTTP_KEEP_ALIVE;
 // values: true | false
-extern const std::string PREF_ENABLE_HTTP_PIPELINING;
+extern const Pref* PREF_ENABLE_HTTP_PIPELINING;
 // value: 1*digit
-extern const std::string PREF_MAX_HTTP_PIPELINING;
+extern const Pref* PREF_MAX_HTTP_PIPELINING;
 // value: string
-extern const std::string PREF_HEADER;
+extern const Pref* PREF_HEADER;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_CERTIFICATE;
+extern const Pref* PREF_CERTIFICATE;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_PRIVATE_KEY;
+extern const Pref* PREF_PRIVATE_KEY;
 // value: string that your file system recognizes as a file name.
-extern const std::string PREF_CA_CERTIFICATE;
+extern const Pref* PREF_CA_CERTIFICATE;
 // value: true | false
-extern const std::string PREF_CHECK_CERTIFICATE;
+extern const Pref* PREF_CHECK_CERTIFICATE;
 // value: true | false
-extern const std::string PREF_USE_HEAD;
+extern const Pref* PREF_USE_HEAD;
 // value: true | false
-extern const std::string PREF_HTTP_AUTH_CHALLENGE;
+extern const Pref* PREF_HTTP_AUTH_CHALLENGE;
 // value: true | false
-extern const std::string PREF_HTTP_NO_CACHE;
+extern const Pref* PREF_HTTP_NO_CACHE;
 // value: true | false
-extern const std::string PREF_HTTP_ACCEPT_GZIP;
+extern const Pref* PREF_HTTP_ACCEPT_GZIP;
 
 /**;
  * Proxy related preferences
  */
-extern const std::string PREF_HTTP_PROXY;
-extern const std::string PREF_HTTPS_PROXY;
-extern const std::string PREF_FTP_PROXY;
-extern const std::string PREF_ALL_PROXY;
+extern const Pref* PREF_HTTP_PROXY;
+extern const Pref* PREF_HTTPS_PROXY;
+extern const Pref* PREF_FTP_PROXY;
+extern const Pref* PREF_ALL_PROXY;
 // values: comma separeted hostname or domain
-extern const std::string PREF_NO_PROXY;
+extern const Pref* PREF_NO_PROXY;
 // values: get | tunnel
-extern const std::string PREF_PROXY_METHOD;
-extern const std::string V_GET;
-extern const std::string V_TUNNEL;
-extern const std::string PREF_HTTP_PROXY_USER;
-extern const std::string PREF_HTTP_PROXY_PASSWD;
-extern const std::string PREF_HTTPS_PROXY_USER;
-extern const std::string PREF_HTTPS_PROXY_PASSWD;
-extern const std::string PREF_FTP_PROXY_USER;
-extern const std::string PREF_FTP_PROXY_PASSWD;
-extern const std::string PREF_ALL_PROXY_USER;
-extern const std::string PREF_ALL_PROXY_PASSWD;
+extern const Pref* PREF_PROXY_METHOD;
+extern const Pref* PREF_HTTP_PROXY_USER;
+extern const Pref* PREF_HTTP_PROXY_PASSWD;
+extern const Pref* PREF_HTTPS_PROXY_USER;
+extern const Pref* PREF_HTTPS_PROXY_PASSWD;
+extern const Pref* PREF_FTP_PROXY_USER;
+extern const Pref* PREF_FTP_PROXY_PASSWD;
+extern const Pref* PREF_ALL_PROXY_USER;
+extern const Pref* PREF_ALL_PROXY_PASSWD;
 
 /**
  * BitTorrent related preferences
  */
 // values: 1*digit
-extern const std::string PREF_PEER_CONNECTION_TIMEOUT;
+extern const Pref* PREF_PEER_CONNECTION_TIMEOUT;
 // values: 1*digit
-extern const std::string PREF_BT_TIMEOUT;
+extern const Pref* PREF_BT_TIMEOUT;
 // values: 1*digit
-extern const std::string PREF_BT_REQUEST_TIMEOUT;
+extern const Pref* PREF_BT_REQUEST_TIMEOUT;
 // values: true | false
-extern const std::string PREF_SHOW_FILES;
+extern const Pref* PREF_SHOW_FILES;
 // values: 1*digit
-extern const std::string PREF_MAX_OVERALL_UPLOAD_LIMIT;
+extern const Pref* PREF_MAX_OVERALL_UPLOAD_LIMIT;
 // values: 1*digit
-extern const std::string PREF_MAX_UPLOAD_LIMIT;
+extern const Pref* PREF_MAX_UPLOAD_LIMIT;
 // values: a string that your file system recognizes as a file name.
-extern const std::string PREF_TORRENT_FILE;
+extern const Pref* PREF_TORRENT_FILE;
 // values: 1*digit
-extern const std::string PREF_LISTEN_PORT;
+extern const Pref* PREF_LISTEN_PORT;
 // values: true | false | mem
-extern const std::string PREF_FOLLOW_TORRENT;
+extern const Pref* PREF_FOLLOW_TORRENT;
 // values: 1*digit *( (,|-) 1*digit)
-extern const std::string PREF_SELECT_FILE;
+extern const Pref* PREF_SELECT_FILE;
 // values: 1*digit
-extern const std::string PREF_SEED_TIME;
+extern const Pref* PREF_SEED_TIME;
 // values: 1*digit ['.' [ 1*digit ] ]
-extern const std::string PREF_SEED_RATIO;
+extern const Pref* PREF_SEED_RATIO;
 // values: 1*digit
-extern const std::string PREF_BT_KEEP_ALIVE_INTERVAL;
+extern const Pref* PREF_BT_KEEP_ALIVE_INTERVAL;
 // values: a string, less than or equals to 20 bytes length
-extern const std::string PREF_PEER_ID_PREFIX;
+extern const Pref* PREF_PEER_ID_PREFIX;
 // values: true | false
-extern const std::string PREF_ENABLE_PEER_EXCHANGE;
+extern const Pref* PREF_ENABLE_PEER_EXCHANGE;
 // values: true | false
-extern const std::string PREF_ENABLE_DHT;
+extern const Pref* PREF_ENABLE_DHT;
 // values: a string
-extern const std::string PREF_DHT_LISTEN_ADDR;
+extern const Pref* PREF_DHT_LISTEN_ADDR;
 // values: 1*digit
-extern const std::string PREF_DHT_LISTEN_PORT;
+extern const Pref* PREF_DHT_LISTEN_PORT;
 // values: a string
-extern const std::string PREF_DHT_ENTRY_POINT_HOST;
+extern const Pref* PREF_DHT_ENTRY_POINT_HOST;
 // values: 1*digit
-extern const std::string PREF_DHT_ENTRY_POINT_PORT;
+extern const Pref* PREF_DHT_ENTRY_POINT_PORT;
 // values: a string (hostname:port)
-extern const std::string PREF_DHT_ENTRY_POINT;
+extern const Pref* PREF_DHT_ENTRY_POINT;
 // values: a string
-extern const std::string PREF_DHT_FILE_PATH;
+extern const Pref* PREF_DHT_FILE_PATH;
 // values: true | false
-extern const std::string PREF_ENABLE_DHT6;
+extern const Pref* PREF_ENABLE_DHT6;
 // values: a string
-extern const std::string PREF_DHT_LISTEN_ADDR6;
+extern const Pref* PREF_DHT_LISTEN_ADDR6;
 // values: a string
-extern const std::string PREF_DHT_ENTRY_POINT_HOST6;
+extern const Pref* PREF_DHT_ENTRY_POINT_HOST6;
 // values: 1*digit
-extern const std::string PREF_DHT_ENTRY_POINT_PORT6;
+extern const Pref* PREF_DHT_ENTRY_POINT_PORT6;
 // values: a string (hostname:port)
-extern const std::string PREF_DHT_ENTRY_POINT6;
+extern const Pref* PREF_DHT_ENTRY_POINT6;
 // values: a string
-extern const std::string PREF_DHT_FILE_PATH6;
+extern const Pref* PREF_DHT_FILE_PATH6;
 // values: plain | arc4
-extern const std::string PREF_BT_MIN_CRYPTO_LEVEL;
-extern const std::string V_PLAIN;
-extern const std::string V_ARC4;
+extern const Pref* PREF_BT_MIN_CRYPTO_LEVEL;
 // values:: true | false
-extern const std::string PREF_BT_REQUIRE_CRYPTO;
+extern const Pref* PREF_BT_REQUIRE_CRYPTO;
 // values: 1*digit
-extern const std::string PREF_BT_REQUEST_PEER_SPEED_LIMIT;
+extern const Pref* PREF_BT_REQUEST_PEER_SPEED_LIMIT;
 // values: 1*digit
-extern const std::string PREF_BT_MAX_OPEN_FILES;
+extern const Pref* PREF_BT_MAX_OPEN_FILES;
 // values: true | false
-extern const std::string PREF_BT_SEED_UNVERIFIED;
+extern const Pref* PREF_BT_SEED_UNVERIFIED;
 // values: true | false
-extern const std::string PREF_BT_HASH_CHECK_SEED;
+extern const Pref* PREF_BT_HASH_CHECK_SEED;
 // values: 1*digit
-extern const std::string PREF_BT_MAX_PEERS;
+extern const Pref* PREF_BT_MAX_PEERS;
 // values: a string (IP address)
-extern const std::string PREF_BT_EXTERNAL_IP;
+extern const Pref* PREF_BT_EXTERNAL_IP;
 // values: 1*digit '=' a string that your file system recognizes as a file name.
-extern const std::string PREF_INDEX_OUT;
+extern const Pref* PREF_INDEX_OUT;
 // values: 1*digit
-extern const std::string PREF_BT_TRACKER_INTERVAL;
+extern const Pref* PREF_BT_TRACKER_INTERVAL;
 // values: 1*digit
-extern const std::string PREF_BT_STOP_TIMEOUT;
+extern const Pref* PREF_BT_STOP_TIMEOUT;
 // values: head[=SIZE]|tail[=SIZE], ...
-extern const std::string PREF_BT_PRIORITIZE_PIECE;
+extern const Pref* PREF_BT_PRIORITIZE_PIECE;
 // values: true | false
-extern const std::string PREF_BT_SAVE_METADATA;
+extern const Pref* PREF_BT_SAVE_METADATA;
 // values: true | false
-extern const std::string PREF_BT_METADATA_ONLY;
+extern const Pref* PREF_BT_METADATA_ONLY;
 // values: true | false
-extern const std::string PREF_BT_ENABLE_LPD;
+extern const Pref* PREF_BT_ENABLE_LPD;
 // values: string
-extern const std::string PREF_BT_LPD_INTERFACE;
+extern const Pref* PREF_BT_LPD_INTERFACE;
 // values: 1*digit
-extern const std::string PREF_BT_TRACKER_TIMEOUT;
+extern const Pref* PREF_BT_TRACKER_TIMEOUT;
 // values: 1*digit
-extern const std::string PREF_BT_TRACKER_CONNECT_TIMEOUT;
+extern const Pref* PREF_BT_TRACKER_CONNECT_TIMEOUT;
 // values: 1*digit
-extern const std::string PREF_DHT_MESSAGE_TIMEOUT;
+extern const Pref* PREF_DHT_MESSAGE_TIMEOUT;
 // values: string
-extern const std::string PREF_ON_BT_DOWNLOAD_COMPLETE;
+extern const Pref* PREF_ON_BT_DOWNLOAD_COMPLETE;
 // values: string
-extern const std::string PREF_BT_TRACKER;
+extern const Pref* PREF_BT_TRACKER;
 // values: string
-extern const std::string PREF_BT_EXCLUDE_TRACKER;
+extern const Pref* PREF_BT_EXCLUDE_TRACKER;
 
 /**
  * Metalink related preferences
  */
 // values: a string that your file system recognizes as a file name.
-extern const std::string PREF_METALINK_FILE;
+extern const Pref* PREF_METALINK_FILE;
 // values: a string
-extern const std::string PREF_METALINK_VERSION;
+extern const Pref* PREF_METALINK_VERSION;
 // values: a string
-extern const std::string PREF_METALINK_LANGUAGE;
+extern const Pref* PREF_METALINK_LANGUAGE;
 // values: a string
-extern const std::string PREF_METALINK_OS;
+extern const Pref* PREF_METALINK_OS;
 // values: a string
-extern const std::string PREF_METALINK_LOCATION;
+extern const Pref* PREF_METALINK_LOCATION;
 // values: 1*digit
-extern const std::string PREF_METALINK_SERVERS;
+extern const Pref* PREF_METALINK_SERVERS;
 // values: true | false | mem
-extern const std::string PREF_FOLLOW_METALINK;
+extern const Pref* PREF_FOLLOW_METALINK;
 // values: http | https | ftp | none
-extern const std::string PREF_METALINK_PREFERRED_PROTOCOL;
-extern const std::string V_HTTP;
-extern const std::string V_HTTPS;
-extern const std::string V_FTP;
+extern const Pref* PREF_METALINK_PREFERRED_PROTOCOL;
 // values: true | false
-extern const std::string PREF_METALINK_ENABLE_UNIQUE_PROTOCOL;
+extern const Pref* PREF_METALINK_ENABLE_UNIQUE_PROTOCOL;
 // values: a string
-extern const std::string PREF_METALINK_BASE_URI;
+extern const Pref* PREF_METALINK_BASE_URI;
 
 } // namespace aria2
 

+ 7 - 5
src/util.cc

@@ -71,6 +71,7 @@
 #include "DownloadContext.h"
 #include "BufferedFile.h"
 #include "SocketCore.h"
+#include "prefs.h"
 
 #ifdef ENABLE_MESSAGE_DIGEST
 # include "MessageDigest.h"
@@ -1698,15 +1699,16 @@ void executeHook
 
 void executeHookByOptName
 (const SharedHandle<RequestGroup>& group, const Option* option,
- const std::string& opt)
+ const Pref* pref)
 {
-  executeHookByOptName(group.get(), option, opt);
+  executeHookByOptName(group.get(), option, pref);
 }
 
 void executeHookByOptName
-(const RequestGroup* group, const Option* option, const std::string& opt)
+(const RequestGroup* group, const Option* option, const Pref* pref)
 {
-  if(!option->blank(opt)) {
+  const std::string& cmd = option->get(pref);
+  if(!cmd.empty()) {
     const SharedHandle<DownloadContext> dctx = group->getDownloadContext();
     std::string firstFilename;
     size_t numFiles = 0;
@@ -1717,7 +1719,7 @@ void executeHookByOptName
       }
       numFiles = dctx->countRequestedFileEntry();
     }
-    executeHook(option->get(opt), group->getGID(), numFiles, firstFilename);
+    executeHook(cmd, group->getGID(), numFiles, firstFilename);
   }
 }
 

+ 3 - 2
src/util.h

@@ -64,6 +64,7 @@ class BinaryStream;
 class FileEntry;
 class RequestGroup;
 class Option;
+class Pref;
 
 #define STRTOLL(X) strtoll(X, reinterpret_cast<char**>(0), 10)
 #define STRTOULL(X) strtoull(X, reinterpret_cast<char**>(0), 10)
@@ -441,11 +442,11 @@ void removeMetalinkContentTypes(RequestGroup* group);
 // No throw
 void executeHookByOptName
 (const SharedHandle<RequestGroup>& group, const Option* option,
- const std::string& opt);
+ const Pref* pref);
 
 // No throw
 void executeHookByOptName
-(const RequestGroup* group, const Option* option, const std::string& opt);
+(const RequestGroup* group, const Option* option, const Pref* pref);
 
 std::string createSafePath(const std::string& dir, const std::string& filename);
 

+ 54 - 54
test/OptionHandlerTest.cc

@@ -63,19 +63,19 @@ void OptionHandlerTest::testNullOptionHandler()
   CPPUNIT_ASSERT(handler.canHandle("foo"));
   Option option;
   handler.parse(option, "bar");
-  CPPUNIT_ASSERT(!option.defined("bar"));
+  CPPUNIT_ASSERT(!option.defined(PREF_TIMEOUT));
 }
 
 void OptionHandlerTest::testBooleanOptionHandler()
 {
-  BooleanOptionHandler handler("foo");
-  CPPUNIT_ASSERT(handler.canHandle("foo"));
-  CPPUNIT_ASSERT(!handler.canHandle("foobar"));
+  BooleanOptionHandler handler(PREF_DAEMON);
+  CPPUNIT_ASSERT(handler.canHandle(PREF_DAEMON->k));
+  CPPUNIT_ASSERT(!handler.canHandle(PREF_DIR->k));
   Option option;
   handler.parse(option, A2_V_TRUE);
-  CPPUNIT_ASSERT_EQUAL(std::string(A2_V_TRUE), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string(A2_V_TRUE), option.get(PREF_DAEMON));
   handler.parse(option, A2_V_FALSE);
-  CPPUNIT_ASSERT_EQUAL(std::string(A2_V_FALSE), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string(A2_V_FALSE), option.get(PREF_DAEMON));
   try {
     handler.parse(option, "hello");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -86,22 +86,22 @@ void OptionHandlerTest::testBooleanOptionHandler()
 
 void OptionHandlerTest::testNumberOptionHandler()
 {
-  NumberOptionHandler handler("foo");
-  CPPUNIT_ASSERT(handler.canHandle("foo"));
-  CPPUNIT_ASSERT(!handler.canHandle("foobar"));
+  NumberOptionHandler handler(PREF_TIMEOUT);
+  CPPUNIT_ASSERT(handler.canHandle(PREF_TIMEOUT->k));
+  CPPUNIT_ASSERT(!handler.canHandle(PREF_DIR->k));
   Option option;
   handler.parse(option, "0");
-  CPPUNIT_ASSERT_EQUAL(std::string("0"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("0"), option.get(PREF_TIMEOUT));
   CPPUNIT_ASSERT_EQUAL(std::string("*-*"),
                        handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testNumberOptionHandler_min()
 {
-  NumberOptionHandler handler("foo", "", "", 1);
+  NumberOptionHandler handler(PREF_TIMEOUT, "", "", 1);
   Option option;
   handler.parse(option, "1");
-  CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "0");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -112,10 +112,10 @@ void OptionHandlerTest::testNumberOptionHandler_min()
 
 void OptionHandlerTest::testNumberOptionHandler_max()
 {
-  NumberOptionHandler handler("foo", "", "", -1, 100);
+  NumberOptionHandler handler(PREF_TIMEOUT, "", "", -1, 100);
   Option option;
   handler.parse(option, "100");
-  CPPUNIT_ASSERT_EQUAL(std::string("100"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("100"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "101");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -126,12 +126,12 @@ void OptionHandlerTest::testNumberOptionHandler_max()
 
 void OptionHandlerTest::testNumberOptionHandler_min_max()
 {
-  NumberOptionHandler handler("foo", "", "", 1, 100);
+  NumberOptionHandler handler(PREF_TIMEOUT, "", "", 1, 100);
   Option option;
   handler.parse(option, "1");
-  CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("1"), option.get(PREF_TIMEOUT));
   handler.parse(option, "100");
-  CPPUNIT_ASSERT_EQUAL(std::string("100"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("100"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "0");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -146,16 +146,16 @@ void OptionHandlerTest::testNumberOptionHandler_min_max()
 
 void OptionHandlerTest::testUnitNumberOptionHandler()
 {
-  UnitNumberOptionHandler handler("foo");
-  CPPUNIT_ASSERT(handler.canHandle("foo"));
+  UnitNumberOptionHandler handler(PREF_TIMEOUT);
+  CPPUNIT_ASSERT(handler.canHandle(PREF_TIMEOUT->k));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
   handler.parse(option, "4294967296");
-  CPPUNIT_ASSERT_EQUAL(std::string("4294967296"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("4294967296"), option.get(PREF_TIMEOUT));
   handler.parse(option, "4096M");
-  CPPUNIT_ASSERT_EQUAL(std::string("4294967296"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("4294967296"), option.get(PREF_TIMEOUT));
   handler.parse(option, "4096K");
-  CPPUNIT_ASSERT_EQUAL(std::string("4194304"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("4194304"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "K");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -171,12 +171,12 @@ void OptionHandlerTest::testUnitNumberOptionHandler()
 
 void OptionHandlerTest::testParameterOptionHandler_1argInit()
 {
-  ParameterOptionHandler handler("foo", "", "", "value1");
-  CPPUNIT_ASSERT(handler.canHandle("foo"));
+  ParameterOptionHandler handler(PREF_TIMEOUT, "", "", "value1");
+  CPPUNIT_ASSERT(handler.canHandle(PREF_TIMEOUT->k));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
   handler.parse(option, "value1");
-  CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "value3");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -187,14 +187,14 @@ void OptionHandlerTest::testParameterOptionHandler_1argInit()
 
 void OptionHandlerTest::testParameterOptionHandler_2argsInit()
 {
-  ParameterOptionHandler handler("foo", "", "", "value1", "value2");
-  CPPUNIT_ASSERT(handler.canHandle("foo"));
+  ParameterOptionHandler handler(PREF_TIMEOUT, "", "", "value1", "value2");
+  CPPUNIT_ASSERT(handler.canHandle(PREF_TIMEOUT->k));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
   handler.parse(option, "value1");
-  CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get(PREF_TIMEOUT));
   handler.parse(option, "value2");
-  CPPUNIT_ASSERT_EQUAL(std::string("value2"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("value2"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "value3");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -209,14 +209,14 @@ void OptionHandlerTest::testParameterOptionHandler_listInit()
   validValues.push_back("value1");
   validValues.push_back("value2");
 
-  ParameterOptionHandler handler("foo", "", "", validValues);
-  CPPUNIT_ASSERT(handler.canHandle("foo"));
+  ParameterOptionHandler handler(PREF_TIMEOUT, "", "", validValues);
+  CPPUNIT_ASSERT(handler.canHandle(PREF_TIMEOUT->k));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
   handler.parse(option, "value1");
-  CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("value1"), option.get(PREF_TIMEOUT));
   handler.parse(option, "value2");
-  CPPUNIT_ASSERT_EQUAL(std::string("value2"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("value2"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "value3");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -227,14 +227,14 @@ void OptionHandlerTest::testParameterOptionHandler_listInit()
 
 void OptionHandlerTest::testDefaultOptionHandler()
 {
-  DefaultOptionHandler handler("foo");
-  CPPUNIT_ASSERT(handler.canHandle("foo"));
+  DefaultOptionHandler handler(PREF_TIMEOUT);
+  CPPUNIT_ASSERT(handler.canHandle(PREF_TIMEOUT->k));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
   handler.parse(option, "bar");
-  CPPUNIT_ASSERT_EQUAL(std::string("bar"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("bar"), option.get(PREF_TIMEOUT));
   handler.parse(option, "");
-  CPPUNIT_ASSERT_EQUAL(std::string(""), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string(""), option.get(PREF_TIMEOUT));
   CPPUNIT_ASSERT_EQUAL(std::string(""), handler.createPossibleValuesString());
 
   handler.addTag("apple");
@@ -248,22 +248,22 @@ void OptionHandlerTest::testDefaultOptionHandler()
 
 void OptionHandlerTest::testFloatNumberOptionHandler()
 {
-  FloatNumberOptionHandler handler("foo");
-  CPPUNIT_ASSERT(handler.canHandle("foo"));
+  FloatNumberOptionHandler handler(PREF_TIMEOUT);
+  CPPUNIT_ASSERT(handler.canHandle(PREF_TIMEOUT->k));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
   handler.parse(option, "1.0");
-  CPPUNIT_ASSERT_EQUAL(std::string("1.0"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("1.0"), option.get(PREF_TIMEOUT));
   CPPUNIT_ASSERT_EQUAL(std::string("*-*"),
                        handler.createPossibleValuesString());
 }
 
 void OptionHandlerTest::testFloatNumberOptionHandler_min()
 {
-  FloatNumberOptionHandler handler("foo", "", "", 0.0);
+  FloatNumberOptionHandler handler(PREF_TIMEOUT, "", "", 0.0);
   Option option;
   handler.parse(option, "0.0");
-  CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "-0.1");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -274,10 +274,10 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min()
 
 void OptionHandlerTest::testFloatNumberOptionHandler_max()
 {
-  FloatNumberOptionHandler handler("foo", "", "", -1, 10.0);
+  FloatNumberOptionHandler handler(PREF_TIMEOUT, "", "", -1, 10.0);
   Option option;
   handler.parse(option, "10.0");
-  CPPUNIT_ASSERT_EQUAL(std::string("10.0"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("10.0"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "10.1");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -288,12 +288,12 @@ void OptionHandlerTest::testFloatNumberOptionHandler_max()
 
 void OptionHandlerTest::testFloatNumberOptionHandler_min_max()
 {
-  FloatNumberOptionHandler handler("foo", "", "", 0.0, 10.0);
+  FloatNumberOptionHandler handler(PREF_TIMEOUT, "", "", 0.0, 10.0);
   Option option;
   handler.parse(option, "0.0");
-  CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("0.0"), option.get(PREF_TIMEOUT));
   handler.parse(option, "10.0");
-  CPPUNIT_ASSERT_EQUAL(std::string("10.0"), option.get("foo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("10.0"), option.get(PREF_TIMEOUT));
   try {
     handler.parse(option, "-0.1");
     CPPUNIT_FAIL("exception must be thrown.");
@@ -309,7 +309,7 @@ void OptionHandlerTest::testFloatNumberOptionHandler_min_max()
 void OptionHandlerTest::testHttpProxyOptionHandler()
 {
   HttpProxyOptionHandler handler(PREF_HTTP_PROXY, "", "");
-  CPPUNIT_ASSERT(handler.canHandle(PREF_HTTP_PROXY));
+  CPPUNIT_ASSERT(handler.canHandle(PREF_HTTP_PROXY->k));
   CPPUNIT_ASSERT(!handler.canHandle("foobar"));
   Option option;
   handler.parse(option, "proxy:65535");
@@ -425,19 +425,19 @@ void OptionHandlerTest::testDeprecatedOptionHandler()
 {
   {
     DeprecatedOptionHandler handler
-      (SharedHandle<OptionHandler>(new DefaultOptionHandler("dep")));
+      (SharedHandle<OptionHandler>(new DefaultOptionHandler(PREF_TIMEOUT)));
     Option option;
     handler.parse(option, "foo");
-    CPPUNIT_ASSERT(!option.defined("dep"));
+    CPPUNIT_ASSERT(!option.defined(PREF_TIMEOUT));
   }
   {
     DeprecatedOptionHandler handler
-      (SharedHandle<OptionHandler>(new DefaultOptionHandler("dep")),
-       SharedHandle<OptionHandler>(new DefaultOptionHandler("rep")));
+      (SharedHandle<OptionHandler>(new DefaultOptionHandler(PREF_TIMEOUT)),
+       SharedHandle<OptionHandler>(new DefaultOptionHandler(PREF_DIR)));
     Option option;
     handler.parse(option, "foo");
-    CPPUNIT_ASSERT(!option.defined("dep"));
-    CPPUNIT_ASSERT_EQUAL(std::string("foo"), option.get("rep"));
+    CPPUNIT_ASSERT(!option.defined(PREF_TIMEOUT));
+    CPPUNIT_ASSERT_EQUAL(std::string("foo"), option.get(PREF_DIR));
   }
 }
 

+ 65 - 65
test/OptionParserTest.cc

@@ -10,6 +10,7 @@
 #include "util.h"
 #include "Option.h"
 #include "array_fun.h"
+#include "prefs.h"
 
 namespace aria2 {
 
@@ -33,30 +34,31 @@ public:
   {
     oparser_.reset(new OptionParser());
 
-    SharedHandle<OptionHandler> alpha
-      (new DefaultOptionHandler("alpha", NO_DESCRIPTION, "ALPHA", "",
+    SharedHandle<OptionHandler> timeout
+      (new DefaultOptionHandler(PREF_TIMEOUT, NO_DESCRIPTION, "ALPHA", "",
                                 OptionHandler::REQ_ARG, 'A'));
-    alpha->addTag("apple");
-    alpha->setEraseAfterParse(true);
-    oparser_->addOptionHandler(alpha);
-
-    SharedHandle<OptionHandler> bravo(new DefaultOptionHandler("bravo"));
-    bravo->addTag("apple");
-    bravo->addTag("orange");
-    bravo->addTag("pineapple");
-    oparser_->addOptionHandler(bravo);
-
-    SharedHandle<DefaultOptionHandler> charlie
-      (new DefaultOptionHandler("charlie", NO_DESCRIPTION, "CHARLIE", "",
+    timeout->addTag("apple");
+    timeout->setEraseAfterParse(true);
+    oparser_->addOptionHandler(timeout);
+
+    SharedHandle<OptionHandler> dir(new DefaultOptionHandler(PREF_DIR));
+    dir->addTag("apple");
+    dir->addTag("orange");
+    dir->addTag("pineapple");
+    oparser_->addOptionHandler(dir);
+
+    SharedHandle<DefaultOptionHandler> daemon
+      (new DefaultOptionHandler(PREF_DAEMON, NO_DESCRIPTION, "CHARLIE", "",
                                 OptionHandler::REQ_ARG, 'C'));
-    charlie->hide();
-    charlie->addTag("pineapple");
-    oparser_->addOptionHandler(charlie);
-
-    SharedHandle<OptionHandler> delta
-      (new UnitNumberOptionHandler("delta", NO_DESCRIPTION, "1M", -1, -1, 'D'));
-    delta->addTag("pineapple");
-    oparser_->addOptionHandler(delta);    
+    daemon->hide();
+    daemon->addTag("pineapple");
+    oparser_->addOptionHandler(daemon);
+
+    SharedHandle<OptionHandler> out
+      (new UnitNumberOptionHandler(PREF_OUT, NO_DESCRIPTION, "1M",
+                                   -1, -1, 'D'));
+    out->addTag("pineapple");
+    oparser_->addOptionHandler(out);    
   }
 
   void tearDown() {}
@@ -79,18 +81,18 @@ void OptionParserTest::testFindAll()
 {
   std::vector<SharedHandle<OptionHandler> > res = oparser_->findAll();
   CPPUNIT_ASSERT_EQUAL((size_t)3, res.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), res[0]->getName());
-  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), res[1]->getName());
-  CPPUNIT_ASSERT_EQUAL(std::string("delta"), res[2]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("timeout"), res[0]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("dir"), res[1]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("out"), res[2]->getName());
 }
 
 void OptionParserTest::testFindByNameSubstring()
 {
   std::vector<SharedHandle<OptionHandler> > res =
-    oparser_->findByNameSubstring("l");
+    oparser_->findByNameSubstring("i");
   CPPUNIT_ASSERT_EQUAL((size_t)2, res.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), res[0]->getName());
-  CPPUNIT_ASSERT_EQUAL(std::string("delta"), res[1]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("timeout"), res[0]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("dir"), res[1]->getName());
 }
 
 void OptionParserTest::testFindByTag()
@@ -98,37 +100,37 @@ void OptionParserTest::testFindByTag()
   std::vector<SharedHandle<OptionHandler> > res =
     oparser_->findByTag("pineapple");
   CPPUNIT_ASSERT_EQUAL((size_t)2, res.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), res[0]->getName());
-  CPPUNIT_ASSERT_EQUAL(std::string("delta"), res[1]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("dir"), res[0]->getName());
+  CPPUNIT_ASSERT_EQUAL(std::string("out"), res[1]->getName());
 }
 
 void OptionParserTest::testFindByName()
 {
-  SharedHandle<OptionHandler> bravo = oparser_->findByName("bravo");
-  CPPUNIT_ASSERT(bravo);
-  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), bravo->getName());
+  SharedHandle<OptionHandler> dir = oparser_->findByName("dir");
+  CPPUNIT_ASSERT(dir);
+  CPPUNIT_ASSERT_EQUAL(std::string("dir"), dir->getName());
 
-  SharedHandle<OptionHandler> charlie = oparser_->findByName("charlie");
-  CPPUNIT_ASSERT(!charlie);
+  SharedHandle<OptionHandler> daemon = oparser_->findByName("daemon");
+  CPPUNIT_ASSERT(!daemon);
 
-  SharedHandle<OptionHandler> alpha2 = oparser_->findByName("alpha2");
-  CPPUNIT_ASSERT(!alpha2);
+  SharedHandle<OptionHandler> timeout2 = oparser_->findByName("timeout2");
+  CPPUNIT_ASSERT(!timeout2);
 }
 
 void OptionParserTest::testFindByShortName()
 {
-  SharedHandle<OptionHandler> alpha = oparser_->findByShortName('A');
-  CPPUNIT_ASSERT(alpha);
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), alpha->getName());
+  SharedHandle<OptionHandler> timeout = oparser_->findByShortName('A');
+  CPPUNIT_ASSERT(timeout);
+  CPPUNIT_ASSERT_EQUAL(std::string("timeout"), timeout->getName());
 
   CPPUNIT_ASSERT(!oparser_->findByShortName('C'));
 }
 
 void OptionParserTest::testFindByID()
 {
-  SharedHandle<OptionHandler> alpha = oparser_->findByID(1);
-  CPPUNIT_ASSERT(alpha);
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), alpha->getName());
+  SharedHandle<OptionHandler> timeout = oparser_->findByID(1);
+  CPPUNIT_ASSERT(timeout);
+  CPPUNIT_ASSERT_EQUAL(std::string("timeout"), timeout->getName());
 
   CPPUNIT_ASSERT(!oparser_->findByID(3));
 }
@@ -137,10 +139,10 @@ void OptionParserTest::testParseDefaultValues()
 {
   Option option;
   oparser_->parseDefaultValues(option);
-  CPPUNIT_ASSERT_EQUAL(std::string("ALPHA"), option.get("alpha"));
-  CPPUNIT_ASSERT_EQUAL(std::string("1048576"), option.get("delta"));
-  CPPUNIT_ASSERT_EQUAL(std::string("CHARLIE"), option.get("charlie"));
-  CPPUNIT_ASSERT(!option.defined("bravo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("ALPHA"), option.get(PREF_TIMEOUT));
+  CPPUNIT_ASSERT_EQUAL(std::string("1048576"), option.get(PREF_OUT));
+  CPPUNIT_ASSERT_EQUAL(std::string("CHARLIE"), option.get(PREF_DAEMON));
+  CPPUNIT_ASSERT(!option.defined(PREF_DIR));
 }
 
 void OptionParserTest::testParseArg()
@@ -149,21 +151,21 @@ void OptionParserTest::testParseArg()
   char prog[7];
   strncpy(prog, "aria2c", sizeof(prog));
 
-  char optionAlpha[3];
-  strncpy(optionAlpha, "-A", sizeof(optionAlpha));
-  char argAlpha[6];
-  strncpy(argAlpha, "ALPHA", sizeof(argAlpha));
-  char optionBravo[8];
-  strncpy(optionBravo, "--bravo", sizeof(optionBravo));
-  char argBravo[6];
-  strncpy(argBravo, "BRAVO", sizeof(argBravo));
+  char optionTimeout[3];
+  strncpy(optionTimeout, "-A", sizeof(optionTimeout));
+  char argTimeout[6];
+  strncpy(argTimeout, "ALPHA", sizeof(argTimeout));
+  char optionDir[8];
+  strncpy(optionDir, "--dir", sizeof(optionDir));
+  char argDir[6];
+  strncpy(argDir, "BRAVO", sizeof(argDir));
 
   char nonopt1[8];
   strncpy(nonopt1, "nonopt1", sizeof(nonopt1));
   char nonopt2[8];
   strncpy(nonopt2, "nonopt2", sizeof(nonopt2));
 
-  char* argv[] = { prog, optionAlpha, argAlpha, optionBravo, argBravo,
+  char* argv[] = { prog, optionTimeout, argTimeout, optionDir, argDir,
                    nonopt1, nonopt2 };
   int argc = A2_ARRAY_LEN(argv);
 
@@ -172,28 +174,26 @@ void OptionParserTest::testParseArg()
 
   oparser_->parseArg(s, nonopts, argc, argv);
 
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha=ALPHA\n"
-                                   "bravo=BRAVO\n"), s.str());
+  CPPUNIT_ASSERT_EQUAL(std::string("timeout=ALPHA\n"
+                                   "dir=BRAVO\n"), s.str());
 
   CPPUNIT_ASSERT_EQUAL((size_t)2, nonopts.size());
   CPPUNIT_ASSERT_EQUAL(std::string("nonopt1"), nonopts[0]);
   CPPUNIT_ASSERT_EQUAL(std::string("nonopt2"), nonopts[1]);
 
-  CPPUNIT_ASSERT_EQUAL(std::string("*****"), std::string(argAlpha));
+  CPPUNIT_ASSERT_EQUAL(std::string("*****"), std::string(argTimeout));
 }
 
 void OptionParserTest::testParse()
 {
   Option option;
-  std::istringstream in("alpha=Hello\n"
+  std::istringstream in("timeout=Hello\n"
                         "UNKNOWN=x\n"
                         "\n"
-                        "bravo=World");
+                        "dir=World");
   oparser_->parse(option, in);
-  CPPUNIT_ASSERT_EQUAL
-    ((std::ptrdiff_t)2, std::distance(option.begin(), option.end()));
-  CPPUNIT_ASSERT_EQUAL(std::string("Hello"), option.get("alpha"));
-  CPPUNIT_ASSERT_EQUAL(std::string("World"), option.get("bravo"));
+  CPPUNIT_ASSERT_EQUAL(std::string("Hello"), option.get(PREF_TIMEOUT));
+  CPPUNIT_ASSERT_EQUAL(std::string("World"), option.get(PREF_DIR));
 }
 
 } // namespace aria2

+ 22 - 18
test/OptionTest.cc

@@ -1,7 +1,11 @@
 #include "Option.h"
+
 #include <string>
+
 #include <cppunit/extensions/HelperMacros.h>
 
+#include "prefs.h"
+
 namespace aria2 {
 
 class OptionTest:public CppUnit::TestFixture {
@@ -31,45 +35,45 @@ CPPUNIT_TEST_SUITE_REGISTRATION( OptionTest );
 
 void OptionTest::testPutAndGet() {
   Option op;
-  op.put("key", "value");
+  op.put(PREF_TIMEOUT, "value");
   
-  CPPUNIT_ASSERT(op.defined("key"));
-  CPPUNIT_ASSERT_EQUAL(std::string("value"), op.get("key"));
+  CPPUNIT_ASSERT(op.defined(PREF_TIMEOUT));
+  CPPUNIT_ASSERT_EQUAL(std::string("value"), op.get(PREF_TIMEOUT));
 }
 
 void OptionTest::testPutAndGetAsInt() {
   Option op;
-  op.put("key", "1000");
+  op.put(PREF_TIMEOUT, "1000");
 
-  CPPUNIT_ASSERT(op.defined("key"));
-  CPPUNIT_ASSERT_EQUAL((int32_t)1000, op.getAsInt("key"));
+  CPPUNIT_ASSERT(op.defined(PREF_TIMEOUT));
+  CPPUNIT_ASSERT_EQUAL((int32_t)1000, op.getAsInt(PREF_TIMEOUT));
 }
 
 void OptionTest::testPutAndGetAsDouble() {
   Option op;
-  op.put("key", "10.0");
+  op.put(PREF_TIMEOUT, "10.0");
   
-  CPPUNIT_ASSERT_EQUAL(10.0, op.getAsDouble("key"));
+  CPPUNIT_ASSERT_EQUAL(10.0, op.getAsDouble(PREF_TIMEOUT));
 }
 
 void OptionTest::testDefined()
 {
   Option op;
-  op.put("k", "v");
-  op.put("k1", "");
-  CPPUNIT_ASSERT(op.defined("k"));
-  CPPUNIT_ASSERT(op.defined("k1"));
-  CPPUNIT_ASSERT(!op.defined("undefined"));
+  op.put(PREF_TIMEOUT, "v");
+  op.put(PREF_DIR, "");
+  CPPUNIT_ASSERT(op.defined(PREF_TIMEOUT));
+  CPPUNIT_ASSERT(op.defined(PREF_DIR));
+  CPPUNIT_ASSERT(!op.defined(PREF_DAEMON));
 }
 
 void OptionTest::testBlank()
 {
   Option op;
-  op.put("k", "v");
-  op.put("k1", "");
-  CPPUNIT_ASSERT(!op.blank("k"));
-  CPPUNIT_ASSERT(op.blank("k1"));
-  CPPUNIT_ASSERT(op.blank("undefined"));
+  op.put(PREF_TIMEOUT, "v");
+  op.put(PREF_DIR, "");
+  CPPUNIT_ASSERT(!op.blank(PREF_TIMEOUT));
+  CPPUNIT_ASSERT(op.blank(PREF_DIR));
+  CPPUNIT_ASSERT(op.blank(PREF_DAEMON));
 }
 
 } // namespace aria2

+ 14 - 14
test/RpcMethodTest.cc

@@ -171,7 +171,7 @@ void RpcMethodTest::testAddUri()
   }
   // with options
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_DIR, "/sink");
+  opt->put(PREF_DIR->k, "/sink");
   req.params->append(opt);
   {
     RpcResponse res = m.execute(req, e_.get());
@@ -209,7 +209,7 @@ void RpcMethodTest::testAddUri_withBadOption()
   urisParam->append("http://localhost");
   req.params->append(urisParam);
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_FILE_ALLOCATION, "badvalue");
+  opt->put(PREF_FILE_ALLOCATION->k, "badvalue");
   req.params->append(opt);
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
@@ -288,7 +288,7 @@ void RpcMethodTest::testAddTorrent()
   std::string dir = A2_TEST_OUT_DIR"/aria2_RpcMethodTest_testAddTorrent";
   File(dir).mkdirs();
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_DIR, dir);
+  opt->put(PREF_DIR->k, dir);
   File(dir+"/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").remove();
   req.params->append(opt);
   {
@@ -379,7 +379,7 @@ void RpcMethodTest::testAddMetalink()
   std::string dir = A2_TEST_OUT_DIR"/aria2_RpcMethodTest_testAddMetalink";
   File(dir).mkdirs();
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_DIR, dir);
+  opt->put(PREF_DIR->k, dir);
   File(dir+"/c908634fbc257fd56f0114912c2772aeeb4064f4.meta4").remove();
   req.params->append(opt);
   {
@@ -446,11 +446,11 @@ void RpcMethodTest::testChangeOption()
   RpcRequest req(ChangeOptionRpcMethod::getMethodName(), List::g());
   req.params->append("1");
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_MAX_DOWNLOAD_LIMIT, "100K");
+  opt->put(PREF_MAX_DOWNLOAD_LIMIT->k, "100K");
 #ifdef ENABLE_BITTORRENT
-  opt->put(PREF_BT_MAX_PEERS, "100");
-  opt->put(PREF_BT_REQUEST_PEER_SPEED_LIMIT, "300K");
-  opt->put(PREF_MAX_UPLOAD_LIMIT, "50K");
+  opt->put(PREF_BT_MAX_PEERS->k, "100");
+  opt->put(PREF_BT_REQUEST_PEER_SPEED_LIMIT->k, "300K");
+  opt->put(PREF_MAX_UPLOAD_LIMIT->k, "50K");
 
   BtObject btObject;
   btObject.btRuntime_ = SharedHandle<BtRuntime>(new BtRuntime());
@@ -489,7 +489,7 @@ void RpcMethodTest::testChangeOption_withBadOption()
   RpcRequest req(ChangeOptionRpcMethod::getMethodName(), List::g());
   req.params->append("1");
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_MAX_DOWNLOAD_LIMIT, "badvalue");
+  opt->put(PREF_MAX_DOWNLOAD_LIMIT->k, "badvalue");
   req.params->append(opt);
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
@@ -504,7 +504,7 @@ void RpcMethodTest::testChangeOption_withNotAllowedOption()
   RpcRequest req(ChangeOptionRpcMethod::getMethodName(), List::g());
   req.params->append("1");
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT, "100K");
+  opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT->k, "100K");
   req.params->append(opt);
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
@@ -524,9 +524,9 @@ void RpcMethodTest::testChangeGlobalOption()
   RpcRequest req
     (ChangeGlobalOptionRpcMethod::getMethodName(), List::g());
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT, "100K");
+  opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT->k, "100K");
 #ifdef ENABLE_BITTORRENT
-  opt->put(PREF_MAX_OVERALL_UPLOAD_LIMIT, "50K");
+  opt->put(PREF_MAX_OVERALL_UPLOAD_LIMIT->k, "50K");
 #endif // ENABLE_BITTORRENT
   req.params->append(opt);
   RpcResponse res = m.execute(req, e_.get());
@@ -552,7 +552,7 @@ void RpcMethodTest::testChangeGlobalOption_withBadOption()
   RpcRequest req
     (ChangeGlobalOptionRpcMethod::getMethodName(), List::g());
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT, "badvalue");
+  opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT->k, "badvalue");
   req.params->append(opt);
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);
@@ -564,7 +564,7 @@ void RpcMethodTest::testChangeGlobalOption_withNotAllowedOption()
   RpcRequest req
     (ChangeGlobalOptionRpcMethod::getMethodName(), List::g());
   SharedHandle<Dict> opt = Dict::g();
-  opt->put(PREF_MAX_DOWNLOAD_LIMIT, "100K");
+  opt->put(PREF_MAX_DOWNLOAD_LIMIT->k, "100K");
   req.params->append(opt);
   RpcResponse res = m.execute(req, e_.get());
   CPPUNIT_ASSERT_EQUAL(1, res.code);

+ 2 - 2
test/UTMetadataPostDownloadHandlerTest.cc

@@ -107,8 +107,8 @@ void UTMetadataPostDownloadHandlerTest::testGetNextRequestGroups()
     newAttrs->announceList;
   CPPUNIT_ASSERT_EQUAL((size_t)1, newAnnounceList.size());
   CPPUNIT_ASSERT_EQUAL(std::string("http://tracker"), newAnnounceList[0][0]);
-  CPPUNIT_ASSERT_EQUAL(option_->get("Hello"),
-                       newRg->getOption()->get("Hello"));
+  CPPUNIT_ASSERT_EQUAL(option_->get(PREF_DIR),
+                       newRg->getOption()->get(PREF_DIR));
   CPPUNIT_ASSERT
     (std::find(requestGroup_->followedBy().begin(),
                requestGroup_->followedBy().end(),