Package anvil.util

Source Code of anvil.util.Format

/*
* $Id: Format.java,v 1.5 2002/09/16 08:05:07 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.util;

import anvil.core.Any;
import java.text.DecimalFormat;

public class Format
{

  private static final String[] TYPES = {
   "none",
   "boolean",
   "int",
   "double",
   "string",
   "char"
  };
  public static final int TYPE_BOOLEAN = 1;
  public static final int TYPE_LONG    = 2;
  public static final int TYPE_DOUBLE  = 3;
  public static final int TYPE_DOUBLE_SIGNIFICANT = 4;
  public static final int TYPE_STRING  = 5;
  public static final int TYPE_CHAR    = 6;
 
  public static final byte FLAG_ADJUST_LEFT = 1
  public static final byte FLAG_WITH_SIGN   = 2
  public static final byte FLAG_WITH_ZEROS  = 4

  public static final int STATE_INITIAL   = 0;
  public static final int STATE_PRECISION = 2;

  public static final String format(String format, Any[] arguments)
  {
    int length = format.length();
    int i = 0;
    char ch;
    StringBuffer result = new StringBuffer(length + 16);
    int index = 0;
    int max = (arguments != null) ? arguments.length : 0;
    while(i<length) {
      ch = format.charAt(i++);
      if (ch == '%') {
        if (i<length) {
          ch = format.charAt(i);
          if (ch == '%') {
            result.append('%');
          } else {
            int type = 0;
            byte flags = 0;
            int width = 0;
            int precision = 0;
            int state = STATE_INITIAL;
            boolean done = false;
         
            while(i<length) {
              switch(ch) {
              case 'b':
                i++;
                type = TYPE_BOOLEAN;
                done = true;
                break;
              case 'd':
              case 'i':
                i++;
                type = TYPE_LONG;
                done = true;
                break;
              case 'f':
                i++;
                type = TYPE_DOUBLE;
                done = true;
                break;
              case 'g':
                i++;
                type = TYPE_DOUBLE_SIGNIFICANT;
                done = true;
                break;
              case 'c':
                i++;
                type = TYPE_CHAR;
                done = true;
                break;
              case 's':
                i++;
                type = TYPE_STRING;
                done = true;
                break;

              case ' ':
                i++;
                if (state == STATE_INITIAL) {
                  flags &= ~FLAG_WITH_ZEROS;
                } else {
                  done = true;
                }
                break;
              case '-':
                i++;
                if (state == STATE_INITIAL) {
                  flags |= FLAG_ADJUST_LEFT;
                } else {
                  done = true;
                }
                break;
              case '+':
                i++;
                if (state == STATE_INITIAL) {
                  flags |= FLAG_WITH_SIGN;
                } else {
                  done = true;
                }
                break;
               
              case '.':
                i++;
                state = STATE_PRECISION;
                break;
             
              case '*':
                i++;
                if (state == STATE_PRECISION) {
                  precision = -1;
                } else {
                  width = -1;
                  state = STATE_PRECISION;
                }
                break;
             
              case '0':
                i++;
                if (state == STATE_INITIAL) {
                  flags |= FLAG_WITH_ZEROS;
                  break;
                }

              case '1':
              case '2':
              case '3':
              case '4':
              case '5':
              case '6':
              case '7':
              case '8':
              case '9':
                int begin = i;
                while(i+1 < length) {
                  ch = format.charAt(i+1);
                  if ((ch<'0') || (ch >'9')) {
                    break;
                  }
                  i++;
                }
                int num = 0;
                int mul = 1;
                int j = i;
                while(j>=begin) {
                  num += mul * (format.charAt(j--) - '0');
                  mul *= 10;
                }

                if (state == STATE_PRECISION) {
                  precision = num;
                } else {
                  width = num;
                }
                i++;
                break;
               
              default:
                done = true;
               
              }
              if (done) {
                break;
              }
              if (i<length) {
                ch = format.charAt(i);
              }
            }

            if (type != 0) {
              index = append(result, type, flags, width, precision, arguments, index, max);
            }
           
          }
         
        } else {
          result.append('%');
        }
      } else {
        result.append(ch);
      }
    }
    return result.toString();
  }


  private static final void appendChar(StringBuffer result, Any value)
  {
    if (value.isInt()) {
      result.append((char)value.toInt());
    } else {
      String s = value.toString();
      if (s.length() > 0) {
        result.append(s.charAt(0));
      } else {
        result.append(' ');
      }
    }
  }


  private static final int numlen(long number)
  {
    if (number == 0) {
      return 1;
    }
    int length = 0;
    if (number < 0) {
      length++;
    }
    while(number != 0) {
      number /= 10;
      length++;
    }
    return length;
  }
 

  private static final void appendLong(StringBuffer result, byte flags, int width, long num)
  {
    switch(flags) {

    case 0*FLAG_WITH_ZEROS | 0*FLAG_WITH_SIGN | 0*FLAG_ADJUST_LEFT:
      if (width > 0) {
        int len = numlen(num);
        if (len < width) {
          width -= len;
          while(width-- > 0) {
            result.append(' ');
          }
        }
        result.append(num);
      } else {
        result.append(num);
      }
      break;

    case 0*FLAG_WITH_ZEROS | 0*FLAG_WITH_SIGN | 1*FLAG_ADJUST_LEFT:
      if (width > 0) {
        result.append(num);
        int len = numlen(num);
        if (len < width) {
          width -= len;
          while(width-- > 0) {
            result.append(' ');
          }
        }
      } else {
        result.append(num);
      }
      break;

    case 0*FLAG_WITH_ZEROS | 1*FLAG_WITH_SIGN | 0*FLAG_ADJUST_LEFT:
      if (width > 0) {
        int len = numlen(num);
        if (num>=0) {
          len++;
        }
        if (len < width) {
          width -= len;
          while(width-- > 0) {
            result.append(' ');
          }
        }
        if (num >= 0) {
          result.append('+');
        }
        result.append(num);
      } else {
        if (num >= 0) {
          result.append('+');
        }
        result.append(num);
      }
      break;

    case 0*FLAG_WITH_ZEROS | 1*FLAG_WITH_SIGN | 1*FLAG_ADJUST_LEFT:
      if (width > 0) {
        int len = numlen(num);
        if (num >= 0) {
          result.append('+');
          len++;
        }
        result.append(num);
        if (len < width) {
          width -= len;
          while(width-- > 0) {
            result.append(' ');
          }
        }
      } else {
        if (num >= 0) {
          result.append('+');
        }
        result.append(num);
      }
      break;

    case 1*FLAG_WITH_ZEROS | 0*FLAG_WITH_SIGN | 0*FLAG_ADJUST_LEFT:
      if (width > 0) {
        int len = numlen(num);
        if (num < 0) {
          result.append('-');
          num = -num;
          len--;
          width--;
        }
        if (len < width) {
          width -= len;
          while(width-- > 0) {
            result.append('0');
          }
        }
        result.append(num);
      } else {
        result.append(num);
      }
      break;

    case 1*FLAG_WITH_ZEROS | 0*FLAG_WITH_SIGN | 1*FLAG_ADJUST_LEFT:
      if (width > 0) {
        int len = numlen(num);
        if (num < 0) {
          result.append('-');
          num = -num;
        }
        if (len < width) {
          width -= len;
          while(width-- > 0) {
            result.append('0');
          }
        }
        result.append(num);
      } else {
        result.append(num);
      }
      break;

    case 1*FLAG_WITH_ZEROS | 1*FLAG_WITH_SIGN | 0*FLAG_ADJUST_LEFT:
      if (width > 0) {
        int len = numlen(num);
        if (num >= 0) {
          result.append('+');
          len++;
        } else {
          result.append('-');
          num = -num;
        }
        if (len < width) {
          width -= len;
          while(width-- > 0) {
            result.append('0');
          }
        }
        result.append(num);
      } else {
        if (num >= 0) {
          result.append('+');
        }
        result.append(num);
      }
      break;

    case 1*FLAG_WITH_ZEROS | 1*FLAG_WITH_SIGN | 1*FLAG_ADJUST_LEFT:
      if (width > 0) {
        int len = numlen(num);
        if (num >= 0) {
          result.append('+');
          len++;
        } else {
          result.append('-');
          num = -num;
        }
        if (len < width) {
          width -= len;
          while(width-- > 0) {
            result.append('0');
          }
        }
        result.append(num);
      } else {
        if (num >= 0) {
          result.append('+');
        }
        result.append(num);
      }
      break;
    }
  }


  private static final void appendString(StringBuffer result, byte flags,
     int width, String str)
  {
    if (width > 0) {
      int len = str.length();
      if (len == width) {
        result.append(str);
      } else if (len > width) {
        result.append(str.substring(0, width));
      } else {
        if ((flags & FLAG_ADJUST_LEFT) != 0) {
          result.append(str);
          width -= len;
          while(width-- > 0) {
            result.append(' ');
          }
        } else {
          width -= len;
          while(width-- > 0) {
            result.append(' ');
          }
          result.append(str);
        }
      }
    } else {
      result.append(str);
    }
  }


  private static final void appendFloat(StringBuffer result, byte flags,
    int width, int precision, double number, boolean significant)
  {
    StringBuffer format = new StringBuffer(32);
   
    boolean negative = (number < 0.0);
    number = Math.abs(number);

    if (width>0) {
      int i = width;
      if (negative || (flags & FLAG_WITH_SIGN) != 0) {
        format.append(negative ? '-' : '+');
        i--;
      }
      while(i-- > 0) {
        format.append('0');
      }
    } else {
      if (negative || (flags & FLAG_WITH_SIGN) != 0) {
        format.append(negative ? '-' : '+');
      }
      format.append('0');
    }
    if (precision>0) {
      format.append('.');
      int i = precision;
      while(i-- > 0) {
        format.append('0');
      }
    } else if (significant) {
      format.append(".##########################");
    }
    format.append(';');
   
    String formatted = new java.text.DecimalFormat(format.toString()).format(number);

    if ((flags & FLAG_WITH_ZEROS) == 0) {
      format.setLength(0);
      int n = formatted.length();
     
      format.append(formatted);
      while (n < width+1+precision) {
        format.append(' ');
        n++;
      }

      char sign = ' ';
      int i = 0;
      if (n>0) {
        sign = format.charAt(0);
        if (sign == '-' || sign == '+') {
          i++;
        }
        while((i+1<n) && (format.charAt(i) == '0') && (format.charAt(i+1) != '.')) {
          format.setCharAt(i++, ' ');
        }
      }

      i--;
      if (i>0 && (sign == '-' || sign == '+')) {
        format.setCharAt(0, ' ');
        format.setCharAt(i, sign);
      } else {
        formatted = format.toString();
      }

      if (i>0 && (flags & FLAG_ADJUST_LEFT) != 0) {
        if (sign != '-' && sign != '+') {
          formatted = format.substring(i+1) + format.substring(0, i+1);
        } else {
          formatted = format.substring(i) + format.substring(0, i);
        }
      } else {
        formatted = format.toString();
      }
     
    }
   
    result.append(formatted);
  }


  private static final int append(StringBuffer result, int type, byte flags,
      int width, int precision, Any[] arguments, int index, int max)
  {

    Any value = (index < max) ? arguments[index++] : Any.NULL;

    if (width == -1) {
      width = (index < max) ? arguments[index++].toInt() : 0;
      if (width < 0) {
        width = 0;
      }
    }

    if (precision == -1) {
      precision = (index < max) ? arguments[index++].toInt() : 0;
      if (precision < 0) {
        precision = 0;
      }
    }
   
    switch(type) {
    case TYPE_CHAR:
      if (width > 0) {
        if ((flags & FLAG_ADJUST_LEFT) != 0) {
          appendChar(result, value);
          while(--width > 0) {
            result.append(' ');
          }
        } else {
          while(width-- > 1) {
            result.append(' ');
          }
          appendChar(result, value);
        }
      } else {
        appendChar(result, value);
      }
      break;
   
    case TYPE_BOOLEAN:
    case TYPE_STRING:
      appendString(result, flags, width, value.toString());
      break;

    case TYPE_LONG:
      appendLong(result, flags, width, value.toLong());
      break;

    case TYPE_DOUBLE:
      appendFloat(result, flags, width, precision, value.toDouble(), false);
      break;

    case TYPE_DOUBLE_SIGNIFICANT:
      appendFloat(result, flags, width, precision, value.toDouble(), true);
      break;
     
    }
   
    return index;
  }

}
TOP

Related Classes of anvil.util.Format

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.