blob: 29cc6d2c85cb670c35d0faca6455b6cda4c5ca07 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
IDENTIFICATION DIVISION.
PROGRAM-ID. CEPIS-CSV-NEXT.
*> ---------------------------------------------------------------------
*> Read one field of an RFC 4180 record.
*>
*> CALL "CEPIS-CSV-NEXT" USING CSV-TEXT CEPIS-CSV-SCAN
*>
*> Values from the batch endpoint contain commas -- "Rua Um, Dois" is an
*> ordinary street name -- and are then double-quoted with "" for an
*> embedded quote. Splitting on commas would shear those rows in two and
*> shift every column after them, so this walks the quoting properly,
*> newlines inside a quoted value included.
*> ---------------------------------------------------------------------
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-C PIC X.
01 WS-DOUBLED PIC X.
01 CONST-QUOTE PIC X VALUE '"'.
LINKAGE SECTION.
01 CSV-TEXT PIC X(262144).
COPY "cepis-csv.cpy".
PROCEDURE DIVISION USING CSV-TEXT CEPIS-CSV-SCAN.
MAIN-START.
MOVE SPACES TO CSV-FIELD
MOVE 0 TO CSV-FIELD-LEN
MOVE "N" TO CSV-ROW-END
MOVE "N" TO CSV-EXHAUSTED
IF CSV-POS > CSV-LEN
MOVE "Y" TO CSV-EXHAUSTED
MOVE "Y" TO CSV-ROW-END
GOBACK
END-IF
IF CSV-TEXT(CSV-POS:1) = CONST-QUOTE
PERFORM READ-QUOTED
ELSE
PERFORM READ-BARE
END-IF
PERFORM CLOSE-FIELD
GOBACK.
*> -------------------------------------------------------------------
READ-QUOTED.
ADD 1 TO CSV-POS
PERFORM UNTIL CSV-POS > CSV-LEN
MOVE CSV-TEXT(CSV-POS:1) TO WS-C
IF WS-C = CONST-QUOTE
MOVE "N" TO WS-DOUBLED
IF CSV-POS < CSV-LEN
IF CSV-TEXT(CSV-POS + 1:1) = CONST-QUOTE
MOVE "Y" TO WS-DOUBLED
END-IF
END-IF
IF WS-DOUBLED = "Y"
PERFORM APPEND-CHAR
ADD 2 TO CSV-POS
ELSE
ADD 1 TO CSV-POS
EXIT PERFORM
END-IF
ELSE
PERFORM APPEND-CHAR
ADD 1 TO CSV-POS
END-IF
END-PERFORM
PERFORM UNTIL CSV-POS > CSV-LEN
MOVE CSV-TEXT(CSV-POS:1) TO WS-C
IF WS-C = "," OR WS-C = X"0D" OR WS-C = X"0A"
EXIT PERFORM
END-IF
ADD 1 TO CSV-POS
END-PERFORM.
*> -------------------------------------------------------------------
READ-BARE.
PERFORM UNTIL CSV-POS > CSV-LEN
MOVE CSV-TEXT(CSV-POS:1) TO WS-C
IF WS-C = "," OR WS-C = X"0D" OR WS-C = X"0A"
EXIT PERFORM
END-IF
PERFORM APPEND-CHAR
ADD 1 TO CSV-POS
END-PERFORM.
*> -------------------------------------------------------------------
CLOSE-FIELD.
IF CSV-POS > CSV-LEN
MOVE "Y" TO CSV-ROW-END
EXIT PARAGRAPH
END-IF
MOVE CSV-TEXT(CSV-POS:1) TO WS-C
EVALUATE TRUE
WHEN WS-C = ","
ADD 1 TO CSV-POS
WHEN WS-C = X"0D"
ADD 1 TO CSV-POS
IF CSV-POS <= CSV-LEN
IF CSV-TEXT(CSV-POS:1) = X"0A"
ADD 1 TO CSV-POS
END-IF
END-IF
MOVE "Y" TO CSV-ROW-END
WHEN WS-C = X"0A"
ADD 1 TO CSV-POS
MOVE "Y" TO CSV-ROW-END
WHEN OTHER
ADD 1 TO CSV-POS
END-EVALUATE.
*> -------------------------------------------------------------------
APPEND-CHAR.
IF CSV-FIELD-LEN < 512
ADD 1 TO CSV-FIELD-LEN
MOVE WS-C TO CSV-FIELD(CSV-FIELD-LEN:1)
END-IF.
END PROGRAM CEPIS-CSV-NEXT.
|