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 public class PackedDecimalMarshaller {
18
19
20
21
22 private static final Logger LOG
23 = LoggerFactory.getLogger(PackedDecimalMarshaller.class);
24
25
26
27
28 private static final Messages MESSAGES
29 = Messages.getMessages(PackedDecimalMarshaller.class);
30
31
32
33 public final static byte POSITIVE_SIGN = 0x0C;
34 public final static byte NEGATIVE_SIGN = 0x0D;
35 public final static byte NO_SIGN = 0x0F;
36
37
38
39
40 public PackedDecimalMarshaller(){
41 }
42
43
44
45
46 public static void marshallBigDecimal(BigDecimal value, byte[] buffer, CobolTypeDescriptor cobolType, int startingOffset) throws FormatException{
47 LOG.debug("value: "+value);
48
49 value=value.movePointRight(cobolType.getVirtualDecimalPoint());
50
51 value=value.setScale(0);
52
53 boolean isNegative=false;
54 if (value.compareTo(new BigDecimal(0))==-1){
55 value=value.abs();
56 isNegative=true;
57 }
58
59 String stringValue=value.toPlainString();
60
61 StringBuffer stringBufferValue=new StringBuffer();
62 int numberSize=cobolType.getIntegerPartLength()+cobolType.getDecimalPartLength();
63
64 for (int i=0;i<(numberSize-stringValue.length());i++){
65 stringBufferValue.append('0');
66 }
67
68 stringValue=stringBufferValue+stringValue;
69
70 byte[] valueArray=stringValue.toString().getBytes();
71 int bufferedLength=cobolType.getBufferedLength();
72 for (int i=bufferedLength-1;i>=0;i--){
73 byte result;
74 if (i==bufferedLength-1){
75
76 byte signByte;
77 if (cobolType.isSigned()){
78 if (isNegative){
79 signByte=NEGATIVE_SIGN;
80 }
81 else {
82 signByte=POSITIVE_SIGN;
83 }
84 }
85 else {
86 signByte=NO_SIGN;
87 }
88 result=(byte)((valueArray[i*2+(valueArray.length%2)-1]<<4)|signByte);
89 }
90 else {
91 if (i==0 && (valueArray.length%2)==0){
92 result=(byte)(0x0f&valueArray[0]);
93 }
94 else {
95 byte lowSemibyte=(byte)(0x0f&valueArray[i*2+(valueArray.length%2)]);
96 byte highSemibyte=(byte)(0x0f&valueArray[i*2+(valueArray.length%2)-1]);
97
98
99
100
101
102 result=(byte)( (highSemibyte << 4) | lowSemibyte );
103 }
104 }
105
106 buffer[startingOffset+i]=result;
107 }
108 }
109
110 public static BigDecimal unmarshallBigDecimal(byte[] buffer, CobolTypeDescriptor cobolType,int startingOffset) throws FormatException{
111 StringBuffer stringBuffer=new StringBuffer();
112 boolean positive=true;
113 for (int i=0;i<cobolType.getBufferedLength();i++){
114 byte currentByte=buffer[startingOffset+i];
115
116 if (i==cobolType.getBufferedLength()-1){
117
118 if (cobolType.isSigned()){
119 byte signbyte=(byte)(currentByte&0x0F);
120 switch (signbyte) {
121 case POSITIVE_SIGN : {positive=true;break;}
122 case NEGATIVE_SIGN : {positive=false;break;}
123 default: {
124 LOG.error("CIC002115_Signed_decimal_int_not_found", signbyte);
125 throw new FormatException(MESSAGES.getString("CIC002115_Signed_decimal_int_not_found", signbyte));
126 }
127 }
128 }
129 byte firstChar=(byte)((currentByte&0xF0)>>4);
130 stringBuffer.append(String.valueOf(firstChar));
131 }
132 else {
133 byte lowSemiByte=(byte)(currentByte&0x0F);
134 byte highSemiByte=(byte)((currentByte&0xF0)>>4);
135
136
137 stringBuffer.append(String.valueOf(highSemiByte));
138 stringBuffer.append(String.valueOf(lowSemiByte));
139
140
141 }
142 }
143
144 BigDecimal result=new BigDecimal(stringBuffer.toString());
145
146 result=result.setScale(0);
147
148 result=result.movePointLeft(cobolType.getVirtualDecimalPoint());
149
150 if (!positive){
151 result=result.negate();
152 }
153
154 return result;
155 }
156
157 }