protected String tradAlphaCount()

in xalan/src/main/java/org/apache/xalan/templates/ElemNumber.java [1730:1928]


  protected String tradAlphaCount(long val, XResourceBundle thisBundle)
  {

    // if this number is larger than the largest number we can represent, error!
    if (val > Long.MAX_VALUE)
    {
      this.error(XSLTErrorResources.ER_NUMBER_TOO_BIG);
      return XSLTErrorResources.ERROR_STRING;
    }
    char[] table = null;

    // index in table of the last character that we stored
    int lookupIndex = 1;  // start off with anything other than zero to make correction work

    // Create a buffer to hold the result
    // TODO:  size of the table can be detereined by computing
    // logs of the radix.  For now, we fake it.
    char buf[] = new char[100];

    //some languages go left to right(ie. english), right to left (ie. Hebrew),
    //top to bottom (ie.Japanese), etc... Handle them differently
    //String orientation = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_ORIENTATION);
    // next character to set in the buffer
    int charPos;

    charPos = 0;  //start at 0

    // array of number groups: ie.1000, 100, 10, 1
    IntArrayWrapper groups = (IntArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_NUMBERGROUPS);

    // array of tables of hundreds, tens, digits...
    StringArrayWrapper tables =
      (StringArrayWrapper) (thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_NUM_TABLES));

    //some languages have additive alphabetical notation,
    //some multiplicative-additive, etc... Handle them differently.
    String numbering = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_NUMBERING);

    // do multiplicative part first
    if (numbering.equals(org.apache.xml.utils.res.XResourceBundle.LANG_MULT_ADD))
    {
      String mult_order = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.MULT_ORDER);
      LongArrayWrapper multiplier =
        (LongArrayWrapper) (thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_MULTIPLIER));
      CharArrayWrapper zeroChar = (CharArrayWrapper) thisBundle.getObject("zero");
      int i = 0;

      // skip to correct multiplier
      while (i < multiplier.getLength() && val < multiplier.getLong(i))
      {
        i++;
      }

      do
      {
        if (i >= multiplier.getLength())
          break;  //number is smaller than multipliers

        // some languages (ie chinese) put a zero character (and only one) when
        // the multiplier is multiplied by zero. (ie, 1001 is 1X1000 + 0X100 + 0X10 + 1)
        // 0X100 is replaced by the zero character, we don't need one for 0X10
        if (val < multiplier.getLong(i))
        {
          if (zeroChar.getLength() == 0)
          {
            i++;
          }
          else
          {
            if (buf[charPos - 1] != zeroChar.getChar(0))
              buf[charPos++] = zeroChar.getChar(0);

            i++;
          }
        }
        else if (val >= multiplier.getLong(i))
        {
          long mult = val / multiplier.getLong(i);

          val = val % multiplier.getLong(i);  // save this.

          int k = 0;

          while (k < groups.getLength())
          {
            lookupIndex = 1;  // initialize for each table

            if (mult / groups.getInt(k) <= 0)  // look for right table
              k++;
            else
            {

              // get the table
              CharArrayWrapper THEletters = (CharArrayWrapper) thisBundle.getObject(tables.getString(k));

              table = new char[THEletters.getLength() + 1];

              int j;

              for (j = 0; j < THEletters.getLength(); j++)
              {
                table[j + 1] = THEletters.getChar(j);
              }

              table[0] = THEletters.getChar(j - 1);  // don't need this                                                                         

              // index in "table" of the next char to emit
              lookupIndex = (int)mult / groups.getInt(k);

              //this should not happen
              if (lookupIndex == 0 && mult == 0)
                break;

              char multiplierChar = ((CharArrayWrapper) (thisBundle.getObject(
                org.apache.xml.utils.res.XResourceBundle.LANG_MULTIPLIER_CHAR))).getChar(i);

              // put out the next character of output   
              if (lookupIndex < table.length)
              {
                if (mult_order.equals(org.apache.xml.utils.res.XResourceBundle.MULT_PRECEDES))
                {
                  buf[charPos++] = multiplierChar;
                  buf[charPos++] = table[lookupIndex];
                }
                else
                {

                  // don't put out 1 (ie 1X10 is just 10)
                  if (lookupIndex == 1 && i == multiplier.getLength() - 1){}
                  else
                    buf[charPos++] = table[lookupIndex];

                  buf[charPos++] = multiplierChar;
                }

                break;  // all done!
              }
              else
                return XSLTErrorResources.ERROR_STRING;
            }  //end else
          }  // end while        

          i++;
        }  // end else if
      }  // end do while
      while (i < multiplier.getLength());
    }

    // Now do additive part...
    int count = 0;
    String tableName;

    // do this for each table of hundreds, tens, digits...
    while (count < groups.getLength())
    {
      if (val / groups.getInt(count) <= 0)  // look for correct table
        count++;
      else
      {
        CharArrayWrapper theletters = (CharArrayWrapper) thisBundle.getObject(tables.getString(count));

        table = new char[theletters.getLength() + 1];

        int j;

        // need to start filling the table up at index 1
        for (j = 0; j < theletters.getLength(); j++)
        {
          table[j + 1] = theletters.getChar(j);
        }

        table[0] = theletters.getChar(j - 1);  // don't need this

        // index in "table" of the next char to emit
        lookupIndex = (int)val / groups.getInt(count);

        // shift input by one "column"
        val = val % groups.getInt(count);

        // this should not happen
        if (lookupIndex == 0 && val == 0)
          break;

        if (lookupIndex < table.length)
        {

          // put out the next character of output       
          buf[charPos++] = table[lookupIndex];  // left to right or top to bottom                                       
        }
        else
          return XSLTErrorResources.ERROR_STRING;

        count++;
      }
    }  // end while

    // String s = new String(buf, 0, charPos);
    return new String(buf, 0, charPos);
  }