1
2
3
4
5
6
7
8
9
10
11 package com.legstar.coxb.convert.simple;
12
13 import com.legstar.coxb.CobolContext;
14 import com.legstar.coxb.ICobolArrayBinaryBinding;
15 import com.legstar.coxb.ICobolBinaryBinding;
16 import com.legstar.coxb.convert.ICobolBinaryConverter;
17 import com.legstar.coxb.convert.CobolConversionException;
18 import com.legstar.coxb.host.HostData;
19 import com.legstar.coxb.host.HostException;
20
21 import java.math.BigDecimal;
22 import java.math.BigInteger;
23 import java.util.ArrayList;
24 import java.util.List;
25
26
27
28
29
30
31
32
33 public class CobolBinarySimpleConverter extends CobolSimpleConverter
34 implements ICobolBinaryConverter {
35
36
37
38
39 public CobolBinarySimpleConverter(final CobolContext cobolContext) {
40 super(cobolContext);
41 }
42
43
44 public int toHost(
45 final ICobolBinaryBinding ce,
46 final byte[] hostTarget,
47 final int offset)
48 throws HostException {
49 int newOffset = 0;
50 try {
51 newOffset = toHostSingle(ce.getBigDecimalValue(),
52 ce.getByteLength(),
53 ce.isSigned(),
54 hostTarget,
55 offset);
56 } catch (CobolConversionException e) {
57 throwHostException(ce, e);
58 }
59 return newOffset;
60 }
61
62
63 public int toHost(
64 final ICobolArrayBinaryBinding ce,
65 final byte[] hostTarget,
66 final int offset,
67 final int currentOccurs)
68 throws HostException {
69 int newOffset = offset;
70 try {
71 for (BigDecimal javaSource : ce.getBigDecimalList()) {
72 newOffset = toHostSingle(javaSource,
73 ce.getItemByteLength(),
74 ce.isSigned(),
75 hostTarget,
76 newOffset);
77 }
78
79 for (int i = ce.getBigDecimalList().size();
80 i < currentOccurs; i++) {
81 newOffset = toHostSingle(BigDecimal.ZERO,
82 ce.getItemByteLength(),
83 ce.isSigned(),
84 hostTarget,
85 newOffset);
86 }
87 } catch (CobolConversionException e) {
88 throwHostException(ce, e);
89 }
90 return newOffset;
91 }
92
93
94 public int fromHost(
95 final ICobolBinaryBinding ce,
96 final byte[] hostSource,
97 final int offset)
98 throws HostException {
99 int newOffset = offset;
100 try {
101 BigDecimal javaDecimal = fromHostSingle(ce.getByteLength(),
102 ce.isSigned(),
103 ce.getTotalDigits(),
104 ce.getFractionDigits(),
105 hostSource,
106 newOffset);
107 ce.setBigDecimalValue(javaDecimal);
108 newOffset += ce.getByteLength();
109 } catch (CobolConversionException e) {
110 throwHostException(ce, e);
111 }
112 return newOffset;
113 }
114
115
116 public int fromHost(
117 final ICobolArrayBinaryBinding ce,
118 final byte[] hostSource,
119 final int offset,
120 final int currentOccurs)
121 throws HostException {
122 List < BigDecimal > lArray = new ArrayList < BigDecimal >();
123 int newOffset = offset;
124 try {
125 for (int i = 0; i < currentOccurs; i++) {
126 BigDecimal javaDecimal = fromHostSingle(ce.getItemByteLength(),
127 ce.isSigned(),
128 ce.getTotalDigits(),
129 ce.getFractionDigits(),
130 hostSource,
131 newOffset);
132 lArray.add(javaDecimal);
133 newOffset += ce.getItemByteLength();
134 }
135 ce.setBigDecimalList(lArray);
136
137 } catch (CobolConversionException e) {
138 throwHostException(ce, e);
139 }
140 return newOffset;
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154 public static final int toHostSingle(
155 final BigDecimal javaDecimal,
156 final int cobolByteLength,
157 final boolean isSigned,
158 final byte[] hostTarget,
159 final int offset) throws CobolConversionException {
160
161
162 int lastOffset = offset + cobolByteLength;
163 if (lastOffset > hostTarget.length) {
164 throw (
165 new CobolConversionException(
166 "Attempt to write past end of host source buffer",
167 new HostData(hostTarget), offset, cobolByteLength));
168 }
169
170
171
172 BigInteger javaInteger;
173 if (javaDecimal == null) {
174 javaInteger = BigInteger.ZERO;
175 } else {
176 javaInteger = javaDecimal.unscaledValue();
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190 byte[] javaBytes = javaInteger.toByteArray();
191 if (!isSigned) {
192 if (javaBytes.length > cobolByteLength + 1) {
193 throw (new CobolConversionException(
194 "Java binary too large for Cobol element",
195 new HostData(hostTarget), offset, cobolByteLength));
196 } else {
197 if ((javaBytes.length == cobolByteLength + 1)
198 && (javaBytes[0] != 0)) {
199 throw (new CobolConversionException(
200 "Java binary too large for Cobol element",
201 new HostData(hostTarget), offset, cobolByteLength));
202 }
203 }
204 } else {
205 if (javaBytes.length > cobolByteLength) {
206 throw (new CobolConversionException(
207 "Java binary too large for Cobol element",
208 new HostData(hostTarget), offset, cobolByteLength));
209 }
210 }
211
212
213
214
215
216
217
218
219
220 int j = offset + cobolByteLength;
221 for (int i = javaBytes.length; i > 0; i--) {
222 if (j > offset) {
223 hostTarget[j - 1] = javaBytes[i - 1];
224 j--;
225 }
226 }
227
228
229 while (j > offset) {
230 if (javaInteger.signum() == -1) {
231 hostTarget[j - 1] = -0x01;
232 } else {
233 hostTarget[j - 1] = 0;
234 }
235 j--;
236 }
237 return offset + cobolByteLength;
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251 public static final BigDecimal fromHostSingle(
252 final int cobolByteLength,
253 final boolean isSigned,
254 final int totalDigits,
255 final int fractionDigits,
256 final byte[] hostSource,
257 final int offset) throws CobolConversionException {
258
259
260
261
262 byte[] javaBytes;
263 int j;
264 if (isSigned) {
265 javaBytes = new byte[cobolByteLength];
266 j = cobolByteLength;
267 } else {
268 javaBytes = new byte[cobolByteLength + 1];
269 j = cobolByteLength + 1;
270 }
271
272 for (int i = (offset + cobolByteLength); i > offset; i--) {
273 if (j > 0) {
274 if (i > hostSource.length) {
275 javaBytes[j - 1] = 0x00;
276 } else {
277 javaBytes[j - 1] = hostSource[i - 1];
278 }
279 j--;
280 } else {
281
282
283
284
285 javaBytes[0] = 0;
286 }
287 }
288
289 BigInteger result = new BigInteger(javaBytes);
290
291
292
293 BigDecimal bDecimal = new BigDecimal(result, fractionDigits);
294
295 return bDecimal;
296 }
297
298 }