コード例 #1
0
zstring zstring::replace(zstring const& src, zstring const& dst) const {
    zstring result(m_encoding);
    if (length() < src.length()) {
        return zstring(*this);
    }
    if (src.length() == 0) {
        return zstring(*this);
    }
    bool found = false;
    for (unsigned i = 0; i < length(); ++i) {
        bool eq = !found && i + src.length() <= length();
        for (unsigned j = 0; eq && j < src.length(); ++j) {
            eq = m_buffer[i+j] == src[j];
        }
        if (eq) {
            result.m_buffer.append(dst.m_buffer);
            found = true;
            i += src.length() - 1;
        }
        else {
            result.m_buffer.push_back(m_buffer[i]);
        }
    }
    return result;
}
コード例 #2
0
ファイル: seq_decl_plugin.cpp プロジェクト: delcypher/z3
bool operator<(const zstring& lhs, const zstring& rhs) {
    // This has the same semantics as strcmp()
    unsigned len = lhs.length();
    if (rhs.length() < len) {
        len = rhs.length();
    }
    for (unsigned i = 0; i < len; ++i) {
        unsigned Li = lhs[i];
        unsigned Ri = rhs[i];
        if (Li < Ri) {
            return true;
        } else if (Li > Ri) {
            return false;
        } else {
            continue;
        }
    }
    // at this point, all compared characters are equal,
    // so decide based on the relative lengths
    if (lhs.length() < rhs.length()) {
        return true;
    } else {
        return false;
    }
}
コード例 #3
0
bool zstring::suffixof(zstring const& other) const {
    if (length() > other.length()) return false;
    bool suffix = true;
    for (unsigned i = 0; suffix && i < length(); ++i) {
        suffix = m_buffer[length()-i-1] == other[other.length()-i-1];
    }
    return suffix;
}
コード例 #4
0
bool zstring::contains(zstring const& other) const {
    if (other.length() > length()) return false;
    unsigned last = length() - other.length();
    bool cont = false;
    for (unsigned i = 0; !cont && i <= last; ++i) {
        cont = true;
        for (unsigned j = 0; cont && j < other.length(); ++j) {
            cont = other[j] == m_buffer[j+i];
        }
    }
    return cont;
}
コード例 #5
0
void PrinterVisitor::
beginVisitFlworLetVariable( bool materialize, zstring const &varName,
                            vector<PlanIter_t> const &varRefs ) {
  thePrinter.startBeginVisit( "LetVariable", ++theId );

  thePrinter.addAttribute( "name", varName.str() );
  thePrinter.addAttribute( "materialize", materialize ? "true" : "false");

  ostringstream str;
  vector<PlanIter_t>::size_type const numRefs = varRefs.size();
  for ( vector<PlanIter_t>::size_type i = 0; i < numRefs; ++i ) {
#ifndef NDEBUG
    str << varRefs[i]->getId();
#else
    str << varRefs[i].getp();
#endif
    if ( i < numRefs - 1 )
      str << ' ';
  }

  if ( !Properties::instance().getNoTreeIDs() )
    thePrinter.addAttribute( "referenced-by", str.str() );

  thePrinter.endBeginVisit( theId );
}
コード例 #6
0
void PrinterVisitor::
beginVisitFlworForVariable( zstring const &varName,
                            vector<PlanIter_t> const &varRefs,
                            vector<PlanIter_t> const &posRefs ) {
  thePrinter.startBeginVisit( "ForVariable", ++theId );
  thePrinter.addAttribute( "name", varName.str() );

  ostringstream ref_oss;
  vector<PlanIter_t>::size_type const numRefs = varRefs.size();
  for ( vector<PlanIter_t>::size_type i = 0; i < numRefs; ++i ) {
#ifndef NDEBUG
    ref_oss << varRefs[i]->getId();
#else
    ref_oss << varRefs[i].getp();
#endif
    if ( i < numRefs - 1 )
      ref_oss << ' ';
  }

  if ( !Properties::instance().getNoTreeIDs() )
    thePrinter.addAttribute( "referenced-by", ref_oss.str() );

  if ( !posRefs.empty() ) {
    string const ref_s( var_refs( posRefs ) );
    if ( !Properties::instance().getNoTreeIDs() )
      thePrinter.addAttribute( "pos-referenced-by", ref_s );
  }

  thePrinter.endBeginVisit( theId );
}
コード例 #7
0
ファイル: zstring.cpp プロジェクト: Leoyuseu/CodeHub
zstring::zstring(const zstring &rzw)
	{
	const char *rstr;rstr=rzw.getString();
	mem_data.mem_length=(unsigned int)strlen(rstr);    	
	mem_data.mem_string=(char *)malloc(mem_data.mem_length+1);
	unsigned int i;for(i=0;i<=mem_data.mem_length;i++)mem_data.mem_string[i]='\0';	
	strcpy(mem_data.mem_string,rstr);	
    
	mem_data.mem_erchar=rzw.mem_data.mem_erchar;	    	
	if(rzw.Buffer!=0)
		{
		unsigned int len=(unsigned int)strlen(rzw.Buffer);		
		Buffer=(char *)malloc(len+1);
	    unsigned int i;for(i=0;i<=len;i++)Buffer[i]='\0';
		strcpy(this->Buffer,rzw.Buffer);
		}
	else {this->Buffer=0;}

	mem_data.mem_encryptkey=0;
	mem_data.mem_copy=0;
	mem_data.mem_ifile=0;
	mem_data.mem_ofile=0;
	   #ifndef  _zhuwei_ztools_NOT_USE_MFC_CLASS 
	mem_data.mem_ReadWatchfile=0;
	mem_data.mem_WriteWatchfile=0;
		mem_data.mem_runfilelock=0;
#endif
	}
