diff options
Diffstat (limited to 'src/cepis-csv.cob')
| -rw-r--r-- | src/cepis-csv.cob | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/cepis-csv.cob b/src/cepis-csv.cob new file mode 100644 index 0000000..29cc6d2 --- /dev/null +++ b/src/cepis-csv.cob @@ -0,0 +1,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. |