summaryrefslogtreecommitdiffstats
path: root/copy
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-26 12:49:48 -0300
committerMurilo Ijanc <[email protected]>2026-07-26 12:49:48 -0300
commitf979d07d23098b96e758b3feb555cd06d85d9b2d (patch)
tree47298197a17a3d6c438a1f4cc7cb61afd390cf05 /copy
downloadcobol-f979d07d23098b96e758b3feb555cd06d85d9b2d.tar.gz
Initial importv0.1.0
Diffstat (limited to 'copy')
-rw-r--r--copy/cepis-address.cpy41
-rw-r--r--copy/cepis-csv.cpy14
-rw-r--r--copy/cepis-http.cpy17
-rw-r--r--copy/cepis-json.cpy24
-rw-r--r--copy/cepis-status.cpy23
-rw-r--r--copy/cepis.cpy81
6 files changed, 200 insertions, 0 deletions
diff --git a/copy/cepis-address.cpy b/copy/cepis-address.cpy
new file mode 100644
index 0000000..b1e6c35
--- /dev/null
+++ b/copy/cepis-address.cpy
@@ -0,0 +1,41 @@
+*> ---------------------------------------------------------------------
+*> Address layout without its 01 level, so the same definition serves
+*> both the standalone record and the elements of the batch table.
+*>
+*> Include it under an 01 (or under a table entry) and replace the three
+*> tags: the field-name prefix and the two level numbers. cepis.cpy does
+*> exactly that, twice.
+*>
+*> Every text field is a fixed-width PIC X. A value longer than its field
+*> is truncated on the right and the record is flagged; the sizes below
+*> are the documented limits and are repeated in the README.
+*> ---------------------------------------------------------------------
+:L1: :P:-CEP PIC X(8).
+:L1: :P:-CEP-MASKED PIC X(9).
+:L1: :P:-LOGRADOURO PIC X(120).
+:L1: :P:-COMPLEMENTO PIC X(120).
+:L1: :P:-UNIDADE PIC X(80).
+:L1: :P:-BAIRRO PIC X(100).
+:L1: :P:-LOCALIDADE PIC X(100).
+:L1: :P:-UF PIC X(2).
+:L1: :P:-ESTADO PIC X(60).
+:L1: :P:-REGIAO PIC X(30).
+:L1: :P:-IBGE PIC X(10).
+:L1: :P:-GIA PIC X(10).
+:L1: :P:-DDD PIC X(4).
+:L1: :P:-SIAFI PIC X(10).
+:L1: :P:-TRUNCATED PIC X.
+ 88 :P:-WAS-TRUNCATED VALUE "Y".
+ 88 :P:-NOT-TRUNCATED VALUE "N".
+:L1: :P:-GEO.
+ :L2: :P:-GEO-PRESENT PIC X.
+ 88 :P:-GEO-KNOWN VALUE "Y".
+ 88 :P:-GEO-ABSENT VALUE "N".
+ :L2: :P:-GEO-LAT PIC S9(3)V9(6)
+ SIGN IS LEADING SEPARATE.
+ :L2: :P:-GEO-LON PIC S9(3)V9(6)
+ SIGN IS LEADING SEPARATE.
+ :L2: :P:-GEO-RAIO-M PIC 9(9).
+ :L2: :P:-GEO-PRECISAO PIC X(16).
+ 88 :P:-GEO-PRECISE VALUE "logradouro".
+ 88 :P:-GEO-CITY-WIDE VALUE "localidade".
diff --git a/copy/cepis-csv.cpy b/copy/cepis-csv.cpy
new file mode 100644
index 0000000..8ef9599
--- /dev/null
+++ b/copy/cepis-csv.cpy
@@ -0,0 +1,14 @@
+*> ---------------------------------------------------------------------
+*> Control block for CEPIS-CSV-NEXT. Internal.
+*>
+*> Set CSV-LEN once and CSV-POS to 1, then call repeatedly: each call
+*> yields the next field. CSV-ROW-END marks the field that closed the
+*> record, CSV-EXHAUSTED that there was nothing left to read.
+*> ---------------------------------------------------------------------
+01 CEPIS-CSV-SCAN.
+ 05 CSV-POS PIC 9(9).
+ 05 CSV-LEN PIC 9(9).
+ 05 CSV-FIELD PIC X(512).
+ 05 CSV-FIELD-LEN PIC 9(9).
+ 05 CSV-ROW-END PIC X.
+ 05 CSV-EXHAUSTED PIC X.
diff --git a/copy/cepis-http.cpy b/copy/cepis-http.cpy
new file mode 100644
index 0000000..5868ed2
--- /dev/null
+++ b/copy/cepis-http.cpy
@@ -0,0 +1,17 @@
+*> ---------------------------------------------------------------------
+*> Internal layouts shared between CEPIS-REQUEST and its callers. Not
+*> part of the public surface; nothing outside this library needs it.
+*>
+*> HTTP-BODY is fixed at 256 KiB. A response larger than that is reported
+*> as CEPIS-INVALID-RESPONSE rather than being silently cut: 500 CSV rows
+*> come to roughly 60 KiB, so the margin is wide.
+*> ---------------------------------------------------------------------
+01 CEPIS-HTTP-REQUEST.
+ 05 HTTPQ-PATH PIC X(8192).
+ 05 HTTPQ-PATH-LEN PIC 9(9).
+ 05 HTTPQ-ALLOW-503 PIC X.
+
+01 CEPIS-HTTP-RESPONSE.
+ 05 HTTP-STATUS PIC 9(3).
+ 05 HTTP-BODY-LEN PIC 9(9).
+ 05 HTTP-BODY PIC X(262144).
diff --git a/copy/cepis-json.cpy b/copy/cepis-json.cpy
new file mode 100644
index 0000000..05e43ea
--- /dev/null
+++ b/copy/cepis-json.cpy
@@ -0,0 +1,24 @@
+*> ---------------------------------------------------------------------
+*> Control block for CEPIS-JSON-GET. Internal.
+*>
+*> Set JS-FROM and JS-TO to the span of the object to search (JS-FROM on
+*> its opening brace) and JS-KEY to the member wanted. On return JS-TYPE
+*> says what was found:
+*>
+*> S string JS-VALUE holds it, escapes already decoded
+*> N number JS-VALUE holds the literal text, for FUNCTION NUMVAL
+*> O object JS-VSTART and JS-VEND span it; search it in turn
+*> A array likewise
+*> B boolean, Z null
+*> space the key is not in this object
+*> E the text is not a JSON object
+*> ---------------------------------------------------------------------
+01 CEPIS-JSON-SCAN.
+ 05 JS-FROM PIC 9(9).
+ 05 JS-TO PIC 9(9).
+ 05 JS-KEY PIC X(32).
+ 05 JS-TYPE PIC X.
+ 05 JS-VALUE PIC X(1024).
+ 05 JS-VALUE-LEN PIC 9(9).
+ 05 JS-VSTART PIC 9(9).
+ 05 JS-VEND PIC 9(9).
diff --git a/copy/cepis-status.cpy b/copy/cepis-status.cpy
new file mode 100644
index 0000000..75632c8
--- /dev/null
+++ b/copy/cepis-status.cpy
@@ -0,0 +1,23 @@
+*> ---------------------------------------------------------------------
+*> Status layout without its 01 level, so the library can keep a private
+*> scratch status alongside the caller's without duplicating the
+*> definition. Replace the field-name tag and the level number.
+*>
+*> The six failure categories are split by the decision the caller has to
+*> make, not by the HTTP status that produced them.
+*> ---------------------------------------------------------------------
+:L1: :P:-STATUS-CODE PIC 9(2).
+ 88 :P:-OK VALUE 0.
+ 88 :P:-INVALID-CEP VALUE 1.
+ 88 :P:-NOT-FOUND VALUE 2.
+ 88 :P:-RATE-LIMITED VALUE 3.
+ 88 :P:-SERVER-ERROR VALUE 4.
+ 88 :P:-NETWORK-ERROR VALUE 5.
+ 88 :P:-INVALID-RESPONSE VALUE 6.
+ 88 :P:-FAILED VALUE 1 THRU 6.
+ 88 :P:-RETRIABLE VALUE 3 THRU 5.
+:L1: :P:-STATUS-MESSAGE PIC X(200).
+:L1: :P:-STATUS-HTTP PIC 9(3).
+:L1: :P:-STATUS-RETRY-AFTER-MS PIC S9(9)
+ SIGN IS LEADING SEPARATE.
+:L1: :P:-STATUS-ATTEMPTS PIC 9(4).
diff --git a/copy/cepis.cpy b/copy/cepis.cpy
new file mode 100644
index 0000000..59d643c
--- /dev/null
+++ b/copy/cepis.cpy
@@ -0,0 +1,81 @@
+*> ---------------------------------------------------------------------
+*> cepis 0.1.0 -- public data layouts for the cep.is client.
+*>
+*> Copy this into WORKING-STORAGE (callers) or LINKAGE (subprograms).
+*> It defines, in order:
+*>
+*> CEPIS-CONFIG client configuration; fill it with
+*> CALL "CEPIS-DEFAULT-CONFIG" before overriding
+*> CEPIS-STATUS outcome of the last call, with the six error
+*> categories as 88-levels
+*> CEPIS-CEP-INPUT a CEP as the user typed it, masked or not
+*> CEPIS-CEP the same CEP, 8 digits
+*> CEPIS-ADDRESS one address
+*> CEPIS-HEALTH the answer of GET /health
+*> CEPIS-BATCH the batch table, one slot per requested CEP
+*>
+*> Data field names are the API's own, in Portuguese. Everything else in
+*> this library is English.
+*> ---------------------------------------------------------------------
+
+*> Client configuration. CEPIS-DEFAULT-CONFIG fills every field; change
+*> what you need afterwards. CFG-BASE-URL is the one that usually differs
+*> between environments.
+01 CEPIS-CONFIG.
+ 05 CFG-BASE-URL PIC X(200).
+ 05 CFG-TIMEOUT-MS PIC 9(9).
+ 05 CFG-MAX-ATTEMPTS PIC 9(4).
+ 05 CFG-BACKOFF-BASE-MS PIC 9(9).
+ 05 CFG-BACKOFF-MAX-MS PIC 9(9).
+ 05 CFG-TOTAL-TIMEOUT-MS PIC 9(9).
+ 05 CFG-USER-AGENT PIC X(120).
+
+*> Outcome of the last call. Test CEPIS-OK first; the six failure
+*> categories are split by the decision the caller has to make, not by
+*> the HTTP status that produced them. CEPIS-RETRIABLE covers the three
+*> the client already retried on its own before giving up.
+01 CEPIS-STATUS.
+ COPY "cepis-status.cpy" REPLACING
+ ==:P:== BY ==CEPIS== ==:L1:== BY ==05==.
+
+*> A CEP as the caller has it: "01001-000", "01001000" or "01001.000".
+01 CEPIS-CEP-INPUT PIC X(20).
+
+*> The same CEP reduced to its 8 digits by CEPIS-NORMALIZE-CEP.
+01 CEPIS-CEP PIC X(8).
+
+*> One address. Fields the database lacks come back as spaces, never as
+*> a marker value. ADDR-GEO-PRESENT says whether the coordinate exists;
+*> ADDR-GEO-LAT and ADDR-GEO-LON are meaningless when it does not.
+01 CEPIS-ADDRESS.
+ COPY "cepis-address.cpy" REPLACING
+ ==:P:== BY ==ADDR== ==:L1:== BY ==05== ==:L2:== BY ==10==.
+
+*> The answer of GET /health. HEALTH-DEGRADED is not an error: the API
+*> reporting itself unwell is the diagnosis you asked for.
+01 CEPIS-HEALTH.
+ 05 HEALTH-STATUS PIC X(20).
+ 88 HEALTH-OK VALUE "ok".
+ 05 HEALTH-DNE PIC X(20).
+ 05 HEALTH-CEPS PIC 9(12).
+ 05 HEALTH-GEO PIC 9(12).
+ 05 HEALTH-BASE-GERADA-EM PIC X(32).
+
+*> The batch table. Fill BATCH-COUNT and BATCH-REQUESTED for each slot,
+*> then CALL "CEPIS-LOOKUP-MANY". Every slot comes back in place: a CEP
+*> that does not exist, or that is not 8 digits, leaves its slot
+*> BATCH-ENTRY-MISSING. Slots are never removed or shifted.
+*>
+*> Batches carry no coordinate: the endpoint behind them is CSV and the
+*> CSV has no geo column, so BAT-GEO-PRESENT is always "N" here even for
+*> CEPs that do have one. Need the coordinate? Use CEPIS-LOOKUP.
+01 CEPIS-BATCH.
+ 05 BATCH-COUNT PIC 9(4).
+ 05 BATCH-ENTRY OCCURS 1000 TIMES.
+ 10 BATCH-REQUESTED PIC X(20).
+ 10 BATCH-FOUND PIC X.
+ 88 BATCH-ENTRY-FOUND VALUE "Y".
+ 88 BATCH-ENTRY-MISSING VALUE "N".
+ 10 BATCH-ADDRESS.
+ COPY "cepis-address.cpy" REPLACING
+ ==:P:== BY ==BAT== ==:L1:== BY ==15== ==:L2:== BY ==20==.