コード例 #8
0
int zstring::indexof(zstring const& other, int offset) const {
    SASSERT(offset >= 0);
    if (static_cast<unsigned>(offset) == length()) return -1;
    if (other.length() + offset > length()) return -1;
    unsigned last = length() - other.length();
    for (unsigned i = static_cast<unsigned>(offset); i <= last; ++i) {
        bool prefix = true;
        for (unsigned j = 0; prefix && j < other.length(); ++j) {
            prefix = m_buffer[i + j] == other[j];
        }
        if (prefix) {
            return static_cast<int>(i);
        }
    }
    return -1;
}
コード例 #9
0
ファイル: compiler_api.cpp プロジェクト: alyst/zorba
PlanIter_t XQueryCompiler::compile(
    std::istream& aXQuery,
    const zstring& aFileName,
    ulong& nextDynamicVarId)
{
  audit::Event* ae = theCompilerCB->theRootSctx->get_audit_event();
  zorba::audit::ScopedRecord sar(ae);

  const char* lFileName = aFileName.c_str();

  audit::ScopedAuditor<const char*>
  filenameAudit(sar, zorba::audit::XQUERY_COMPILATION_FILENAME, lFileName);

  parsenode_t lAST;

  {
    time::Timer lTimer;

    audit::DurationAuditor
    durationAudit(sar, audit::XQUERY_COMPILATION_PARSE_DURATION, lTimer);

    lAST = parse(aXQuery, aFileName);

    if (theCompilerCB->theConfig.lib_module &&
        dynamic_cast<LibraryModule*>(lAST.getp()) != NULL)
    {
      lAST = createMainModule(lAST, aXQuery, aFileName);
    }
  }

  return compile(lAST, true, nextDynamicVarId, sar);
}
コード例 #10
0
bool zstring::prefixof(zstring const& other) const {
    if (length() > other.length()) return false;
    bool prefix = true;
    for (unsigned i = 0; prefix && i < length(); ++i) {
        prefix = m_buffer[i] == other[i];
    }
    return prefix;
}
コード例 #11
0
void PrinterVisitor::
beginVisitWinCondVariable( zstring const &varName,
                           vector<PlanIter_t> const &varRefs ) {
  thePrinter.startBeginVisit( "WinCondVariable", theId );
  thePrinter.addAttribute( "name", varName.str() );

  if ( !Properties::instance().getNoTreeIDs() )
    printVarRefs( "referenced-by", varRefs );

  thePrinter.endBeginVisit( theId );
}
コード例 #12
0
ファイル: compiler_api.cpp プロジェクト: alyst/zorba
void XQueryCompiler::xqdoc(
    std::istream&         aXQuery,
    const zstring&        aFileName,
    store::Item_t&        aResult,
    const store::Item_t&  aDateTime,
    uint32_t              aOptions)
{
  parsenode_t lAST = parse(aXQuery, aFileName);

  print_parsetree_xqdoc(aResult, lAST.getp(),
                        aFileName.c_str(), aDateTime, aOptions);
}
コード例 #13
0
void PrinterVisitor::
beginVisitFlworLetVariable( bool materialize, zstring const &varName,
                            vector<PlanIter_t> const &varRefs ) {
  thePrinter.startBeginVisit( "LetVariable", ++theId );

  thePrinter.addAttribute( "name", varName.str() );
  thePrinter.addBoolAttribute( "materialize", materialize ? true : false);

  if ( !Properties::instance().getNoTreeIDs() )
    printVarRefs( "referenced-by", varRefs );

  thePrinter.endBeginVisit( theId );
}
コード例 #14
0
ファイル: module_version.cpp プロジェクト: alyst/zorba
/**
 * Utility function: Given a string aStr and position aPos, populate
 * aInt with the integer at that position in the string. aPos will be
 * updated to next character.
 * @return true if an integer found, false if not.
 */
