1
2
3
4
5
6
7
8
9
10
11 package com.legstar.coxb.convert.simple;
12
13 import java.io.UnsupportedEncodingException;
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.regex.Matcher;
17 import java.util.regex.Pattern;
18
19 import com.legstar.coxb.CobolContext;
20 import com.legstar.coxb.ICobolArrayStringBinding;
21 import com.legstar.coxb.ICobolStringBinding;
22 import com.legstar.coxb.convert.CobolConversionException;
23 import com.legstar.coxb.convert.ICobolStringConverter;
24 import com.legstar.coxb.host.HostData;
25 import com.legstar.coxb.host.HostException;
26
27
28
29
30
31
32
33
34 public class CobolStringSimpleConverter extends CobolSimpleConverter implements
35 ICobolStringConverter {
36
37
38 private static final Pattern BINARY_CONTENT_PATTERN = Pattern
39 .compile("0x[\\da-fA-F]+");
40
41
42
43
44 public CobolStringSimpleConverter(final CobolContext cobolContext) {
45 super(cobolContext);
46 }
47
48
49 public int toHost(final ICobolStringBinding ce, final byte[] hostTarget,
50 final int offset) throws HostException {
51 int newOffset = 0;
52 try {
53 newOffset = toHostSingle(ce.getStringValue(), getCobolContext()
54 .getHostCharsetName(), getCobolContext()
55 .getAlphanumPaddingChar(), getCobolContext()
56 .failOnAlphanumOverflow(), ce.getByteLength(),
57 ce.isJustifiedRight(), hostTarget, offset);
58 } catch (CobolConversionException e) {
59 throwHostException(ce, e);
60 }
61 return newOffset;
62 }
63
64
65 public int toHost(final ICobolArrayStringBinding ce,
66 final byte[] hostTarget, final int offset, final int currentOccurs)
67 throws HostException {
68 int newOffset = offset;
69 try {
70 for (String javaSource : ce.getStringList()) {
71 newOffset = toHostSingle(javaSource, getCobolContext()
72 .getHostCharsetName(), getCobolContext()
73 .getAlphanumPaddingChar(), getCobolContext()
74 .failOnAlphanumOverflow(), ce.getItemByteLength(),
75 ce.isJustifiedRight(), hostTarget, newOffset);
76 }
77
78 for (int i = ce.getStringList().size(); i < currentOccurs; i++) {
79 newOffset = toHostSingle("", getCobolContext()
80 .getHostCharsetName(), getCobolContext()
81 .getAlphanumPaddingChar(), getCobolContext()
82 .failOnAlphanumOverflow(), ce.getItemByteLength(),
83 ce.isJustifiedRight(), hostTarget, newOffset);
84 }
85 } catch (CobolConversionException e) {
86 throwHostException(ce, e);
87 }
88 return newOffset;
89 }
90
91
92 public int fromHost(final ICobolStringBinding ce, final byte[] hostSource,
93 final int offset) throws HostException {
94 int newOffset = offset;
95 try {
96 String javaString = fromHostSingle(getCobolContext()
97 .getHostCharsetName(), ce.getByteLength(), hostSource,
98 newOffset);
99 ce.setStringValue(javaString);
100 newOffset += ce.getByteLength();
101 } catch (CobolConversionException e) {
102 throwHostException(ce, e);
103 }
104 return newOffset;
105 }
106
107
108 public int fromHost(final ICobolArrayStringBinding ce,
109 final byte[] hostSource, final int offset, final int currentOccurs)
110 throws HostException {
111 List < String > lArray = new ArrayList < String >();
112 int newOffset = offset;
113 try {
114 for (int i = 0; i < currentOccurs; i++) {
115 String javaString = fromHostSingle(getCobolContext()
116 .getHostCharsetName(), ce.getItemByteLength(),
117 hostSource, newOffset);
118 lArray.add(javaString);
119 newOffset += ce.getItemByteLength();
120 }
121 ce.setStringList(lArray);
122 } catch (CobolConversionException e) {
123 throwHostException(ce, e);
124 }
125 return newOffset;
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 public static final int toHostSingle(final String javaString,
146 final String hostCharsetName, final Byte paddingChar,
147 final int cobolByteLength, final boolean isJustifiedRight,
148 final byte[] hostTarget, final int offset)
149 throws CobolConversionException {
150 return toHostSingle(javaString, hostCharsetName, paddingChar, false,
151 cobolByteLength, isJustifiedRight, hostTarget, offset);
152 }
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173 public static final int toHostSingle(final String javaString,
174 final String hostCharsetName, final Byte paddingChar,
175 final boolean failOnOverflow, final int cobolByteLength,
176 final boolean isJustifiedRight, final byte[] hostTarget,
177 final int offset) throws CobolConversionException {
178
179
180 int lastOffset = offset + cobolByteLength;
181 if (lastOffset > hostTarget.length) {
182 throw (new CobolConversionException(
183 "Attempt to write past end of host source buffer",
184 new HostData(hostTarget), offset, cobolByteLength));
185 }
186
187
188 byte[] hostSource = new byte[0];
189 byte padChar;
190
191
192
193
194
195 if (isBinaryContent(javaString)) {
196 padChar = (paddingChar == null) ? 0x0 : paddingChar;
197 hostSource = HostData.toByteArray(javaString.substring(2));
198 } else {
199 try {
200 padChar = (paddingChar == null) ? " ".getBytes(hostCharsetName)[0]
201 : paddingChar;
202 if (javaString != null) {
203 hostSource = javaString.getBytes(hostCharsetName);
204 }
205 } catch (UnsupportedEncodingException e) {
206 throw new CobolConversionException(
207 "UnsupportedEncodingException:" + e.getMessage());
208 }
209 }
210
211
212
213
214
215 if (failOnOverflow && hostSource.length > cobolByteLength) {
216 throw new CobolConversionException(
217 "Java string content too long for target COBOL alphanumeric data item");
218 }
219
220
221
222
223
224 int leftPadIndex = offset;
225 int rightPadIndex = lastOffset;
226
227 if (hostSource.length < cobolByteLength) {
228 if (isJustifiedRight) {
229 leftPadIndex = offset + cobolByteLength - hostSource.length;
230 } else {
231 rightPadIndex = lastOffset - 1 - cobolByteLength
232 + hostSource.length;
233 }
234 }
235
236 int iSource = 0;
237 for (int iTarget = offset; iTarget < lastOffset; iTarget++) {
238 if (iTarget < leftPadIndex || iTarget > rightPadIndex) {
239 hostTarget[iTarget] = padChar;
240 } else {
241 hostTarget[iTarget] = hostSource[iSource];
242 iSource++;
243 }
244 }
245
246 return lastOffset;
247
248 }
249
250
251
252
253
254
255
256 private static boolean isBinaryContent(final String javaString) {
257 if (javaString != null && javaString.length() > 2
258 && javaString.charAt(0) == '0') {
259 Matcher matcher = BINARY_CONTENT_PATTERN.matcher(javaString);
260 if (matcher.matches()) {
261 return true;
262 }
263 }
264 return false;
265 }
266
267
268
269
270
271
272
273
274
275
276
277 public static final String fromHostSingle(final String hostCharsetName,
278 final int cobolByteLength, final byte[] hostSource, final int offset)
279 throws CobolConversionException {
280
281 String javaString = null;
282 int javaStringLength = cobolByteLength;
283
284
285
286
287
288
289
290 int lastOffset = offset + cobolByteLength;
291 if (lastOffset > hostSource.length) {
292 if (offset >= hostSource.length) {
293 return javaString;
294 } else {
295 javaStringLength = hostSource.length - offset;
296 }
297 }
298
299
300
301
302
303 try {
304
305 int i = javaStringLength;
306 while (i > 0 && (hostSource[offset + i - 1] == 0)) {
307 i--;
308 }
309 javaStringLength = i;
310
311 javaString = new String(hostSource, offset, javaStringLength,
312 hostCharsetName);
313
314
315
316
317
318 if (javaString.indexOf("\0") != -1) {
319 javaString = javaString.replace('\0', ' ');
320 }
321
322
323 int end = javaString.length();
324 while ((end != 0)
325 && Character.isWhitespace(javaString.charAt(end - 1))) {
326 end--;
327 }
328
329 return javaString.substring(0, end);
330 } catch (UnsupportedEncodingException uee) {
331 throw new CobolConversionException("UnsupportedEncodingException:"
332 + uee.getMessage());
333 }
334
335 }
336
337 }