Java: Convert String to packed decimal

mpmp picture mpmp · Jun 26, 2012 · Viewed 16.9k times · Source

new here!

Situation: I'm working on a project which needs to communicate with an AS/400 server. My task is to basically handle the requests which will be sent to the AS/400 server. To do this, all the user input should be in EDCDIC bytes.

Problem:
I have managed to convert packed decimals to String with the code below, found on this forum:

public class PackedDecimal {
    public static long parse(byte[] pdIn) throws Exception {
        // Convert packed decimal to long
        final int PlusSign = 0x0C; // Plus sign
        final int MinusSign = 0x0D; // Minus
        final int NoSign = 0x0F; // Unsigned
        final int DropHO = 0xFF; // AND mask to drop HO sign bits
        final int GetLO = 0x0F; // Get only LO digit
        long val = 0; // Value to return

        for (int i = 0; i < pdIn.length; i++) {
            int aByte = pdIn[i] & DropHO; // Get next 2 digits & drop sign bits
            if (i == pdIn.length - 1) { // last digit?
                int digit = aByte >> 4; // First get digit
                val = val * 10 + digit;
                // System.out.println("digit=" + digit + ", val=" + val);
                int sign = aByte & GetLO; // now get sign
                if (sign == MinusSign)
                    val = -val;
                else {
                    // Do we care if there is an invalid sign?
                    if (sign != PlusSign && sign != NoSign)
                        throw new Exception("OC7");
                }
            } else {
                int digit = aByte >> 4; // HO first
                val = val * 10 + digit;
                // System.out.println("digit=" + digit + ", val=" + val);
                digit = aByte & GetLO; // now LO
                val = val * 10 + digit;
                // System.out.println("digit=" + digit + ", val=" + val);
            }
        }
        return val;
    } // end parse()
      // Test the above

    public static void main(String[] args) throws Exception {
        byte[] pd = new byte[] { 0x19, 0x2C }; // 192
        System.out.println(PackedDecimal.parse(pd));
        pd = new byte[] { (byte) 0x98, 0x44, 0x32, 0x3D }; // -9844323
        System.out.println(PackedDecimal.parse(pd));
        pd = new byte[] { (byte) 0x98, 0x44, 0x32 }; // invalid sign
        System.out.println(PackedDecimal.parse(pd));
    }
}

My problem now is I have to convert these String values again to EBCDIC bytes so that the AS/400 server would understand it. I'm planning to do something like constructing a request (raw bytes) using the format specified in the Silverlake documentation. Once the request is built, I plan to manually change values inside that request using a POJO which stores my request (with setters and getters) so I could just go like request.setField1("Stuff".getBytes(Charset.forName("Cp1047"))).

I don't have that much experience with bits, bytes and nibbles. I hope someone could help me out.

In our code, there's a packed decimal we found which consists of 5 bytes. It goes something like = {00 00 00 00 0F}. I convert this using the method I got from the code above and the value I got was 0. Now, I would like to convert this 0 back to its original form with its original byte size 5.

Answer

James Allman picture James Allman · Jun 26, 2012

The IBM Toolbox for Java and JTOpen library provides data conversion classes for exactly this purpose.