static bool
getInteger(zstring const& aStr, size_t& aPos, int& aInt)
{
  char lChar;
  size_t lLen = aStr.length();
  size_t const lOrigPos = aPos;

  aInt = 0;
  while (aPos < lLen && isdigit(lChar = aStr[aPos])) {
    aInt = aInt * 10 + (lChar - '0');
    aPos++;
  }
  return (aPos != lOrigPos);
}
コード例 #15
0
ファイル: seq_decl_plugin.cpp プロジェクト: delcypher/z3
bool zstring::operator==(const zstring& other) const {
    // two strings are equal iff they have the same length and characters
    if (length() != other.length()) {
        return false;
    }
    for (unsigned i = 0; i < length(); ++i) {
        unsigned Xi = m_buffer[i];
        unsigned Yi = other[i];
        if (Xi != Yi) {
            return false;
        }
    }

    return true;
}
コード例 #16
0
void PrinterVisitor::
beginVisitFlworForVariable( zstring const &varName,
                            vector<PlanIter_t> const &varRefs,
                            vector<PlanIter_t> const &posRefs ) {
  thePrinter.startBeginVisit( "ForVariable", ++theId );
  thePrinter.addAttribute( "name", varName.str() );

  if ( !Properties::instance().getNoTreeIDs() )
  {
    printVarRefs( "referenced-by", varRefs );
    if (!posRefs.empty())
      printVarRefs( "pos-referenced-by", posRefs );
  }

  thePrinter.endBeginVisit( theId );
}
コード例 #17
0
  void
  URIMapperWrapper::mapURI
  (const zstring& aUri,
    internal::EntityData const* aEntityData,
    static_context const& aSctx,
    std::vector<zstring>& oUris)
  {
    std::unique_ptr<const EntityDataWrapper> lDataWrap
        (EntityDataWrapper::create(aEntityData));
    if (lDataWrap.get() == NULL) {
      return;
    }

    std::vector<zorba::String> lUserUris;
    // QQQ should public API have a StaticContext on it?
    theUserMapper.mapURI(zorba::String(aUri.c_str()), lDataWrap.get(),
                         lUserUris);
    std::vector<zorba::String>::iterator iter;
    for (iter = lUserUris.begin(); iter != lUserUris.end(); iter++) {
      oUris.push_back(Unmarshaller::getInternalString(*iter));
    }
  }
