OverpunchFormat is a subclass of DecimalFormat that formats decimal numbers into NSF Overpunch Format.
The purpose of an Overpunch format is to encode the sign (+/-) into the least significant (right-most) digit via an encoding scheme. Also the values are typically dollar amounts, and therefore are integers representing cents (1/100 dollar). The use of DecimalFormat's setMultipler method will make quick work of this scaling.
Get the Java source code for OverpunchFormat.java.
OverpunchFormat is a subclass of DecimalFormat that formats decimal numbers into NSF Overpunch Format.
The purpose of an Overpunch format is to encode the sign (+/-) into the least significant (right-most) digit via an encoding scheme. Also the values are typically dollar amounts, and therefore are integers representing cents (1/100 dollar). The use of DecimalFormat's setMultipler method will make quick work of this scaling.
//package name.koontz.util;
import java.io.Serializable;
import java.text.NumberFormat;
import java.text.ParsePosition;
import java.text.FieldPosition;
//import java.lang.Number;
//import java.lang.StringBuffer;
import java.text.*;
/**
* OverpunchFormat is a subclass of DecimalFormat that formats
* decimal numbers into NSF Overpunch Format.
*
* The purpose of an Overpunch format is to encode the sign (+/-) into the
* least significant (right-most) digit via an encoding scheme. Also the values are
* typically dollar amounts, and therefore are integers representing cents
* (1/100 dollar). The use of the setMultipler method will make quick work of
* this scaling.
*
*
*
* Holy hanging chad! Batman, the bat computer has detected an
* overpunched field, what could it mean?
*
* Well, Robin, it means the Joker has saved a byte in transmition cost, but it
* will take the bat computer only 23 instructions to figure out what this sign
* could be...
*
*
*
*
* OverpunchFormat does not support locales, itself! So do not expect Kanji
* characters in your overpunched output.
*
*
*
Overpunch Encoding
*
* Least
* Significant Positive Negative
* Digit Overpunch Overpunch
* 0 { }
* 1 A J
* 2 B K
* 3 C L
* 4 D M
* 5 E N
* 6 F O
* 7 G P
* 8 H Q
* 9 J R
*
*
*
* Example:
*
* -1575 => 157N
* +1200 => 120{
*
*
*
* If OverpunchFormat.parse(String, ParsePosition) fails to parse a string, it
* returns null, leaves the ParsePosition index unchanged, and sets the
* ParsePosition error index.
*
* A OverpunchFormat pattern contains only a postive pattern (no negative subpattern).
* Since the whole concept of an overpunched value is to
* encode the sign within the last digit, there will be no negative subpattern.
*
*
* Note: DecimalFormat JVM 1.2.2 bugs Sun Bug Id 4322804, 4254220, 4243108
*
*
* @see Format
* @see NumberFormat
* @see DecimalFormat
* @see ParsePosition
*/
public class OverpunchFormat extends java.text.DecimalFormat
implements Cloneable, Serializable {
// array of overpunch replacement characters
private static final char[] positiveDigit = {'{', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'};
// overpunch digit 0 1 2 3 4 5 6 7 8 9
private static final char[] negativeDigit = {'}', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R'};
public OverpunchFormat() {
super();
}
public OverpunchFormat(String pattern) throws IllegalArgumentException {
super(pattern);
//
}
/**
* Returns an instance of Number with a value matching the given string.
*
*
* @param text the string to be parsed
* @param parsePosition on entry, where to begin parsing; on exit, just past the last parsed character. If parsing fails, the index will not move and the error index will be set.
* @return the parsed value, or null if the parse fails
*/
public Number parse(String text, ParsePosition parsePosition) {
//
int sign = 1; // or -1 if negative
char lastDigit;
char overpunchChar = '{';
int overpunchIndex = 0;
// start at the parsePosition within text - look for a non-numeric char
// that's the overpunch char
if ( parsePosition.getIndex() < text.length() ) {
for (int i = parsePosition.getIndex(); i < text.length(); i++) {
char c = text.charAt(i);
if ( Character.getType(c) == Character.DECIMAL_DIGIT_NUMBER ) {
continue;
} else {
// found first non digit char - that's the overpunch
overpunchChar = c;
overpunchIndex = i;
break;
}
}
}
// reverse the overpunch
switch (overpunchChar) {
case '}':
sign = -1;
lastDigit = '0';
break;
case '{':
sign = 1;
lastDigit = '0';
break;
case 'A':
sign = 1;
lastDigit = '1';
break;
case 'B':
sign = 1;
lastDigit = '2';
break;
case 'C':
sign = 1;
lastDigit = '3';
break;
case 'D':
sign = 1;
lastDigit = '4';
break;
case 'E':
sign = 1;
lastDigit = '5';
break;
case 'F':
sign = 1;
lastDigit = '6';
break;
case 'G':
sign = 1;
lastDigit = '7';
break;
case 'H':
sign = 1;
lastDigit = '8';
break;
case 'I':
sign = 1;
lastDigit = '9';
break;
case 'J':
sign = -1;
lastDigit = '1';
break;
case 'K':
sign = -1;
lastDigit = '2';
break;
case 'L':
sign = -1;
lastDigit = '3';
break;
case 'M':
sign = -1;
lastDigit = '4';
break;
case 'N':
sign = -1;
lastDigit = '5';
break;
case 'O':
sign = -1;
lastDigit = '6';
break;
case 'P':
sign = -1;
lastDigit = '7';
break;
case 'Q':
sign = -1;
lastDigit = '8';
break;
case 'R':
sign = -1;
lastDigit = '9';
break;
default:
// not the overpunch char - error
parsePosition.setErrorIndex(overpunchIndex);
return null; // error return null
}
// replace with the overpunch char in text with the digit
StringBuffer sb = new StringBuffer(text);
sb.setCharAt(overpunchIndex, lastDigit);
// now call the super's function
Number n = super.parse(sb.toString(), parsePosition);
if ( n instanceof Double ) {
double d = n.doubleValue();
d = d * sign;
n = new Double(d);
} else if ( n instanceof Long ) {
long l = n.longValue();
l = l * sign;
n = new Long(l);
} else {
; // nothing
}
return n;
}
/**
* Formats a long to produce a string.
*
* @param number the long to format
* @param result where the text is to be appended
* @param fieldPosition On input: an alignment field, if desired. On output: the offsets of the alignment field.
* @return The value passed in as the result parameter
*/
public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) {
//System.out.println("OverpunchFormat.format|long number");
//System.out.println("OverpunchFormat.format( "+number+", "+result.toString()+", "+fieldPosition+" )");
//
StringBuffer buf = new StringBuffer(result.length()+20);
long abs = Math.abs(number); // get the absolute value
//System.out.println(" abs = "+abs);
// call DecmialFormat to format all but the overpunch
buf = super.format(abs, result, fieldPosition);
//System.out.println(" super.format() returns buf = " + buf.toString());
// now we must workout the overpunch
//
// get last digit of the string
char overpunchChar = buf.charAt(buf.length()-1);
//System.out.println(" buf.length()-1 = " + (buf.length()-1));
//System.out.println(" overpunchChar = " + overpunchChar);
// convert last digit to index into the overpunch (+/-) array
int overpunchIndex = Character.getNumericValue(overpunchChar);
//System.out.println(" overpunchIndex = " + overpunchIndex);
// get overpunch char
if ( number < 0 ) {
overpunchChar = negativeDigit[overpunchIndex];
} else {
overpunchChar = positiveDigit[overpunchIndex];
}
//System.out.println(" overpunchChar = " + overpunchChar);
// replace the lastChar in the string with new lastChar
buf.deleteCharAt(buf.length()-1);
buf.append(overpunchChar);
//System.out.println(" buf = " + buf.toString());
return buf;
}
/**
* Formats a double to produce a string.
*
* @param number the double to format
* @param result where the text is to be appended
* @param fieldPosition On input: an alignment field, if desired. On output: the offsets of the alignment field.
* @return The value passed in as the result parameter
*/
public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
//System.out.println("OverpunchFormat.format|double number");
//System.out.println("OverpunchFormat.format( "+number+", "+result.toString()+", "+fieldPosition+" )");
//
StringBuffer buf = new StringBuffer(result.length()+20);
double abs = Math.abs(number); // get the absolute value
//System.out.println(" abs = "+abs);
// call DecmialFormat to format all but the overpunch
buf = super.format(abs, result, fieldPosition);
//System.out.println(" super.format() returns buf = " + buf.toString());
// now we must workout the overpunch
//
// get last digit of the string
char overpunchChar = buf.charAt(buf.length()-1);
//System.out.println(" buf.length()-1 = " + (buf.length()-1));
//System.out.println(" overpunchChar = " + overpunchChar);
// convert last digit to index into the overpunch (+/-) array
int overpunchIndex = Character.getNumericValue(overpunchChar);
//System.out.println(" overpunchIndex = " + overpunchIndex);
// get overpunch char
if ( number < 0 ) {
overpunchChar = negativeDigit[overpunchIndex];
} else {
overpunchChar = positiveDigit[overpunchIndex];
}
//System.out.println(" overpunchChar = " + overpunchChar);
// replace the lastChar in the string with new lastChar
buf.deleteCharAt(buf.length()-1);
buf.append(overpunchChar);
//System.out.println(" buf = " + buf.toString());
return buf;
}
/**
* The main program for the class - a test method.
*
*@param args the text to parse
*/
public static void main(String[] args) {
OverpunchFormat of = new OverpunchFormat();
of.applyPattern("0000000"); // fixed field zero padded
of.setMultiplier(100); // imply 2 decimal places
if (args.length < 2) {
System.out.println("Usage: java OverpunchFormat 'pattern' 'value'");
System.out.println("Examples format():");
System.out.println(" 9876 -> " +of.format(9876l));
System.out.println(" -1.35 -> " +of.format(-1.35));
System.out.println(" .2389 -> " +of.format(0.2389));
System.out.println("note; fixed field zero padding, implied decimal place, rounding and encoding");
StringBuffer sb = new StringBuffer("x=012345F dollars ");
ParsePosition pos = new ParsePosition(2);
System.out.println("Examples parse():");
System.out.println(" before call:" + sb);
System.out.println(" parse(sb, pos) where pos =" + pos);
System.out.println(" parse returns a Number = " + of.parse(sb.toString(), pos));
System.out.println(" and sets ParsePosition.index = " + pos.getIndex() + " & errorIndex = " + pos.getErrorIndex());
System.exit(99);
} else {
StringBuffer sb = new StringBuffer("OverpunchFormat of "+ args[1] +" is ");
of.applyPattern(args[0]);
of.format(Double.valueOf(args[1]), sb, new FieldPosition(NumberFormat.FRACTION_FIELD) );
System.out.println(sb.toString());
}
}
}
Comments