1
2
3
4
5
6
7
8 package it.imolinfo.jbi4cics.typemapping.cobol;
9
10 import it.imolinfo.jbi4cics.Logger;
11 import it.imolinfo.jbi4cics.LoggerFactory;
12 import it.imolinfo.jbi4cics.exception.FormatException;
13 import it.imolinfo.jbi4cics.jbi.Messages;
14
15 import java.math.BigDecimal;
16
17
18 public class ZonedMarshaller {
19
20
21
22
23 private static final Logger LOG
24 = LoggerFactory.getLogger(ZonedMarshaller.class);
25
26
27
28
29 private static final Messages MESSAGES
30 = Messages.getMessages(ZonedMarshaller.class);
31
32 private final static byte EBCDIC_PLUS = 0x4E;
33 private final static byte EBCDIC_MINUS = 0x60;
34
35
36
37
38 public ZonedMarshaller(){
39 }
40
41
42 public static void marshallZoned(BigDecimal value, byte[] buffer, int startingOffset, int size, boolean signed, int virtualDecimalPoint, int signFormat, String codePage){
43
44 value=value.movePointRight(virtualDecimalPoint);
45 value=value.setScale(0);
46
47 int signOffset=((signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING_SEPARATE)&&(signed))?1:0;
48 int dataSize=size-signOffset;
49 boolean isNegative=false;
50 if (value.compareTo(new BigDecimal(0))==-1){
51 value=value.abs();
52 isNegative=true;
53 }
54
55 String stringValue=value.toPlainString();
56 StringBuffer stringBufferValue=new StringBuffer(stringValue);
57
58
59
60 for (int i=0;i<(dataSize-stringValue.length());i++){
61 stringBufferValue.insert(0, '0');
62 }
63
64 LOG.debug("stringValue after padding: "+stringBufferValue);
65 byte[] valueArray=stringBufferValue.toString().getBytes();
66
67 int dataStartingOffset=startingOffset+signOffset;
68 for (int i=dataSize-1;i>=0;i--){
69 byte currentByte=(byte)(valueArray[i] & 0x0f);
70
71 if ((signFormat==CobolTypeDescriptor.SIGN_FORMAT_TRAILING && signed && i==dataSize-1) || (signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING && signed && i==0)){
72 if (isNegative){
73 currentByte=(byte) ((PackedDecimalMarshaller.NEGATIVE_SIGN << 4) | currentByte);
74 }
75 else {
76 currentByte=(byte) ((PackedDecimalMarshaller.POSITIVE_SIGN << 4) | currentByte);
77 }
78 }
79 else {
80 currentByte=(byte)(0xf0 | currentByte);
81 }
82 buffer[dataStartingOffset+i]=currentByte;
83 }
84 if (signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING_SEPARATE && signed){
85 if (isNegative){
86 buffer[startingOffset]= EBCDIC_MINUS;
87 }
88 else {
89 buffer[startingOffset]=EBCDIC_PLUS;
90 }
91 }
92
93 }
94 public static BigDecimal unmarshallZoned(byte[] buffer, int startingOffset, int size, boolean signed, int virtualDecimalPoint, int signFormat, String codePage) throws FormatException{
95 int signOffset=((signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING_SEPARATE)&&(signed))?1:0;
96 int dataStartingOffset=startingOffset+signOffset;
97 int dataSize=size-signOffset;
98 boolean positive=true;
99 if (signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING_SEPARATE && signed){
100 byte signByte=buffer[startingOffset];
101 switch (signByte) {
102 case EBCDIC_PLUS : {positive=true;break;}
103 case EBCDIC_MINUS : {positive=false;break;}
104 default : {
105 LOG.error("CIC002119_Sign_not_recognized", signByte);
106 throw new FormatException(MESSAGES.getString(
107 "CIC002119_Sign_not_recognized", signByte));
108 }
109 }
110 }
111 StringBuffer stringBuffer=new StringBuffer();
112 for (int i=0;i<dataSize;i++){
113 byte currentByte=buffer[dataStartingOffset+i];
114
115 if ((signFormat==CobolTypeDescriptor.SIGN_FORMAT_TRAILING && signed && i==dataSize-1) || (signFormat==CobolTypeDescriptor.SIGN_FORMAT_LEADING && signed && i==0)){
116 byte signByte=(byte) ((currentByte & 0xf0)>>4);
117
118 if (signByte==PackedDecimalMarshaller.NEGATIVE_SIGN){
119 positive=false;
120 }
121 }
122 stringBuffer.append(String.valueOf(currentByte & 0x0f));
123 }
124 BigDecimal result=new BigDecimal(stringBuffer.toString());
125 result=result.movePointLeft(virtualDecimalPoint);
126 if (!positive){
127 result=result.negate();
128 }
129 return result;
130 }
131
132 }