コード例 #18
0
ファイル: module_version.cpp プロジェクト: alyst/zorba
bool
ModuleVersion::initValues(zstring const& aVersionDef)
{
  // Parse fragment for legal version specification. If any illegal
  // characters found, no versioning to be attempted.
  int lMajor, lMinor, lPatch = 0, lMajorB = -1;
  bool lExact = false;
  size_t lPos = 0;
  size_t lLen = aVersionDef.length();
  if (!getInteger(aVersionDef, lPos, lMajor)) {
    return false;
  }
  if (lPos >= lLen) {
    return false;
  }
  if (aVersionDef[lPos++] != '.') {
    return false;
  }
  if (!getInteger(aVersionDef, lPos, lMinor)) {
    return false;
  }
  if (lPos < lLen && aVersionDef[lPos] == '.') {
    // There's (potentially) a patch version specified as well
    lPos ++;
    if (lPos >= lLen) {
      return false;
    }
    if (!getInteger(aVersionDef, lPos, lPatch)) {
      return false;
    }
  }
  if (lPos < lLen) {
    // Found legal major.minor, but there's more to parse - could be "!"
    // or "-major.0"
    char lChar = aVersionDef[lPos++];
    if (lChar == '!' && lPos == lLen) {
      lExact = true;
    }
    else if (lChar == '-') {
      if (!getInteger(aVersionDef, lPos, lMajorB)) {
        return false;
      }
      if (lPos >= lLen || aVersionDef[lPos++] != '.') {
        return false;
      }
      if (lPos >= lLen || aVersionDef[lPos++] != '0') {
        return false;
      }
    }
    else {
      return false;
    }
  }

  // Verify there's no more to read.
  if (lPos != lLen) {
    return false;
  }

  // Ok, we successfully parsed a version definition; set all our variables.
  theMinMajor = lMajor;
  theMinMinor = lMinor;
  theMinPatch = lPatch;
  theMaxMajor = lMajorB == -1 ? lMajor : lMajorB;
  theIsExact = lExact;
  theValidVersion = true;
  return true;
}
コード例 #19
0
ファイル: zstring.cpp プロジェクト: Leoyuseu/CodeHub
double operator+( double rdb, zstring &rzw){double ls=rdb+atof(rzw.getString());return ls;}
コード例 #20
0
ファイル: zstring.cpp プロジェクト: Leoyuseu/CodeHub
int operator+(int rdb, zstring &rzw){int ls=rdb+atoi(rzw.getString());return ls;}
コード例 #21
0
ファイル: zstring.cpp プロジェクト: Leoyuseu/CodeHub
long operator+(long rdb, zstring &rzw){long ls=rdb+atol(rzw.getString());return ls;}
コード例 #22
0
ファイル: zstring.cpp プロジェクト: Leoyuseu/CodeHub
//          5>
const bool zstring::operator==(const zstring &rzw)   const
	{        if(strcmp(this->mem_data.mem_string,rzw.getString())==0)return true;else return false;	}
