summaryrefslogtreecommitdiffstats
path: root/src/cepis-csv.cob
diff options
context:
space:
mode:
Diffstat (limited to 'src/cepis-csv.cob')
-rw-r--r--src/cepis-csv.cob124
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.