瀏覽代碼

Rewritten parametered URI handling routine.

Tatsuhiro Tsujikawa 14 年之前
父節點
當前提交
30fdb08f40

+ 0 - 82
src/AlphaNumberDecorator.cc

@@ -1,82 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2010 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#include "AlphaNumberDecorator.h"
-
-#include <algorithm>
-
-namespace aria2 {
-
-namespace {
-std::string widen(const std::string& s, size_t width, char zeroChar)
-{
-  std::string t = s;
-  std::string zero(1, zeroChar);
-  while(t.size() < width) {
-    t.insert(0, zero);
-  }
-  return t;
-}
-} // namespace
-
-AlphaNumberDecorator::AlphaNumberDecorator(size_t width, bool uppercase)
-  : width_(width),
-    zero_(uppercase?'A':'a')
-{}
-
-AlphaNumberDecorator::~AlphaNumberDecorator() {}
-
-std::string AlphaNumberDecorator::decorate(unsigned int number)
-{
-  if(number == 0) {
-    return widen(std::string(1, zero_), width_, zero_);
-  }
-
-  int base = 26;
-  char u[14]; // because if unsigned int is 64bit, which is the
-              // biggest integer for the time being and number is
-              // UINT64_MAX, you get "HLHXCZMXSYUMQP"
-  size_t index = 0;
-  do {
-    unsigned int quot = number/base;
-    unsigned int rem = number%base;
-    u[index++] = zero_+rem;
-    number = quot;
-  } while(number);
-  std::reverse(&u[0], &u[index]);
-
-  return widen(std::string(&u[0], &u[index]), width_, zero_);
-}
-
-} // namespace aria2

+ 0 - 60
src/AlphaNumberDecorator.h

@@ -1,60 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_ALPHA_NUMBER_DECORATOR_H
-#define D_ALPHA_NUMBER_DECORATOR_H
-
-#include "NumberDecorator.h"
-
-namespace aria2 {
-
-class AlphaNumberDecorator : public NumberDecorator
-{
-private:
-  size_t width_;
-  char zero_;
-public:
-  AlphaNumberDecorator(size_t width, bool uppercase = false);
-  virtual ~AlphaNumberDecorator();
-
-  // Don't allow copying
-  AlphaNumberDecorator(const AlphaNumberDecorator& c);
-  AlphaNumberDecorator& operator=(const AlphaNumberDecorator& c);
-
-  virtual std::string decorate(unsigned int number);
-};
-
-} // namespace aria2
-
-#endif // D_ALPHA_NUMBER_DECORATOR_H

+ 0 - 56
src/FixedWidthNumberDecorator.h

@@ -1,56 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_FIXED_WIDTH_NUMBER_DECORATOR_H
-#define D_FIXED_WIDTH_NUMBER_DECORATOR_H
-
-#include "NumberDecorator.h"
-
-namespace aria2 {
-
-class FixedWidthNumberDecorator : public NumberDecorator
-{
-private:
-  size_t width_;
-public:
-  FixedWidthNumberDecorator(size_t width);
-
-  virtual ~FixedWidthNumberDecorator();
-
-  virtual std::string decorate(unsigned int number);
-};
-
-} // namespace aria2
-
-#endif // D_FIXED_WIDTH_NUMBER_DECORATOR_H

+ 2 - 11
src/Makefile.am

@@ -96,16 +96,6 @@ SRCS =  Socket.h\
 	HttpHeaderProcessor.cc HttpHeaderProcessor.h\
 	FileEntry.cc FileEntry.h\
 	Platform.cc Platform.h\
-	PStringDatum.h\
-	PStringSegment.cc PStringSegment.h\
-	PStringNumLoop.cc PStringNumLoop.h\
-	PStringSelect.cc PStringSelect.h\
-	PStringVisitor.h\
-	PStringBuildVisitor.cc PStringBuildVisitor.h\
-	ParameterizedStringParser.cc ParameterizedStringParser.h\
-	FixedWidthNumberDecorator.cc FixedWidthNumberDecorator.h\
-	NumberDecorator.h\
-	AlphaNumberDecorator.cc AlphaNumberDecorator.h\
 	TimeBasedCommand.cc TimeBasedCommand.h\
 	AutoSaveCommand.cc AutoSaveCommand.h\
 	PieceStorage.h\
@@ -231,7 +221,8 @@ SRCS =  Socket.h\
 	BufferedFile.cc BufferedFile.h\
 	SegList.h\
 	NullHandle.h\
-	a2iterator.h
+	a2iterator.h\
+	paramed_string.cc paramed_string.h
 
 if MINGW_BUILD
 SRCS += WinConsoleFile.cc WinConsoleFile.h

+ 0 - 53
src/NumberDecorator.h

@@ -1,53 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_NUMBER_DECORATOR_H
-#define D_NUMBER_DECORATOR_H
-
-#include "common.h"
-
-#include <string>
-
-namespace aria2 {
-
-class NumberDecorator {
-public:
-  virtual ~NumberDecorator() {}
-
-  virtual std::string decorate(unsigned int number) = 0;
-};
-
-} // namespace aria2;
-
-#endif // D_NUMBER_DECORATOR_H

+ 0 - 100
src/PStringBuildVisitor.cc

@@ -1,100 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#include "PStringBuildVisitor.h"
-#include "PStringSegment.h"
-#include "PStringNumLoop.h"
-#include "PStringSelect.h"
-#include "NumberDecorator.h"
-#include "a2functional.h"
-
-namespace aria2 {
-
-PStringBuildVisitor::PStringBuildVisitor() {}
-
-PStringBuildVisitor::~PStringBuildVisitor() {}
-
-void PStringBuildVisitor::visit(PStringSegment& segment)
-{
-  std::string uri;
-  if(buildQueue_.empty()) {
-    uri += segment.getValue();
-  } else {
-    uri = buildQueue_.front();
-    uri += segment.getValue();
-  }
-  buildQueue_.push_front(uri);
-  if(!segment.hasNext()) {
-    uris_.push_back(uri);
-  }
-
-  if(segment.getNext()) {
-    segment.getNext()->accept(*this);
-  }
-
-  buildQueue_.pop_front();
-}
-
-void PStringBuildVisitor::visit(PStringNumLoop& s)
-{
-  unsigned int start = s.getStartValue();
-  unsigned int end = s.getEndValue();
-  unsigned int step = s.getStep();
-  for(unsigned int i = start; i <= end; i += step) {
-    PStringSegment(s.getNumberDecorator()->decorate(i),
-                   s.getNext()).accept(*this);
-  }
-}
-
-void PStringBuildVisitor::visit(PStringSelect& s)
-{
-  const std::vector<std::string>& values = s.getValues();
-  for(std::vector<std::string>::const_iterator i = values.begin(),
-        eoi = values.end(); i != eoi; ++i) {
-    PStringSegment(*i, s.getNext()).accept(*this);
-  }
-}
-
-const std::vector<std::string>& PStringBuildVisitor::getURIs() const
-{
-  return uris_;
-}
-
-void PStringBuildVisitor::reset()
-{
-  buildQueue_.clear();
-  uris_.clear();
-}
-
-} // namespace aria2

+ 0 - 74
src/PStringBuildVisitor.h