コード例 #23
0
ファイル: zstring.cpp プロジェクト: Leoyuseu/CodeHub
double  zstring::instr(unsigned int start,const zstring &rzw)	{return instr(start,rzw.getString());}
コード例 #24
0
ファイル: format_integer.cpp プロジェクト: alyst/zorba
static void parse_primary( zstring const &picture_str,
                           zstring::const_iterator *i, picture *pic,
                           QueryLoc const &loc ) {
  if ( picture_str.empty() ) {
    //
    // XQuery 3.0 F&O 4.6.1: The primary format token is always present and
    // must not be zero-length.
    //
empty_format:
    throw XQUERY_EXCEPTION(
      err::FODF1310,
      ERROR_PARAMS( ZED( FODF1310_EmptyFormat ) ),
      ERROR_LOC( loc )
    );
  }

  //
  // Because of:
  //
  //    Ibid: If the string contains one or more semicolons then everything
  //    that precedes the last semicolon is taken as the primary format token
  //    and everything that follows is taken as the format modifier.
  //
  // we have to count the number of semicolons in order to know when we've
  // reached the last one.
  //
  int semicolon_counter = 0;
  FOR_EACH( zstring, c, picture_str )
    if ( *c == ';' )
      ++semicolon_counter;
  int const semicolons = semicolon_counter;

  if ( semicolons == 1 && picture_str[0] == ';' ) {
    //
    // This also means that the primary format token is zero-length.
    //
    goto empty_format;
  }

  unicode::code_point cp;
  utf8_string<zstring const> const u_picture_str( picture_str );
  utf8_string<zstring const>::const_iterator u;

  //
  // Determine whether the primary format token is a decimal-digit-pattern:
  //
  //    Ibid: If the primary format token contains at least one Unicode digit
  //    then it is taken as a decimal digit pattern.
  //
  // and whether all digits are from the same digit family:
  //
  //    Ibid: All mandatory-digit-signs within the format token must be from
  //    the same digit family, where a digit family is a sequence of ten
  //    consecutive characters in Unicode category Nd, having digit values 0
  //    through 9.
  //
  bool is_decimal_digit_pattern = false;
  unicode::code_point zero[] = { '0', '0' };
  semicolon_counter = semicolons;
  for ( u = u_picture_str.begin(); u != u_picture_str.end(); ++u ) {
    cp = *u;
    if ( cp == ';' && !--semicolon_counter )
      break;
    if ( unicode::is_Nd( cp, &zero[ is_decimal_digit_pattern ] ) ) {
      if ( is_decimal_digit_pattern && zero[1] != zero[0] ) {
        throw XQUERY_EXCEPTION(
          err::FODF1310,
          ERROR_PARAMS(
            picture_str,
            ZED( FODF1310_DigitNotSameFamily_34 ),
            unicode::printable_cp( cp ),
            unicode::printable_cp( zero[0] )
          ),
          ERROR_LOC( loc )
        );
      }
      is_decimal_digit_pattern = true;
      ++pic->primary.mandatory_digits;
    }
  }

  u = u_picture_str.begin();
  cp = *u;

  if ( is_decimal_digit_pattern ) {
    if ( cp != '#' && unicode::is_grouping_separator( cp ) ) {
      //
      // Ibid 4.6.1: A grouping-separator-sign must not appear at the start ...
      // of the decimal-digit-pattern ....
      //
      throw XQUERY_EXCEPTION(
        err::FODF1310,
        ERROR_PARAMS(
          picture_str,
          ZED( FODF1310_NoGroupSepAtStart_3 ),
          unicode::printable_cp( cp )
        ),
        ERROR_LOC( loc )
      );
    }

    pic->primary.zero = zero[0];

    utf8_string<zstring> u_pic_format( pic->primary.format );
    u_pic_format += cp;

    bool got_grouping_separator = false;
    bool got_mandatory_digit = cp != '#';
    utf8::size_type grouping_interval = 0;
    bool grouping_interval_possible = true;
    unicode::code_point grouping_separator_cp = 0;
    int grouping_separators = 0;
    utf8::size_type pos = 1, prev_grouping_pos = utf8::npos;

    semicolon_counter = semicolons;
    while ( ++u != u_picture_str.end() ) {
      cp = *u;
      if ( cp == '#' ) {
        if ( got_mandatory_digit ) {
          //
          // Ibid: There may be zero or more optional-digit-signs, and (if
          // present) these must precede all mandatory-digit-signs.
          //
          throw XQUERY_EXCEPTION(
            err::FODF1310,
            ERROR_PARAMS(
              picture_str,
              ZED( FODF1310_NoOptDigitAfterMandatory )
            ),
            ERROR_LOC( loc )
          );
        }
        got_grouping_separator = false;
      } else if ( unicode::is_Nd( cp ) ) {
        got_mandatory_digit = true;
        got_grouping_separator = false;
      } else if ( unicode::is_grouping_separator( cp ) ) {
        if ( cp == ';' && !--semicolon_counter ) {
          //
          // Ibid: If the string contains one or more semicolons then
          // everything that precedes the last semicolon is taken as the
          // primary format token and everything that follows is taken as the
          // format modifier.
          //
          break;
        }
        if ( got_grouping_separator ) {
          //
          // Ibid: A grouping-separator-sign must not appear ... adjacent to
          // another grouping-separator-sign.
          //
          throw XQUERY_EXCEPTION(
            err::FODF1310,
            ERROR_PARAMS(
              picture_str,
              ZED( FODF1310_NoAdjacentGroupSep_3 ),
              unicode::printable_cp( cp )
            ),
            ERROR_LOC( loc )
          );
        }
        got_grouping_separator = true;
        ++grouping_separators;

        if ( grouping_interval_possible ) {
          //
          // Ibid: If grouping-separator-signs appear at regular intervals
          // within the format token, that is if the same grouping separator
          // appears at positions forming a sequence N, 2N, 3N, ... for some
          // integer value N (including the case where there is only one number
          // in the list), then the sequence is extrapolated to the left, so
          // grouping separators will be used in the formatted number at every
          // multiple of N. For example, if the format token is 0'000 then the
          // number one million will be formatted as 1'000'000, while the
          // number fifteen will be formatted as 0'015.
          //
          if ( !grouping_separator_cp )
            grouping_separator_cp = cp;
          else if ( cp != grouping_separator_cp )
            grouping_interval_possible = false;
          else if ( !grouping_interval )
            grouping_interval = pos - prev_grouping_pos;
          else if ( pos - prev_grouping_pos != grouping_interval )
            grouping_interval_possible = false;
          prev_grouping_pos = pos + 1;
        }
      } else {
        throw XQUERY_EXCEPTION(
          err::FODF1310,
          ERROR_PARAMS(
            picture_str,
            ZED( FODF1310_BadCharacter_3 ),
            unicode::printable_cp( cp )
          ),
          ERROR_LOC( loc )
        );
      }
      u_pic_format += cp;
      ++pos;
    } // while

    if ( got_grouping_separator ) {
      //
      // Ibid: A grouping-separator-sign must not appear at the ... end of the
      // decimal-digit-pattern ....
      //
      throw XQUERY_EXCEPTION(
        err::FODF1310,
        ERROR_PARAMS(
          picture_str,
          ZED( FODF1310_NoGroupSepAtEnd_3 ),
          unicode::printable_cp( cp )
        ),
        ERROR_LOC( loc )
      );
    }

    if ( grouping_interval_possible ) {
      if ( !grouping_interval ) {
        if ( grouping_separator_cp ) {
          //
          // There's only a single grouping separator, e.g., "1,000".
          //
          grouping_interval = pos - prev_grouping_pos;
        }
      } else if ( pos - prev_grouping_pos != grouping_interval ) {
        //
        // There are multiple grouping separators, but they're not equally
        // spaced from the last digit, e.g., "1,000,00".  (This is most likely
        // a mistake on the part of the user.)
        //
        grouping_interval = 0;
      }
      pic->primary.grouping_interval = grouping_interval;
    } else
      pic->primary.mandatory_grouping_seps = grouping_separators;

  } else {

    using namespace unicode;
    ++u;
    switch ( cp ) {
      case 'A':
        pic->primary.type = picture::ALPHA;
        break;
      case 'a':
        pic->primary.type = picture::alpha;
        break;
      case 'I':
        pic->primary.type = picture::ROMAN;
        break;
      case 'i':
        pic->primary.type = picture::roman;
        break;
      case 'W':
        if ( u != u_picture_str.end() && *u == 'w' )
          pic->primary.type = picture::Words, ++u;
        else
          pic->primary.type = picture::WORDS;
        break;
      case 'w':
        pic->primary.type = picture::words;
        break;
      case CIRCLED_DIGIT_ONE:
      case CIRCLED_IDEOGRAPH_ONE:
      case DIGIT_ONE_FULL_STOP:
      case DINGBAT_CIRCLED_SANS_SERIF_DIGIT_ONE:
      case DINGBAT_NEGATIVE_CIRCLED_DIGIT_ONE:
      case DINGBAT_NEGATIVE_CIRCLED_SANS_SERIF_DIGIT_ONE:
      case DOUBLE_CIRCLED_DIGIT_ONE:
      case PARENTHESIZED_DIGIT_ONE:
      case PARENTHESIZED_IDEOGRAPH_ONE:
      case SUBSCRIPT_ONE:
      case SUPERSCRIPT_ONE:
        pic->primary.type = picture::one;
        pic->primary.one = cp;
        break;
      default:
        //
        // Ibid: If an implementation does not support a numbering sequence
        // represented by the given token, it must use a format token of 1.
        //
        pic->primary.type = picture::arabic;
        pic->primary.format = "1";

        //
        // Ibid: If the string contains one or more semicolons then
        // everything that precedes the last semicolon is taken as the
        // primary format token and everything that follows is taken as the
        // format modifier.
        //
        // Hence, we have to skip everything up to (but not including) the last
        // semicolon (if any).
        //
        semicolon_counter = semicolons;
        for ( ; u != u_picture_str.end(); ++u )
          if ( *u == ';' && !--semicolon_counter )
            break;
    } // switch
  }
  *i = u.base();
}
コード例 #25
0
ファイル: format_integer.cpp プロジェクト: alyst/zorba
static void format_integer( xs_integer const &xs_n, picture const &pic,
                            zstring *dest ) {
  picture default_pic;

  switch ( pic.primary.type ) {
    case picture::one:
      //
      // XQuery F&O 3.0: 4.6.1: For all format tokens other than [ones that
      // consists of decimal digits], there may be implementation-defined lower
      // and upper bounds on the range of numbers that can be formatted using
      // this format token; indeed, for some numbering sequences there may be
      // intrinsic limits. For example, the format token &#x2460; (circled
      // digit one) has a range of 1 to 20 imposed by the Unicode character
      // repertoire.
      //
      try {
        xs_long const n = to_xs_long( xs_n );
        int min, max;
        if ( get_one_range( pic.primary.one, &min, &max ) &&
            n >= min && n <= max ) {
          utf8_string<zstring> u_dest( *dest );
          u_dest = (unicode::code_point)(pic.primary.one + n - 1);
          break;
        }
        //
        // Ibid: Numbers that fall outside this range must be formatted using
        // the format token 1.
        //
        format_integer( xs_n, default_pic, dest );
      }
      catch ( range_error const& ) {
        format_integer( xs_n, default_pic, dest );
      }
      break;

    case picture::arabic: {
      xs_integer xs_n2( xs_n );
      if ( xs_n2.sign() < 0 )
        xs_n2 = -xs_n2;

      zstring const s( xs_n2.toString() );
      zstring::const_reverse_iterator n_i( s.rbegin() );
      zstring::const_reverse_iterator const n_end( s.rend() );

      utf8_string<zstring const> const u_pic_format( pic.primary.format );
      utf8_string<zstring const>::const_reverse_iterator
        pic_i( u_pic_format.rbegin() );
      utf8_string<zstring const>::const_reverse_iterator const
        pic_end( u_pic_format.rend() );

      int digit_pos = 0;
      unicode::code_point grouping_cp;
      bool just_inserted_grouping_separator = false;
      int mandatory_digits = pic.primary.mandatory_digits;
      int mandatory_grouping_seps = pic.primary.mandatory_grouping_seps;
      utf8_string<zstring> u_dest( *dest );

      //
      // Step through both the integer and picture from right-to-left.
      //
      while ( n_i != n_end || pic_i != pic_end ) {
        unicode::code_point digit_cp = pic.primary.zero;
        if ( n_i != n_end )
          digit_cp += *n_i - '0';
        if ( pic_i != pic_end ) {       // haven't exhausted the picture
          if ( !mandatory_digits && !mandatory_grouping_seps && n_i == n_end )
            break;
          unicode::code_point const pic_cp = *pic_i++;
          if ( pic_cp == '#' || unicode::is_Nd( pic_cp ) ) {
            u_dest.insert( 0, 1, digit_cp );
            if ( n_i != n_end ) ++n_i;
            ++digit_pos;
            if ( pic_cp != '#' )
              --mandatory_digits;
          } else {                      // must be a grouping-separator
            grouping_cp = pic_cp;       // remember for later
            u_dest.insert( 0, 1, grouping_cp );
            if ( mandatory_grouping_seps )
              --mandatory_grouping_seps;
          }
        } else {                        // have exhausted the picture
          if ( pic.primary.grouping_interval &&
               digit_pos % pic.primary.grouping_interval == 0 ) {
            if ( just_inserted_grouping_separator )
              just_inserted_grouping_separator = false;
            else {
              u_dest.insert( 0, 1, grouping_cp );
              just_inserted_grouping_separator = true;
              continue;
            }
          }
          u_dest.insert( 0, 1, digit_cp );
          if ( n_i != n_end ) ++n_i;
          ++digit_pos;
        }
      } // while

      if ( xs_n.sign() < 0 )
        dest->insert( (zstring::size_type)0, 1, '-' );
      if ( pic.modifier.co == picture::ordinal )
        *dest += ordinal( xs_n );
      break;
    }

    case picture::alpha:
    case picture::ALPHA:
      if ( xs_n.sign() == 0 ) {
        //
        // Ibid: Numbers that fall outside this range must be formatted using
        // the format token 1.
        //
        *dest = '0';
      } else
        try {
          xs_long n = to_xs_long( xs_n );
          if ( n < 0 ) {
            *dest = '-';
            n = -n;
          }
          *dest += ztd::alpha( n, pic.primary.type == picture::ALPHA );
        }
        catch ( range_error const& ) {
          format_integer( xs_n, default_pic, dest );
        }
      break;

    case picture::roman:
    case picture::ROMAN:
      if ( xs_n.sign() == 0 ) {
        //
        // Ibid: Numbers that fall outside this range must be formatted using
        // the format token 1.
        //
        *dest = '0';
      } else
        try {
          xs_long n = to_xs_long( xs_n );
          if ( n < 0 ) {
            *dest = '-';
            n = -n;
          }
          ostringstream oss;
          if ( pic.primary.type == picture::ROMAN )
            oss << uppercase;
          oss << roman( static_cast<unsigned>( n ) );
          *dest += oss.str();
        }
        catch ( range_error const& ) {
          format_integer( xs_n, default_pic, dest );
        }
      break;

    case picture::words:
      try {
        xs_long const n = to_xs_long( xs_n );
        *dest = ztd::english( n, pic.modifier.co == picture::ordinal );
      }
      catch ( range_error const& ) {
        format_integer( xs_n, default_pic, dest );
      }
      break;

    case picture::Words:
      try {
        xs_long const n = to_xs_long( xs_n );
        *dest = ztd::english( n, pic.modifier.co == picture::ordinal );
        std::transform(
          dest->begin(), dest->end(), dest->begin(), ascii::to_title()
        );
      }
      catch ( range_error const& ) {
        format_integer( xs_n, default_pic, dest );
      }
      break;

    case picture::WORDS:
      try {
        xs_long const n = to_xs_long( xs_n );
        *dest = ztd::english( n, pic.modifier.co == picture::ordinal );
        ascii::to_upper( *dest );
      }
      catch ( range_error const& ) {
        format_integer( xs_n, default_pic, dest );
      }
      break;
  } // switch
}