12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- // SPDX-License-Identifier: GPL-2.0 or GPL-3.0
- // Copyright © 2019 Ariadne Devos
- #ifndef _sHT_LEX_IPv4_ADDR
- #define _sHT_LEX_IPv4_ADDR
- #include <sHT/logic/failbit.h>
- /** *Perhaps* a numeric IP address parsed from a string */
- struct s2_ipv4_maybe
- {
- /** The IP address' numeric value
- Byte order: "127.0.0.1" -> 0x7f000001.
- The byte order of 0x7f000001 depends
- on the implementation of C (ABI, CPU). */
- uint32_t ip;
- /* one-past-end last last correct byte,
- -- if not fully parsed, the failbit is set. */
- sHT_with_failbit
- size_t end;
- };
- /** Parse a IPv4 address from an ASCII string into a number.
- The match is made as long as possible!
- If there is not match, `ret.end` is set to the first incorrect
- byte -- non-speculatively, all before were [0-9.] (may be useful
- to reduce backtracking).
- Requires:
- (a): 0 < length < failbit_limit(size_t)
- (* the string, not the buffer, begins at 1 *)
- (b): SliceCap(read ^ set, length, from)
- Definition:
- (RFC 3986, URI: Generic Syntax, 3.2.2 Host, p. 20)
- (* ABNF + regex-capture *)
- IPv4address := (dec-octet) "." (dec-octet) "." (dec-octet) "." (dec-octet)
- (abbreviated) IPv4address = dec-octet ("." dec-octet){3}
- dec-octet := [0-9] / [1-9] [0-9] / "1" [0-9]{2} / "2" [0-4][0-9] / "25" [0-5]
- (* dec-octet is interpreted as a natural < 256 (see <sHT/lex/nat.h>),
- IPv4address is formed by concatenating the `dec-octet`s into a uint32_t.
- *)
- end := maximalise (noexist → 0) {k | 1 ≤ k ≤ length }
- [\0, \1, \2, \3] <- do match IPv4address from 1 length
- value := (mappend . (map (->octet . ->nat)) [\0 .. \3]
- Ensures:
- (v): 0 ≤ fail_value(size_t, ret.end) ≤ length
- (w): nonspec: end ≠ 0 ↔ good(size_t, ret.end)
- (x): nonspec: good(size_t, ret.end) → fail_value(size_t, ret.end) = end
- (y): nonspec: good(size_t, ret.end) → ret.ip = value
- (z): nonspec: ¬good(size_t, ret.end)
- → match [0-9.]* from 1 fail_value(size_t, ret.end) */
- __attribute__((pure))
- struct s2_ipv4_maybe
- s2_parse_ipv4(size_t length, const uint8_t from[length]);
- #endif
|