@@ -1,74 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_P_STRING_BUILD_VISITOR_H
-#define D_P_STRING_BUILD_VISITOR_H
-
-#include "PStringVisitor.h"
-
-#include <deque>
-#include <vector>
-#include <string>
-
-#include "SharedHandle.h"
-
-namespace aria2 {
-
-class PStringBuildVisitor : public PStringVisitor
-{
-private:
-
-  std::deque<std::string> buildQueue_;
-
-  std::vector<std::string> uris_;
-public:
-  PStringBuildVisitor();
-  ~PStringBuildVisitor();
-  
-  virtual void visit(PStringSegment& s);
-
-  virtual void visit(PStringNumLoop& s);
-
-  virtual void visit(PStringSelect& s);
-
-  const std::vector<std::string>& getURIs() const;
-
-  void reset();
-};
-
-typedef SharedHandle<PStringBuildVisitor> PStringBuildVisitorHandle;
-
-} // namespace aria2
-
-#endif // D_P_STRING_BUILD_VISITOR_H

+ 0 - 54
src/PStringDatum.h

@@ -1,54 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_P_STRING_DATUM_H
-#define D_P_STRING_DATUM_H
-
-#include "common.h"
-#include "SharedHandle.h"
-
-namespace aria2 {
-
-class PStringVisitor;
-
-class PStringDatum {
-public:
-  virtual ~PStringDatum() {}
-
-  virtual void accept(PStringVisitor& visitor) = 0;
-};
-
-} // namespace aria2
-
-#endif // D_P_STRING_DATUM_H

+ 0 - 70
src/PStringNumLoop.cc

@@ -1,70 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2010 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#include "PStringNumLoop.h"
-#include "NumberDecorator.h"
-#include "PStringVisitor.h"
-
-namespace aria2 {
-
-PStringNumLoop::PStringNumLoop
-(unsigned int startValue, unsigned int endValue,
- unsigned int step,
- const SharedHandle<NumberDecorator>& nd,
- const SharedHandle<PStringDatum>& next)
-  : startValue_(startValue),
-    endValue_(endValue),
-    step_(step),
-    numberDecorator_(nd),
-    next_(next)
-{}
-
-PStringNumLoop::PStringNumLoop
-(unsigned int startValue, unsigned int endValue,
- unsigned int step,
- const SharedHandle<NumberDecorator>& nd)
-  : startValue_(startValue),
-    endValue_(endValue),
-    step_(step),
-    numberDecorator_(nd)
-{}
-
-PStringNumLoop::~PStringNumLoop() {}
-
-void PStringNumLoop::accept(PStringVisitor& visitor)
-{
-  visitor.visit(*this);
-}
-
-} // namespace aria2

+ 0 - 102
src/PStringNumLoop.h

@@ -1,102 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_P_STRING_NUM_LOOP_H
-#define D_P_STRING_NUM_LOOP_H
-
-#include "PStringDatum.h"
-
-namespace aria2 {
-
-class NumberDecorator;
-class PStringVisitor;
-
-class PStringNumLoop : public PStringDatum
-{
-private:
-  
-  unsigned int startValue_;
-
-  unsigned int endValue_;
-
-  unsigned int step_;
-
-  SharedHandle<NumberDecorator> numberDecorator_;
-
-  SharedHandle<PStringDatum> next_;
-
-public:
-  PStringNumLoop(unsigned int startValue, unsigned int endValue,
-                 unsigned int step,
-                 const SharedHandle<NumberDecorator>& nd,
-                 const SharedHandle<PStringDatum>& next);
-
-  PStringNumLoop(unsigned int startValue, unsigned int endValue,
-                 unsigned int step,
-                 const SharedHandle<NumberDecorator>& nd);
-
-  virtual ~PStringNumLoop();
-
-  virtual void accept(PStringVisitor& visitor);
-
-  const SharedHandle<NumberDecorator>& getNumberDecorator() const
-  {
-    return numberDecorator_;
-  }
-
-  SharedHandle<PStringDatum> getNext() const
-  {
-    return next_;
-  }
-
-  unsigned int getStartValue() const
-  {
-    return startValue_;
-  }
-
-  unsigned int getEndValue() const
-  {
-    return endValue_;
-  }
-
-  unsigned int getStep() const
-  {
-    return step_;
-  }
-
-};
-
-} // namespace aria2
-
-#endif // D_P_STRING_NUM_LOOP_H

+ 0 - 69
src/PStringSegment.cc

@@ -1,69 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#include "PStringSegment.h"
-#include "PStringVisitor.h"
-
-namespace aria2 {
-
-PStringSegment::PStringSegment(const std::string& value,
-                               const SharedHandle<PStringDatum>& next):
-  value_(value), next_(next) {}
-
-PStringSegment::PStringSegment(const std::string& value):
-  value_(value) {}
-
-PStringSegment::~PStringSegment() {}
-
-void PStringSegment::accept(PStringVisitor& visitor)
-{
-  visitor.visit(*this);
-}
-
-const std::string& PStringSegment::getValue() const
-{
-  return value_;
-}
-
-bool PStringSegment::hasNext() const
-{
-  return next_;
-}
-
-SharedHandle<PStringDatum> PStringSegment::getNext() const
-{
-  return next_;
-}
-
-} // namespace aria2

+ 0 - 70
src/PStringSegment.h

@@ -1,70 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_P_STRING_SEGMENT_H
-#define D_P_STRING_SEGMENT_H
-
-#include "PStringDatum.h"
-#include <string>
-
-namespace aria2 {
-
-class PStringSegment : public PStringDatum
-{
-private:
-
-  std::string value_;
-
-  SharedHandle<PStringDatum> next_;
-
-public:
-  PStringSegment(const std::string& value,
-                 const SharedHandle<PStringDatum>& next);
-
-  PStringSegment(const std::string& value);
-
-  virtual ~PStringSegment();
-
-  virtual void accept(PStringVisitor& visitor);
-
-  const std::string& getValue() const;
-
-  bool hasNext() const;
-
-  SharedHandle<PStringDatum> getNext() const;
-};
-
-} // namespace aria2
-
-#endif // D_P_STRING_SEGMENT_H

+ 0 - 68
src/PStringSelect.cc

@@ -1,68 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2010 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#include "PStringSelect.h"
-#include "PStringVisitor.h"
-
-namespace aria2 {
-
-PStringSelect::PStringSelect
-(const std::vector<std::string>& values,
- const SharedHandle<PStringDatum>& next)
-  : values_(values),
-    next_(next)
-{}
-
-PStringSelect::PStringSelect(const std::vector<std::string>& values)
-  : values_(values)
-{}
-
-PStringSelect::~PStringSelect() {}
-
-void PStringSelect::accept(PStringVisitor& visitor)
-{
-  visitor.visit(*this);
-}
-
-const std::vector<std::string>& PStringSelect::getValues() const
-{
-  return values_;
-}
-
-const SharedHandle<PStringDatum>& PStringSelect::getNext() const
-{
-  return next_;
-}
-
-} // namespace aria2

+ 0 - 72
src/PStringSelect.h

@@ -1,72 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_P_STRING_SELECT_H
-#define D_P_STRING_SELECT_H
-
-#include "PStringDatum.h"
-
-#include <vector>
-#include <string>
-
-namespace aria2 {
-
-class PStringVisitor;
-
-class PStringSelect : public PStringDatum
-{
-private:
-  
-  std::vector<std::string> values_;
-
-  SharedHandle<PStringDatum> next_;
-
-public:
-  PStringSelect(const std::vector<std::string>& values,
-                const SharedHandle<PStringDatum>& next);
-
-  PStringSelect(const std::vector<std::string>& values);
-
-  virtual ~PStringSelect();
-
-  virtual void accept(PStringVisitor& visitor);
-
-  const std::vector<std::string>& getValues() const;
-
-  const SharedHandle<PStringDatum>& getNext() const;
-};
-
-} // namespace aria2
-
-#endif // D_P_STRING_SELECT_H

