Usually we can use three solutions to transcode a EBCDIC to ASCII when rehost a mainframe dataset to an open system.
1. using COBOL INSPECT command.
2. using Intrinsic function ORD, and move char buffer
3. using an external C function.
But finally, the performance result is 3 > 2 > 1; see
[Linux Host]$ make clean && make && time cobrun TRANSCODE
real 2m47.512s real 0m24.274s real 0m2.135s
user 2m45.087s > user 0m23.801s > user 0m2.093s
sys 0m0.078s sys 0m0.036s sys 0m0.017s
Following the programs I used to verify the result (Linux + MF):
[Linux Host]$ ls -1
ctranscode.c
makefile
TRANSCODE.cbl
[Linux Host]$ cat -n makefile
1
2 all: TRANSCODE.gnt ctranscode.so
3
4 TRANSCODE.gnt: TRANSCODE.cbl
5 cob -u $<
6
7 ctranscode.so: ctranscode.c
8 cob -z $<
9
10 clean:
11 -rm -rf *.o *.int *.idy *.gnt *.so
12
[Linux Host]$ cat -n TRANSCODE.cbl
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. TRANSCODE.
3
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6
7 DATA DIVISION.
8 WORKING-STORAGE SECTION.
9
10 01 TRANSCODE-SOURCE.
11 02 FILLER PIC X(16) VALUE X"000102030405060708090a0b0c0d0e0f".
12 02 FILLER PIC X(16) VALUE X"101112131415161718191a1b1c1d1e1f".
13 02 FILLER PIC X(16) VALUE X"202122232425262728292a2b2c2d2e2f".
14 02 FILLER PIC X(16) VALUE X"303132333435363738393a3b3c3d3e3f".
15 02 FILLER PIC X(16) VALUE X"404142434445464748494a4b4c4d4e4f".
16 02 FILLER PIC X(16) VALUE X"505152535455565758595a5b5c5d5e5f".
17 02 FILLER PIC X(16) VALUE X"606162636465666768696a6b6c6d6e6f".
18 02 FILLER PIC X(16) VALUE X"707172737475767778797a7b7c7d7e7f".
19 02 FILLER PIC X(16) VALUE X"808182838485868788898a8b8c8d8e8f".
20 02 FILLER PIC X(16) VALUE X"909192939495969798999a9b9c9d9e9f".
21 02 FILLER PIC X(16) VALUE X"a0a1a2a3a4a5a6a7a8a9aaabacadaeaf".
22 02 FILLER PIC X(16) VALUE X"b0b1b2b3b4b5b6b7b8b9babbbcbdbebf".
23 02 FILLER PIC X(16) VALUE X"c0c1c2c3c4c5c6c7c8c9cacbcccdcecf".
24 02 FILLER PIC X(16) VALUE X"d0d1d2d3d4d5d6d7d8d9dadbdcdddedf".
25 02 FILLER PIC X(16) VALUE X"e0e1e2e3e4e5e6e7e8e9eaebecedeeef".
26 02 FILLER PIC X(16) VALUE X"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff".
27 01 TRANSCODE-TARGET.
28 02 FILLER PIC X(16) VALUE X"000102039c09867f978d8e0b0c0d0e0f".
29 02 FILLER PIC X(16) VALUE X"101112139d0a08871819928f1c1d1e1f".
30 02 FILLER PIC X(16) VALUE X"808182838485171b88898a8b8c050607".
31 02 FILLER PIC X(16) VALUE X"309116939495960498999a9b14159e1a".
32 02 FILLER PIC X(16) VALUE X"20a0e2e4e0e1e3e5e7f15b2e3c282b21".
33 02 FILLER PIC X(16) VALUE X"26e9eaebe8edeeefecdf5d242a293b5e".
34 02 FILLER PIC X(16) VALUE X"2d2fc2c4c0c1c3c5c7d1a62c255f3e3f".
35 02 FILLER PIC X(16) VALUE X"f8c9cacbc8cdcecfcc603a2340273d22".
36 02 FILLER PIC X(16) VALUE X"d8616263646566676869abbbf0fdfeb1".
37 02 FILLER PIC X(16) VALUE X"b06a6b6c6d6e6f707172aabae6b8c6a4".
38 02 FILLER PIC X(16) VALUE X"b57e737475767778797aa1bfd0dddeae".
39 02 FILLER PIC X(16) VALUE X"a2a3a5b7a9a7b6bcbdbeac7cafa8b4d7".
40 02 FILLER PIC X(16) VALUE X"7b414243444546474849adf4f6f2f3f5".
41 02 FILLER PIC X(16) VALUE X"7d4a4b4c4d4e4f505152b9fbfcf9fa9f".
42 02 FILLER PIC X(16) VALUE X"5cf7535455565758595ab2d4d6d2d3d5".
43 02 FILLER PIC X(16) VALUE X"30313233343536373839b3dbdcd9daff".
44
45 78 LOOP-COUNT VALUE 60000.
46 78 INPUT-SIZE VALUE 8192.
47 01 INPUT-BUFFER PIC X(INPUT-SIZE).
48
49 01 I1 PIC 9(4) COMP-5 VALUE 0.
50 01 I2 PIC 9(4) COMP-5 VALUE 0.
51
52 PROCEDURE DIVISION.
53 P-START.
54 * *INITIALIZE INPUT-BUFFER
55 * *WE FAKED ABOVE MAPPING TABLE TRANSCODE-TARGET, SO THAT
56 * *CHAR X"F0" WAS TRANSCODED TO "0", AND
57 * *CHAR "0" WAS TRANSCODED TO "0" EITHER
58 PERFORM VARYING I1 FROM 1 BY 1 UNTIL I1 > INPUT-SIZE
59 MOVE X"F0" TO INPUT-BUFFER(I1:1)
60 END-PERFORM.
61
62 * *PICK UP OPTIONS HERE
63 PERFORM VARYING I2 FROM 1 BY 1 UNTIL I2 > LOOP-COUNT
64 PERFORM USE_EXTERNALC *> use external c function
65 * PERFORM USE_INTRINSIC *> use Intrinsic COBOL function ORD
66 * PERFORM USE_INSPECT *> use INSPECT COBOL command
67 END-PERFORM.
68
69 DISPLAY INPUT-BUFFER.
70 DISPLAY "PLEASE CHECK ABOVE VALUE MUST BE ALWAYS CHAR('0')".
71 DISPLAY "EXIT SIMPLE".
72 STOP RUN.
73
74 USE_EXTERNALC.
75 CALL 'ctranscode' USING TRANSCODE-TARGET
76 INPUT-BUFFER
77 BY VALUE INPUT-SIZE.
78
79 USE_INTRINSIC.
80 PERFORM VARYING I1 FROM 1 BY 1 UNTIL I1 > INPUT-SIZE
81 MOVE TRANSCODE-TARGET(
82 FUNCTION ORD(INPUT-BUFFER(I1:1)) : 1)
83 TO INPUT-BUFFER(I1:1)
84 END-PERFORM.
85
86 USE_INSPECT.
87 INSPECT INPUT-BUFFER(1:INPUT-SIZE)
88 CONVERTING TRANSCODE-SOURCE TO TRANSCODE-TARGET.
[Linux Host]$ cat -n ctranscode.c
1 #include
2
3 /**
4 * This function is used to convert EBCDIC to ASCII
5 *
6 * @param mapping the mapping table how EBCDIC is mapped, if it's NULL DEFAULT_MAPPING is used
7 * @param buffer to be converted
8 * @param len buffer size
9 */
10 void ctranscode(const unsigned char mapping[], unsigned char buffer[], unsigned int len)
11 {
12 unsigned int i = 0;
13 if (buffer != NULL) {
14 for (i = 0; i < len; i++) {
15 buffer[i] = mapping[buffer[i]];
16 }
17 }
18 }