diff options
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 64 |
1 files changed, 63 insertions, 1 deletions
@@ -37,6 +37,16 @@ make install PREFIX=/usr/local Link with `-lcepis -lcurl`. Requires libcurl's headers only for the build of your own program (this library ships no curl types in its header). +> **0.2.0 changed `sizeof(cepis_error)`** — it grew a `faixa` member, from 272 +> to 384 bytes. The source API is unchanged, but a program built against +> 0.1.0 must be recompiled, not just relinked. While the version starts with +> a `0`, that is the promise: source compatibility, not binary. +> +> The soname went with it, `libcepis.so.0` to `libcepis.so.1`. Callers declare +> `cepis_error` on their own stack, so an old binary against the new library +> would have it written past its end — a silent corruption. The soname bump +> turns that into an honest "not found" from the loader instead. + ## Usage ### A single lookup @@ -60,7 +70,7 @@ case CEPIS_OK: cepis_address_free(a); break; case CEPIS_ERR_NOT_FOUND: - break; + break; /* err.faixa may name the municipality - see Errors */ default: fprintf(stderr, "%s\n", err.message); } @@ -201,6 +211,55 @@ to make**, not by the HTTP status that caused it: Pass a `cepis_error` to get `message`, `http_status` and `retry_after`; `cepis_strerror` names the status itself. +### Not found: which city was it? + +A CEP that fails is rarely a random number. It is usually someone who knows +the city and guessed the last digits, and the classic guess is the `-000` that +957 municipalities never received. So a 404 carries an optional `faixa` +naming the municipality that owns the band the number falls in, and +`cepis_lookup` copies it into `err.faixa`: + +```c +if (cepis_lookup(NULL, "25845-000", &a, &err) == CEPIS_ERR_NOT_FOUND) { + fprintf(stderr, "%s\n", err.message); + /* CEP 25845000 does not exist in the DNE database + (Areal/RJ has 118 CEPs, the lowest 25845001 and the highest + 25849899) */ + + if (err.faixa.present) { + err.faixa.localidade; /* "Areal" */ + err.faixa.uf; /* "RJ" */ + err.faixa.cep_ini; /* "25845001" */ + err.faixa.cep_fim; /* "25849899" */ + err.faixa.ceps; /* 118 */ + } +} +``` + +**It is still a 404.** `faixa` is context for a failure, never an address, and +the status stays `CEPIS_ERR_NOT_FOUND`. Everything in it is inline storage +inside the `cepis_error` you already own: nothing to free, nothing that can be +`NULL`. + +Three things about the numbers: + +- `cep_ini` and `cep_fim` are the **smallest and largest CEP that actually + exist** there, not the band the Correios publish. Areal's published band + starts at 25845000 — exactly the CEP that just failed — while `cep_ini` is + 25845001. +- **The band is sparse.** Those 118 CEPs are scattered over the ~4900 numbers + between the two endpoints. `ceps` is a count; the pair is a pair of + endpoints. Do not show it as a range of valid CEPs and do not iterate it. +- The API **omits** `faixa`, and never sends it as null, when the number falls + in a band no municipality owns. Then `present` is 0, the strings are `""`, + `ceps` is 0, and `message` is exactly what it has always been. + +`err.faixa` is reset by every call that receives the `cepis_error`, so a band +left over from a previous 404 cannot be read as this one's. The other keys the +API sends inside `faixa` — `estado`, `regiao`, `ibge` — are not modelled here; +`cepis_lookup_many` never fills `faixa` at all, since the CSV endpoint behind +it does not carry one. + `CEPIS_ERR_INVALID_RESPONSE` almost always means something between you and the API is answering instead of it — a captive Wi-Fi portal, a corporate proxy, an HTML error page. Useful as a diagnosis: the problem is not in your code. @@ -222,6 +281,9 @@ HTML error page. Useful as a diagnosis: the problem is not in your code. unknown fields of any shape, and decodes `\uXXXX` including surrogate pairs. It is not a general-purpose JSON parser and does not build a document tree — `raw` is there for anything it does not model. +- It reaches exactly one level into a nested object, and only for the two the + API defines: `geo` on a 200 and `faixa` on a 404. Either one arriving as + something other than an object is dropped, not an error. ## Development |