+ 0 - 59
src/PStringVisitor.h

@@ -1,59 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_P_STRING_VISITOR_H
-#define D_P_STRING_VISITOR_H
-
-#include "common.h"
-
-namespace aria2 {
-
-class PStringSegment;
-class PStringNumLoop;
-class PStringSelect;
-
-class PStringVisitor {
-public:
-  virtual ~PStringVisitor() {}
-
-  virtual void visit(PStringSegment& s) = 0;
-
-  virtual void visit(PStringNumLoop& s) = 0;
-
-  virtual void visit(PStringSelect& s) = 0;
-};
-
-} // namespace aria2
-
-#endif // D_P_STRING_VISITOR_H

+ 0 - 158
src/ParameterizedStringParser.cc

@@ -1,158 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#include "ParameterizedStringParser.h"
-
-#include <utility>
-
-#include "DlAbortEx.h"
-#include "util.h"
-#include "PStringSegment.h"
-#include "PStringSelect.h"
-#include "PStringNumLoop.h"
-#include "NumberDecorator.h"
-#include "FixedWidthNumberDecorator.h"
-#include "AlphaNumberDecorator.h"
-
-namespace aria2 {
-
-SharedHandle<PStringDatum>
-ParameterizedStringParser::parse(const std::string& src)
-{
-  int offset = 0;
-  return diggPString(src, offset);
-}
-
-SharedHandle<PStringDatum>
-ParameterizedStringParser::diggPString(const std::string& src, int& offset)
-{
-  if(src.size() == (size_t)offset) {
-    return SharedHandle<PStringDatum>();
-  }
-  switch(src[offset]) {
-  case '[':
-    return createLoop(src, offset);
-  case '{':
-    return createSelect(src, offset);
-  default:
-    return createSegment(src, offset);
-  } 
-}
-
-SharedHandle<PStringDatum>
-ParameterizedStringParser::createSegment(const std::string& src, int& offset)
-{
-  std::string::size_type nextDelimiterIndex = src.find_first_of("[{", offset);
-  if(nextDelimiterIndex == std::string::npos) {
-    nextDelimiterIndex = src.size();
-  }
-  std::string value = src.substr(offset, nextDelimiterIndex-offset);
-  offset = nextDelimiterIndex;
-  SharedHandle<PStringDatum> next = diggPString(src, offset);
-  return SharedHandle<PStringDatum>(new PStringSegment(value, next));
-}
-
-SharedHandle<PStringDatum>
-ParameterizedStringParser::createSelect(const std::string& src, int& offset)
-{
-  ++offset;
-  std::string::size_type rightParenIndex = src.find("}", offset);
-  if(rightParenIndex == std::string::npos) {
-    throw DL_ABORT_EX("Missing '}' in the parameterized string.");
-  }
-  std::vector<std::string> values;
-  util::split(src.begin()+offset, src.begin()+rightParenIndex,
-              std::back_inserter(values), ',', true);
-  if(values.empty()) {
-    throw DL_ABORT_EX("Empty {} is not allowed.");
-  }
-  offset = rightParenIndex+1;
-  SharedHandle<PStringDatum> next = diggPString(src, offset);
-  return SharedHandle<PStringDatum>(new PStringSelect(values, next));
-}
-
-SharedHandle<PStringDatum>
-ParameterizedStringParser::createLoop(const std::string& src, int& offset)
-{
-  ++offset;
-  std::string::size_type rightParenIndex = src.find("]", offset);
-  if(rightParenIndex == std::string::npos) {
-    throw DL_ABORT_EX("Missing ']' in the parameterized string.");
-  }
-  std::string loopStr = src.substr(offset, rightParenIndex-offset);
-  offset = rightParenIndex+1;
-
-  unsigned int step = 1;
-  std::string::size_type colonIndex = loopStr.find(":");
-  if(colonIndex != std::string::npos) {
-    std::string stepStr = loopStr.substr(colonIndex+1);
-    if(util::isNumber(stepStr)) {
-      step = util::parseUInt(loopStr.begin()+colonIndex+1, loopStr.end());
-    } else {
-      throw DL_ABORT_EX("A step count must be a positive number.");
-    }
-    loopStr.erase(colonIndex);
-  }
-  std::pair<Sip, Sip> range;
-  util::divide(range, loopStr.begin(), loopStr.end(), '-');
-  if(range.first.first == range.first.second ||
-     range.second.first == range.second.second) {
-    throw DL_ABORT_EX("Loop range missing.");
-  }
-  SharedHandle<NumberDecorator> nd;
-  unsigned int start;
-  unsigned int end;
-  std::string rstart(range.first.first, range.first.second);
-  std::string rend(range.second.first, range.second.second);
-  if(util::isNumber(rstart) && util::isNumber(rend)) {
-    nd.reset(new FixedWidthNumberDecorator(rstart.size()));
-    start = util::parseUInt(rstart.begin(), rstart.end());
-    end = util::parseUInt(rend.begin(), rend.end());
-  } else if(util::isLowercase(rstart) && util::isLowercase(rend)) {
-    nd.reset(new AlphaNumberDecorator(rstart.size()));
-    start = util::alphaToNum(rstart);
-    end = util::alphaToNum(rend);
-  } else if(util::isUppercase(rstart) && util::isUppercase(rend)) {
-    nd.reset(new AlphaNumberDecorator(rstart.size(), true));
-    start = util::alphaToNum(rstart);
-    end = util::alphaToNum(rend);
-  } else {
-    throw DL_ABORT_EX("Invalid loop range.");
-  }
-
-  SharedHandle<PStringDatum> next(diggPString(src, offset));
-  return SharedHandle<PStringDatum>(new PStringNumLoop(start, end, step, nd, next));
-}
-
-} // namespace aria2

+ 0 - 63
src/ParameterizedStringParser.h

@@ -1,63 +0,0 @@
-/* <!-- copyright */
-/*
- * aria2 - The high speed download utility
- *
- * Copyright (C) 2006 Tatsuhiro Tsujikawa
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-/* copyright --> */
-#ifndef D_PARAMETERIZED_STRING_PARSER_H
-#define D_PARAMETERIZED_STRING_PARSER_H
-
-#include "common.h"
-
-#include <string>
-
-#include "PStringDatum.h"
-
-namespace aria2 {
-
-class ParameterizedStringParser {
-private:
-  SharedHandle<PStringDatum> diggPString(const std::string& src, int& offset);
-
-  SharedHandle<PStringDatum> createSegment(const std::string& src, int& offset);
-
-  SharedHandle<PStringDatum> createLoop(const std::string& src, int& offset);
-
-  SharedHandle<PStringDatum> createSelect(const std::string& src, int& offset);
-
-
-public:
-  SharedHandle<PStringDatum> parse(const std::string& parameterizedUri);
-};
-
-} // namespace aria2
-
-#endif // D_PARAMETERIZED_STRING_PARSER_H

+ 5 - 10
src/download_helper.cc

@@ -34,7 +34,6 @@
 /* copyright --> */
 #include "download_helper.h"
 
-#include <iostream>
 #include <algorithm>
 #include <sstream>
 
@@ -43,8 +42,7 @@
 #include "prefs.h"
 #include "Metalink2RequestGroup.h"
 #include "ProtocolDetector.h"
-#include "ParameterizedStringParser.h"
-#include "PStringBuildVisitor.h"
+#include "paramed_string.h"
 #include "UriListParser.h"
 #include "DownloadContext.h"
 #include "RecoverableException.h"
@@ -75,13 +73,10 @@ namespace {
 void unfoldURI
 (std::vector<std::string>& result, const std::vector<std::string>& args)
 {
-  ParameterizedStringParser p;
-  PStringBuildVisitor v;
-  for(std::vector<std::string>::const_iterator itr = args.begin(),
-        eoi = args.end(); itr != eoi; ++itr) {
-    v.reset();
-    p.parse(*itr)->accept(v);
-    result.insert(result.end(), v.getURIs().begin(), v.getURIs().end()); 
+  for(std::vector<std::string>::const_iterator i = args.begin(),
+        eoi = args.end(); i != eoi; ++i) {
+    paramed_string::expand((*i).begin(), (*i).end(),
+                           std::back_inserter(result));
   }
 }
 } // namespace

+ 18 - 13
src/FixedWidthNumberDecorator.cc → src/paramed_string.cc

@@ -2,7 +2,7 @@
 /*
  * aria2 - The high speed download utility
  *
- * Copyright (C) 2010 Tatsuhiro Tsujikawa
+ * Copyright (C) 2011 Tatsuhiro Tsujikawa
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,24 +32,29 @@
  * files in the program, then also delete it here.
  */
 /* copyright --> */
-#include "FixedWidthNumberDecorator.h"
-#include "util.h"
+#include "paramed_string.h"
 
 namespace aria2 {
 
-FixedWidthNumberDecorator::FixedWidthNumberDecorator(size_t width)
- : width_(width)
-{}
+namespace paramed_string {
 
-FixedWidthNumberDecorator::~FixedWidthNumberDecorator() {}
-
-std::string FixedWidthNumberDecorator::decorate(unsigned int number)
+std::string toBase26(uint32_t n, char zero, size_t width)
 {
-  std::string s = util::uitos(number);
-  while(s.size() < width_) {
-    s.insert(0, "0");
+  std::string res;
+  if(n == 0 && width == 0) {
+    width = 1;
+  }
+  while(n) {
+    res += zero+(n % 26);
+    n /= 26;
   }
-  return s;
+  if(width > res.size()) {
+    res.append(width-res.size(), zero);
+  }
+  std::reverse(res.begin(), res.end());
+  return res;
 }
 
+} // namespace paramed_string
+
 } // namespace aria2

+ 249 - 0
src/paramed_string.h

@@ -0,0 +1,249 @@
+/* <!-- copyright */
+/*
+ * aria2 - The high speed download utility
+ *
+ * Copyright (C) 2011 Tatsuhiro Tsujikawa
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL.  If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so.  If you
+ * do not wish to do so, delete this exception statement from your
+ * version.  If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+/* copyright --> */
+#ifndef D_PARAMED_STRING_H
+#define D_PARAMED_STRING_H
+
+#include "common.h"
+
+#include <string>
+#include <vector>
+#include <algorithm>
+
+#include "util.h"
+#include "DlAbortEx.h"
+#include "fmt.h"
+
+namespace aria2 {
+
+namespace paramed_string {
+
+template<typename InputIterator>
+InputIterator expandChoice
+(std::vector<std::string>& res, InputIterator first, InputIterator last)
+{
+  ++first;
+  InputIterator i = std::find(first, last, '}');
+  if(i == last) {
+    throw DL_ABORT_EX("Missing '}' in the parameterized string.");
+  }
+  std::vector<Scip> choices;
+  util::splitIter(first, i, std::back_inserter(choices), ',', true, false);
+  std::vector<std::string> res2;
+  res2.reserve(res.size()*choices.size());
+  for(std::vector<std::string>::const_iterator i = res.begin(),
+        eoi = res.end(); i != eoi; ++i) {
+    for(std::vector<Scip>::const_iterator j = choices.begin(),
+          eoj = choices.end(); j != eoj; ++j) {
+      res2.push_back(*i);
+      res2.back().append((*j).first, (*j).second);
+    }
+  }
+  res.swap(res2);
+  return i+1;
+}
+
+template<typename InputIterator>
+uint32_t fromBase26(InputIterator first, InputIterator last, char zero)
+{
+  uint64_t res = 0;
+  for(; first != last; ++first) {
+    res *= 26;
+    res += *first-zero;
+    if(res > UINT16_MAX) {
+      throw DL_ABORT_EX("Loop range overflow.");
+    }
+  }
+  return res;
+}
+
+std::string toBase26(uint32_t n, char zero, size_t width);
+
+template<typename InputIterator>
+InputIterator expandLoop
+(std::vector<std::string>& res, InputIterator first, InputIterator last)
+{
+  ++first;
+  InputIterator i = std::find(first, last, ']');
+  if(i == last) {
+    throw DL_ABORT_EX("Missing ']' in the parameterized string.");
+  }
+  InputIterator colon = std::find(first, i, ':');
+  uint32_t step;
+  if(colon == i) {
+    step = 1;
+  } else {
+    if(!util::parseUIntNoThrow(step, colon+1, i)) {
+      throw DL_ABORT_EX("A step count must be a positive number.");
+    }
+    if(step > UINT16_MAX) {
+      throw DL_ABORT_EX("Loop step overflow.");
+    }
+  }
+  InputIterator minus = std::find(first, colon, '-');
+  if(minus == colon) {
+    throw DL_ABORT_EX("Loop range missing.");
+  }
+  if(util::isNumber(first, minus) && util::isNumber(minus+1, colon)) {
+    uint32_t start, end;
+    if(!util::parseUIntNoThrow(start, first, minus) ||
+       !util::parseUIntNoThrow(end, minus+1, colon)) {
+      throw DL_ABORT_EX("Loop range missing.");
+    }
+    if(start > UINT16_MAX || end > UINT16_MAX) {
+      throw DL_ABORT_EX("Loop range overflow.");
+    }
+    if(start <= end) {
+      std::string format;
+      if(minus-first == colon-minus-1) {
+        format = "%0";
+        format += util::uitos(minus-first);
+        format += 'd';
+      } else {
+        format = "%d";
+      }
+      std::vector<std::string> res2;
+      res2.reserve(res.size()*((end+1-start)/step));
+      for(std::vector<std::string>::const_iterator i = res.begin(),
+            eoi = res.end(); i != eoi; ++i) {
+        for(uint32_t j = start; j <= end; j += step) {
+          res2.push_back(*i);
+          res2.back() += fmt(format.c_str(), j);
+        }
+      }
+      res.swap(res2);
+    }
+  } else if((util::isLowercase(first, minus) &&
+             util::isLowercase(minus+1, colon)) ||
+            (util::isUppercase(first, minus) &&
+             util::isUppercase(minus+1, colon))) {
+    char zero = ('a' <= *first && *first <= 'z' ? 'a' : 'A');
+    uint32_t start, end;
+    start = fromBase26(first, minus, zero);
+    end = fromBase26(minus+1, colon, zero);
+    if(start <= end) {
+      size_t width;
+      if(minus-first == colon-minus-1) {
+        width = minus-first;
+      } else {
+        width = 0;
+      }
+      std::vector<std::string> res2;
+      res2.reserve(res.size()*((end+1-start)/step));
+      for(std::vector<std::string>::const_iterator i = res.begin(),
+            eoi = res.end(); i != eoi; ++i) {
+        for(uint32_t j = start; j <= end; j += step) {
+          res2.push_back(*i);
+          res2.back() += toBase26(j, zero, width);
+        }
+      }
+      res.swap(res2);
+    }
+  } else {
+    throw DL_ABORT_EX("Invalid loop range.");
+  }
+  return i+1;
+}
+
+// Expand parameterized string.
+// The available parameters are loop [] and choice {}.
+//
+// Loop: [START-END:STEP]
+//
+// A is arbitrary string. START and END must satisfy one of following
+// condition:
+//
+// * both are decimal digits and START <= END.
+//
+// * both are composed of 'a' to 'z' letter and START <= END
+//   lexicographically.
+//
+// * both are composed of 'A' to 'Z' letter and START <= END
+//   lexicographically.
+//
+// Leading zeros in START and END are kep preserved if the length of
+// START and END in string representation is equal.
+//
+// When loop through START to END, we include both START and END.
+//
+// STEP is dicimal number and it is used as loop step.  STEP can be
+// omitted. If omitted, preceding ':' also must be omitted.
+//
+// START, END and STEP must be less than or equal to 65535 in decimal.
+//
+// Examples:
+// "alpha:[1-2]:bravo" -> ["alpha:1:bravo", "alpha:2:bravo"]
+// "alpha:[05-10:5]" -> ["alpha:05:bravo", "alpha:10:bravo"]
+//
+// Choice: {C1,C2,...,Cn}
+//
+// C1 to Cn are arbitrary string but they cannot contain ','.
+//
+// Examples:
+// "alpha:[foo,bar]:bravo" -> ["alpha:foo:bravo", "alpha:bar:bravo"]
+template<typename InputIterator, typename OutputIterator>
+void expand
+(InputIterator first,
+ InputIterator last,
+ OutputIterator out)
+{
+  std::vector<std::string> res;
+  res.push_back("");
+  while(first != last) {
+    InputIterator i = first;
+    for(; i != last && *i != '{' && *i != '['; ++i);
+    for(std::vector<std::string>::iterator j = res.begin(), eoj = res.end();
+        j != eoj; ++j) {
+      (*j).append(first, i);
+    }
+    first = i;
+    if(first == last) {
+      break;
+    }
+    if(*first == '{') {
+      first = expandChoice(res, first, last);
+    } else if(*first == '[') {
+      first = expandLoop(res, first, last);
+    }
+  }
+  if(res.size() != 1 || !res[0].empty()) {
+    std::copy(res.begin(), res.end(), out);
+  }
+}
+
+} // namespace paramed_string
+
+} // namespace aria2
+
+#endif // D_PARAMED_STRING_H

+ 0 - 40
src/util.cc

@@ -1026,46 +1026,6 @@ void usleep(long microseconds) {
 #endif
 }
 
-bool isNumber(const std::string& what)
-{
-  if(what.empty()) {
-    return false;
-  }
-  for(std::string::const_iterator i = what.begin(), eoi = what.end();
-      i != eoi; ++i) {
-    if(!isDigit(*i)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool isLowercase(const std::string& what)
-{
-  if(what.empty()) {
-    return false;
-  }
-  for(uint32_t i = 0, eoi = what.size(); i < eoi; ++i) {
-    if(!('a' <= what[i] && what[i] <= 'z')) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool isUppercase(const std::string& what)
-{
-  if(what.empty()) {
-    return false;
-  }
-  for(uint32_t i = 0, eoi = what.size(); i < eoi; ++i) {
-    if(!('A' <= what[i] && what[i] <= 'Z')) {
-      return false;
-    }
-  }
-  return true;
-}
-
 unsigned int alphaToNum(const std::string& alphabets)
 {
   if(alphabets.empty()) {

+ 42 - 6
src/util.h

@@ -501,18 +501,54 @@ void toStream
 void sleep(long seconds);
 
 void usleep(long microseconds);
-  
-bool isNumber(const std::string& what);
+
+template<typename InputIterator>
+bool isNumber(InputIterator first, InputIterator last)
+{
+  if(first == last) {
+    return false;
+  }
+  for(; first != last; ++first) {
+    if('0' > *first || *first > '9') {
+      return false;
+    }
+  }
+  return true;
+}
 
 bool isDigit(const char c);
 
 bool isHexDigit(const char c);
 
 bool isHexDigit(const std::string& s);
-  
-bool isLowercase(const std::string& what);
-  
-bool isUppercase(const std::string& what);
+
+template<typename InputIterator>
+bool isLowercase(InputIterator first, InputIterator last)
+{
+  if(first == last) {
+    return false;
+  }
+  for(; first != last; ++first) {
+    if('a' > *first || *first > 'z') {
+      return false;
+    }
+  }
+  return true;
+}
+
+template<typename InputIterator>
+bool isUppercase(InputIterator first, InputIterator last)
+{
+  if(first == last) {
+    return false;
+  }
+  for(; first != last; ++first) {
+    if('A' > *first || *first > 'Z') {
+      return false;
+    }
+  }
+  return true;
+}
 
 /**
  * Converts alphabets to unsigned int, assuming alphabets as a base 26

+ 0 - 42
test/AlphaNumberDecoratorTest.cc

@@ -1,42 +0,0 @@
-#include "AlphaNumberDecorator.h"
-#include <iostream>
-#include <cppunit/extensions/HelperMacros.h>
-
-namespace aria2 {
-
-class AlphaNumberDecoratorTest:public CppUnit::TestFixture {
-
-  CPPUNIT_TEST_SUITE(AlphaNumberDecoratorTest);
-  CPPUNIT_TEST(testDecorate);
-  CPPUNIT_TEST(testDecorate_uppercase);
-  CPPUNIT_TEST_SUITE_END();
-private:
-
-public:
-  void setUp() {
-  }
-
-  void testDecorate();
-  void testDecorate_uppercase();
-};
-
-
-CPPUNIT_TEST_SUITE_REGISTRATION( AlphaNumberDecoratorTest );
-
-void AlphaNumberDecoratorTest::testDecorate()
-{
-  CPPUNIT_ASSERT_EQUAL(std::string("a"), AlphaNumberDecorator(1).decorate(0));
-  CPPUNIT_ASSERT_EQUAL(std::string("z"), AlphaNumberDecorator(1).decorate(25));
-  CPPUNIT_ASSERT_EQUAL(std::string("zz"), AlphaNumberDecorator(1).decorate(675)); // 25*26+25
-  CPPUNIT_ASSERT_EQUAL(std::string("aab"), AlphaNumberDecorator(3).decorate(1));
-}
-
-void AlphaNumberDecoratorTest::testDecorate_uppercase()
-{
-  CPPUNIT_ASSERT_EQUAL(std::string("A"), AlphaNumberDecorator(1, true).decorate(0));
-  CPPUNIT_ASSERT_EQUAL(std::string("Z"), AlphaNumberDecorator(1, true).decorate(25));
-  CPPUNIT_ASSERT_EQUAL(std::string("ZZ"), AlphaNumberDecorator(1, true).decorate(675)); // 25*26+25
-  CPPUNIT_ASSERT_EQUAL(std::string("AAB"), AlphaNumberDecorator(3, true).decorate(1));
-}
-
-} // namespace aria2

+ 2 - 4
test/Makefile.am

@@ -15,10 +15,7 @@ aria2c_SOURCES = AllTest.cc\
 	SingleFileAllocationIteratorTest.cc\
 	DefaultBtProgressInfoFileTest.cc\
 	RequestGroupTest.cc\
-	PStringBuildVisitorTest.cc\
-	ParameterizedStringParserTest.cc\
 	UtilTest.cc\
-	AlphaNumberDecoratorTest.cc\
 	UriListParserTest.cc\
 	HttpHeaderProcessorTest.cc\
 	RequestTest.cc\
@@ -81,7 +78,8 @@ aria2c_SOURCES = AllTest.cc\
 	RpcMethodTest.cc\
 	BufferedFileTest.cc\
 	GeomStreamPieceSelectorTest.cc\
-	SegListTest.cc
+	SegListTest.cc\
+	ParamedStringTest.cc
 
 if ENABLE_XML_RPC
 aria2c_SOURCES += XmlRpcRequestParserControllerTest.cc\

+ 0 - 101
test/PStringBuildVisitorTest.cc

@@ -1,101 +0,0 @@
-#include "PStringBuildVisitor.h"
-
-#include <cppunit/extensions/HelperMacros.h>
-
-#include "PStringSegment.h"
-#include "PStringNumLoop.h"
-#include "PStringSelect.h"
-#include "FixedWidthNumberDecorator.h"
-
-namespace aria2 {
-
-class PStringBuildVisitorTest:public CppUnit::TestFixture {
-
-  CPPUNIT_TEST_SUITE(PStringBuildVisitorTest);
-  CPPUNIT_TEST(testVisit_select);
-  CPPUNIT_TEST(testVisit_numLoop);
-  CPPUNIT_TEST(testVisit_select_numLoop);
-  CPPUNIT_TEST_SUITE_END();
-private:
-
-public:
-  void setUp() {
-  }
-
-  void testVisit_select();
-  void testVisit_numLoop();
-  void testVisit_select_numLoop();
-};
-
-
-CPPUNIT_TEST_SUITE_REGISTRATION( PStringBuildVisitorTest );
-
-void PStringBuildVisitorTest::testVisit_select()
-{
-  SharedHandle<PStringSegment> segment1(new PStringSegment("/tango"));
-
-  const char* select1data[] = { "alpha", "bravo", "charlie" };
-  
-  SharedHandle<PStringSelect> select1
-    (new PStringSelect
-     (std::vector<std::string>(&select1data[0], &select1data[3]), segment1));
-
-  PStringBuildVisitor v;
-
-  select1->accept(v);
-
-  CPPUNIT_ASSERT_EQUAL((size_t)3, v.getURIs().size());
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha/tango"), v.getURIs()[0]);
-  CPPUNIT_ASSERT_EQUAL(std::string("bravo/tango"), v.getURIs()[1]);
-  CPPUNIT_ASSERT_EQUAL(std::string("charlie/tango"), v.getURIs()[2]);
-}
-
-void PStringBuildVisitorTest::testVisit_numLoop()
-{
-  SharedHandle<PStringSegment> segment1(new PStringSegment("/tango"));
-
-  SharedHandle<NumberDecorator> decorator(new FixedWidthNumberDecorator(2));
-  SharedHandle<PStringNumLoop> loop1
-    (new PStringNumLoop(0, 5, 2, decorator, segment1));
-
-  PStringBuildVisitor v;
-
-  loop1->accept(v);
-
-  CPPUNIT_ASSERT_EQUAL((size_t)3, v.getURIs().size());
-  CPPUNIT_ASSERT_EQUAL(std::string("00/tango"), v.getURIs()[0]);
-  CPPUNIT_ASSERT_EQUAL(std::string("02/tango"), v.getURIs()[1]);
-  CPPUNIT_ASSERT_EQUAL(std::string("04/tango"), v.getURIs()[2]);
-}
-
-void PStringBuildVisitorTest::testVisit_select_numLoop()
-{
-  SharedHandle<PStringSegment> segment1(new PStringSegment("/tango"));
-
-  const char* select1data[] = { "alpha", "bravo", "charlie" };
-  
-  SharedHandle<PStringSelect> select1
-    (new PStringSelect
-     (std::vector<std::string>(&select1data[0], &select1data[3]), segment1));
-
-  SharedHandle<NumberDecorator> decorator(new FixedWidthNumberDecorator(2));
-  SharedHandle<PStringNumLoop> loop1
-    (new PStringNumLoop(0, 5, 2, decorator, select1));
-
-  PStringBuildVisitor v;
-
-  loop1->accept(v);
-
-  CPPUNIT_ASSERT_EQUAL((size_t)9, v.getURIs().size());
-  CPPUNIT_ASSERT_EQUAL(std::string("00alpha/tango"), v.getURIs()[0]);
-  CPPUNIT_ASSERT_EQUAL(std::string("00bravo/tango"), v.getURIs()[1]);
-  CPPUNIT_ASSERT_EQUAL(std::string("00charlie/tango"), v.getURIs()[2]);
-  CPPUNIT_ASSERT_EQUAL(std::string("02alpha/tango"), v.getURIs()[3]);
-  CPPUNIT_ASSERT_EQUAL(std::string("02bravo/tango"), v.getURIs()[4]);
-  CPPUNIT_ASSERT_EQUAL(std::string("02charlie/tango"), v.getURIs()[5]);
-  CPPUNIT_ASSERT_EQUAL(std::string("04alpha/tango"), v.getURIs()[6]);
-  CPPUNIT_ASSERT_EQUAL(std::string("04bravo/tango"), v.getURIs()[7]);
-  CPPUNIT_ASSERT_EQUAL(std::string("04charlie/tango"), v.getURIs()[8]);
-}
-
-} // namespace aria2

+ 200 - 0
test/ParamedStringTest.cc

@@ -0,0 +1,200 @@
+#include "paramed_string.h"
+
+#include <iostream>
+
+#include <cppunit/extensions/HelperMacros.h>
+
+namespace aria2 {
+
+class ParamedStringTest:public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE(ParamedStringTest);
+  CPPUNIT_TEST(testExpand);
+  CPPUNIT_TEST_SUITE_END();
+public:
+  void testExpand();
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( ParamedStringTest );
+
+void ParamedStringTest::testExpand()
+{
+  std::vector<std::string> res;
+
+  std::string s = "alpha:{01,02,03}:bravo:{001,002}";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)6, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:01:bravo:001"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:01:bravo:002"), res[1]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:02:bravo:001"), res[2]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:02:bravo:002"), res[3]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:03:bravo:001"), res[4]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:03:bravo:002"), res[5]);
+  res.clear();
+
+  s = "alpha:[1-3]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)3, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:1:bravo"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:2:bravo"), res[1]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:3:bravo"), res[2]);
+  res.clear();
+
+  s = "alpha:[5-12:3]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)3, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:5:bravo"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:8:bravo"), res[1]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:11:bravo"), res[2]);
+  res.clear();
+
+  s = "alpha:[05-12:3]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)3, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:05:bravo"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:08:bravo"), res[1]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:11:bravo"), res[2]);
+  res.clear();
+
+  s = "alpha:[99-00]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)1, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha::bravo"), res[0]);
+  res.clear();
+
+  s = "alpha:[65535-65535:65535]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)1, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:65535:bravo"), res[0]);
+  res.clear();
+
+  // Invalid loop range
+  s = "alpha:[1-]:bravo";
+  try {
+    paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(const Exception& e) {
+  }
+
+  // Invalid loop range
+  s = "alpha:[-1]:bravo";
+  try {
+    paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(const Exception& e) {
+  }
+
+  // Invalid loop range
+  s = "alpha:[1-3a]:bravo";
+  try {
+    paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(const Exception& e) {
+  }
+
+  // Missing loop step
+  s = "alpha:[1-2:]:bravo";
+  try {
+    paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(const Exception& e) {
+  }
+
+  // Range overflow
+  s = "alpha:[0-65536]:bravo";
+  try {
+    paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(const Exception& e) {
+  }
+
+  // Step overflow
+  s = "alpha:[0-1:65536]:bravo";
+  try {
+    paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(const Exception& e) {
+  }
+
+  s = "alpha:[c-e]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)3, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:c:bravo"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:d:bravo"), res[1]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:e:bravo"), res[2]);
+  res.clear();
+
+  s = "alpha:[C-E]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)3, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:C:bravo"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:D:bravo"), res[1]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:E:bravo"), res[2]);
+  res.clear();
+
+  s = "alpha:[v-z:2]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)3, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:v:bravo"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:x:bravo"), res[1]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:z:bravo"), res[2]);
+  res.clear();
+
+  s = "alpha:[aa-ba]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)27, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:aa:bravo"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:az:bravo"), res[25]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:ba:bravo"), res[26]);
+  res.clear();
+
+  s = "alpha:[a-ba]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)27, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:a:bravo"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:z:bravo"), res[25]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:ba:bravo"), res[26]);
+  res.clear();
+
+  s = "alpha:[z-a]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)1, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha::bravo"), res[0]);
+  res.clear();
+
+  s = "alpha:[dsyo-dsyp]:bravo";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)2, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:dsyo:bravo"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("alpha:dsyp:bravo"), res[1]);
+  res.clear();
+
+  // Range overflow
+  s = "alpha:[dsyo-dsyq]:bravo";
+  try {
+    paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(const Exception& e) {
+  }
+
+  // Invalid loop range
+  s = "alpha:[a-Z]:bravo";
+  try {
+    paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+    CPPUNIT_FAIL("Exception must be thrown.");
+  } catch(const Exception& e) {
+  }
+
+  // Combination of {} and []
+  s = "http://{jp,us}.mirror/image_cd[000-001].iso";
+  paramed_string::expand(s.begin(), s.end(), std::back_inserter(res));
+  CPPUNIT_ASSERT_EQUAL((size_t)4, res.size());
+  CPPUNIT_ASSERT_EQUAL(std::string("http://jp.mirror/image_cd000.iso"), res[0]);
+  CPPUNIT_ASSERT_EQUAL(std::string("http://jp.mirror/image_cd001.iso"), res[1]);
+  CPPUNIT_ASSERT_EQUAL(std::string("http://us.mirror/image_cd000.iso"), res[2]);
+  CPPUNIT_ASSERT_EQUAL(std::string("http://us.mirror/image_cd001.iso"), res[3]);
+  res.clear();
+}
+
+} // namespace aria2

+ 0 - 240
test/ParameterizedStringParserTest.cc

@@ -1,240 +0,0 @@
-#include "ParameterizedStringParser.h"
-
-#include <iostream>
-
-#include <cppunit/extensions/HelperMacros.h>
-
-#include "PStringSelect.h"
-#include "PStringSegment.h"
-#include "PStringNumLoop.h"
-#include "DlAbortEx.h"
-
-namespace aria2 {
-
-class ParameterizedStringParserTest:public CppUnit::TestFixture {
-
-  CPPUNIT_TEST_SUITE(ParameterizedStringParserTest);
-  CPPUNIT_TEST(testParse_select);
-  CPPUNIT_TEST(testParse_select_empty);
-  CPPUNIT_TEST(testParse_select_missingParen);
-  CPPUNIT_TEST(testParse_segment);
-  CPPUNIT_TEST(testParse_segment_select);
-  CPPUNIT_TEST(testParse_loop);
-  CPPUNIT_TEST(testParse_loop_empty);
-  CPPUNIT_TEST(testParse_loop_missingParen);
-  CPPUNIT_TEST(testParse_loop_missingStep);
-  CPPUNIT_TEST(testParse_loop_missingRange);
-  CPPUNIT_TEST(testParse_alphaLoop);
-  CPPUNIT_TEST(testParse_loop_mixedChar);
-  CPPUNIT_TEST(testParse_loop_mixedCase);
-  CPPUNIT_TEST(testParse_segment_loop);
-  CPPUNIT_TEST_SUITE_END();
-private:
-
-public:
-  void setUp() {
-  }
-
-  void testParse_select();
-  void testParse_select_empty();
-  void testParse_select_missingParen();
-  void testParse_segment();
-  void testParse_segment_select();
-  void testParse_loop();
-  void testParse_loop_empty();
-  void testParse_loop_missingParen();
-  void testParse_loop_missingStep();
-  void testParse_loop_missingRange();
-  void testParse_alphaLoop();
-  void testParse_loop_mixedChar();
-  void testParse_loop_mixedCase();
-  void testParse_segment_loop();
-};
-
-
-CPPUNIT_TEST_SUITE_REGISTRATION( ParameterizedStringParserTest );
-
-void ParameterizedStringParserTest::testParse_select()
-{
-  SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("{alpha, bravo, charlie}");
-  SharedHandle<PStringSelect> select(dynamic_pointer_cast<PStringSelect>(ls));
-  CPPUNIT_ASSERT(select);
-
-  std::vector<std::string> values = select->getValues();
-  CPPUNIT_ASSERT_EQUAL((size_t)3, values.size());
-
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), values[0]);
-  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), values[1]);
-  CPPUNIT_ASSERT_EQUAL(std::string("charlie"), values[2]);
-}
-
-void ParameterizedStringParserTest::testParse_select_empty()
-{
-  try {
-    SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("{}");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(DlAbortEx& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  } catch(...) {
-    CPPUNIT_FAIL("unexpected exception thrown.");
-  }
-}
-
-void ParameterizedStringParserTest::testParse_select_missingParen()
-{
-  try {
-    SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("{alpha");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(DlAbortEx& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  } catch(...) {
-    CPPUNIT_FAIL("unexpected exception was thrown.");
-  }
-}
-
-void ParameterizedStringParserTest::testParse_segment()
-{
-  SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("hello world");
-  SharedHandle<PStringSegment> segment(dynamic_pointer_cast<PStringSegment>(ls));
-  CPPUNIT_ASSERT(segment);
-  CPPUNIT_ASSERT_EQUAL(std::string("hello world"), segment->getValue());
-}
-
-void ParameterizedStringParserTest::testParse_segment_select()
-{
-  SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("file:///{alpha, bravo, charlie}/tango");
-
-  SharedHandle<PStringSegment> segment1
-    (dynamic_pointer_cast<PStringSegment>(ls));
-  CPPUNIT_ASSERT(segment1);
-  CPPUNIT_ASSERT_EQUAL(std::string("file:///"), segment1->getValue());
-
-  SharedHandle<PStringSelect> select1
-    (dynamic_pointer_cast<PStringSelect>(segment1->getNext()));
-  CPPUNIT_ASSERT(select1);
-  std::vector<std::string> selectValues = select1->getValues();
-  CPPUNIT_ASSERT_EQUAL((size_t)3, selectValues.size());
-  CPPUNIT_ASSERT_EQUAL(std::string("alpha"), selectValues[0]);
-  CPPUNIT_ASSERT_EQUAL(std::string("bravo"), selectValues[1]);
-  CPPUNIT_ASSERT_EQUAL(std::string("charlie"), selectValues[2]);
-  
-  SharedHandle<PStringSegment> segment2
-    (dynamic_pointer_cast<PStringSegment>(select1->getNext()));
-  CPPUNIT_ASSERT(segment2);
-  CPPUNIT_ASSERT_EQUAL(std::string("/tango"), segment2->getValue());
-}
-
-void ParameterizedStringParserTest::testParse_loop()
-{
-  SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("[1-10:2]");
-
-  SharedHandle<PStringNumLoop> loop1(dynamic_pointer_cast<PStringNumLoop>(ls));
-  CPPUNIT_ASSERT(loop1);
-  CPPUNIT_ASSERT_EQUAL(1U, loop1->getStartValue());
-  CPPUNIT_ASSERT_EQUAL(10U, loop1->getEndValue());
-  CPPUNIT_ASSERT_EQUAL(2U, loop1->getStep());
-}
-
-void ParameterizedStringParserTest::testParse_loop_empty()
-{
-  try {
-    SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("[]");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(DlAbortEx& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  } catch(...) {
-    CPPUNIT_FAIL("unexpected exception was thrown.");
-  }
-}
-
-void ParameterizedStringParserTest::testParse_loop_missingParen()
-{
-  try {
-    SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("[");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(DlAbortEx& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  } catch(...) {
-    CPPUNIT_FAIL("unexpected exception was thrown.");
-  }
-}
-
-void ParameterizedStringParserTest::testParse_loop_missingStep()
-{
-  try {
-    SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("[1-10:]");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(DlAbortEx& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  } catch(...) {
-    CPPUNIT_FAIL("unexpected exception was thrown.");
-  }
-}
-
-void ParameterizedStringParserTest::testParse_loop_missingRange()
-{
-  try {
-    SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("[1-]");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(DlAbortEx& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  } catch(...) {
-    CPPUNIT_FAIL("unexpected exception was thrown.");
-  }
-}
-
-void ParameterizedStringParserTest::testParse_alphaLoop()
-{
-  SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("[a-z:2]");
-
-  SharedHandle<PStringNumLoop> loop1(dynamic_pointer_cast<PStringNumLoop>(ls));
-  CPPUNIT_ASSERT(loop1);
-  CPPUNIT_ASSERT_EQUAL(0U, loop1->getStartValue());
-  CPPUNIT_ASSERT_EQUAL(25U, loop1->getEndValue());
-  CPPUNIT_ASSERT_EQUAL(2U, loop1->getStep());
-}
-
-void ParameterizedStringParserTest::testParse_loop_mixedChar()
-{
-  try {
-    ParameterizedStringParser().parse("[1-z:2]");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(DlAbortEx& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  } catch(...) {
-    CPPUNIT_FAIL("DlAbortEx must be thrown.");
-  }
-}
-
-void ParameterizedStringParserTest::testParse_loop_mixedCase()
-{
-  try {
-    ParameterizedStringParser().parse("[a-Z:2]");
-    CPPUNIT_FAIL("exception must be thrown.");
-  } catch(DlAbortEx& e) {
-    std::cerr << e.stackTrace() << std::endl;
-  } catch(...) {
-    CPPUNIT_FAIL("DlAbortEx must be thrown.");
-  }
-}
-
-void ParameterizedStringParserTest::testParse_segment_loop()
-{
-  SharedHandle<PStringDatum> ls = ParameterizedStringParser().parse("http://server[1-3]/file");
-
-  SharedHandle<PStringSegment> segment1(dynamic_pointer_cast<PStringSegment>(ls));
-  CPPUNIT_ASSERT(segment1);
-  CPPUNIT_ASSERT_EQUAL(std::string("http://server"), segment1->getValue());
-
-  SharedHandle<PStringNumLoop> loop1(dynamic_pointer_cast<PStringNumLoop>(segment1->getNext()));
-  CPPUNIT_ASSERT(loop1);
-  CPPUNIT_ASSERT_EQUAL(1U, loop1->getStartValue());
-  CPPUNIT_ASSERT_EQUAL(3U, loop1->getEndValue());
-  CPPUNIT_ASSERT_EQUAL(1U, loop1->getStep());
-
-  SharedHandle<PStringSegment> segment2(dynamic_pointer_cast<PStringSegment>(loop1->getNext()));
-  CPPUNIT_ASSERT(segment2);
-  CPPUNIT_ASSERT_EQUAL(std::string("/file"), segment2->getValue());
-}
-
-} // namespace aria2

+ 30 - 15
test/UtilTest.cc

@@ -1070,29 +1070,44 @@ void UtilTest::testToStream()
 
 void UtilTest::testIsNumber()
 {
-  CPPUNIT_ASSERT_EQUAL(true, util::isNumber("000"));
-  CPPUNIT_ASSERT_EQUAL(false, util::isNumber("a"));
-  CPPUNIT_ASSERT_EQUAL(false, util::isNumber("0a"));
-  CPPUNIT_ASSERT_EQUAL(false, util::isNumber(""));
-  CPPUNIT_ASSERT_EQUAL(false, util::isNumber(" "));
+  std::string s = "000";
+  CPPUNIT_ASSERT_EQUAL(true, util::isNumber(s.begin(),s.end()));
+  s = "a";
+  CPPUNIT_ASSERT_EQUAL(false, util::isNumber(s.begin(), s.end()));
+  s = "0a";
+  CPPUNIT_ASSERT_EQUAL(false, util::isNumber(s.begin(), s.end()));
+  s = "";
+  CPPUNIT_ASSERT_EQUAL(false, util::isNumber(s.begin(), s.end()));
+  s = " ";
+  CPPUNIT_ASSERT_EQUAL(false, util::isNumber(s.begin(), s.end()));
 }
 
 void UtilTest::testIsLowercase()
 {
-  CPPUNIT_ASSERT_EQUAL(true, util::isLowercase("alpha"));
-  CPPUNIT_ASSERT_EQUAL(false, util::isLowercase("Alpha"));
-  CPPUNIT_ASSERT_EQUAL(false, util::isLowercase("1alpha"));
-  CPPUNIT_ASSERT_EQUAL(false, util::isLowercase(""));
-  CPPUNIT_ASSERT_EQUAL(false, util::isLowercase(" "));
+  std::string s = "alpha";
+  CPPUNIT_ASSERT_EQUAL(true, util::isLowercase(s.begin(), s.end()));
+  s = "Alpha";
+  CPPUNIT_ASSERT_EQUAL(false, util::isLowercase(s.begin(), s.end()));
+  s = "1alpha";
+  CPPUNIT_ASSERT_EQUAL(false, util::isLowercase(s.begin(), s.end()));
+  s = "";
+  CPPUNIT_ASSERT_EQUAL(false, util::isLowercase(s.begin(), s.end()));
+  s = " ";
+  CPPUNIT_ASSERT_EQUAL(false, util::isLowercase(s.begin(), s.end()));
 }
 
 void UtilTest::testIsUppercase()
 {
-  CPPUNIT_ASSERT_EQUAL(true, util::isUppercase("ALPHA"));
-  CPPUNIT_ASSERT_EQUAL(false, util::isUppercase("Alpha"));
-  CPPUNIT_ASSERT_EQUAL(false, util::isUppercase("1ALPHA"));
-  CPPUNIT_ASSERT_EQUAL(false, util::isUppercase(""));
-  CPPUNIT_ASSERT_EQUAL(false, util::isUppercase(" "));
+  std::string s = "ALPHA";
+  CPPUNIT_ASSERT_EQUAL(true, util::isUppercase(s.begin(), s.end()));
+  s = "Alpha";
+  CPPUNIT_ASSERT_EQUAL(false, util::isUppercase(s.begin(), s.end()));
+  s = "1ALPHA";
+  CPPUNIT_ASSERT_EQUAL(false, util::isUppercase(s.begin(), s.end()));
+  s = "";
+  CPPUNIT_ASSERT_EQUAL(false, util::isUppercase(s.begin(), s.end()));
+  s = " ";
+  CPPUNIT_ASSERT_EQUAL(false, util::isUppercase(s.begin(), s.end()));
 }
 
 void UtilTest::testAlphaToNum()