Class ByteScan

java.lang.Object
dev.relism.flash.bytes.ByteScan

public final class ByteScan extends Object
The single home for protocol-neutral byte scanning: single-byte search, the four-byte \r\n\r\n header-terminator search (SWAR-accelerated), case-insensitive comparison, comma-separated token-list scanning (Connection: a, b, c), RFC 9110 tchar validation, and the case-insensitive header-name hash Http1HeaderMap's

Every method here is static and allocates nothing. Every SWAR method has a plain scalar counterpart (*Scalar) that exists for two reasons: it is what the tests use as the correctness oracle (property-tested against the SWAR version on randomized inputs — see ByteScanTest/ByteScanFuzzTest), and it is the documented fallback if a future measurement ever shows the SWAR path is not worth its complexity on some path (none has been

The SWAR technique used throughout

Both indexOf(byte[], int, int, byte) and indexOfCrLfCrLf(byte[], int, int) use the classic "does this word contain byte b" bit trick (Bit Twiddling Hacks, "Determine if a word has a byte equal to n"): XOR the 8-byte word against b broadcast into every lane (turning matching lanes to 0x00), then test for any zero lane with (v - 0x0101010101010101L) & ~v & 0x8080808080808080L — non-zero exactly when some lane was 0x00 before the subtraction, i.e. some original lane equalled b. This finds *that a* matching lane exists in one word-sized read plus a handful of ALU ops, touching every byte only once per 8-byte stride in the common (no-match-yet) case, instead of once per byte.

Reading the word uses MethodHandles.byteArrayViewVarHandle(java.lang.Class<?>, java.nio.ByteOrder) with ByteOrder.nativeOrder() — deliberately native rather than a fixed order (contrast fpr-core's ByteCompare, which fixes LITTLE_ENDIAN because it compares two independently-read words for bit-exact equality and so needs a byte order both reads agree on; nothing here compares across two separately-decoded words, so the fastest order for the host CPU is free to use). Byte-equality detection itself (finding that a matching lane exists in the mask) does not depend on which order was used to assemble the word — XOR and the haszero test are lane-wise operations, indifferent to how lanes map to memory offsets. Position extraction does depend on it: converting "which bit of the 64-bit mask is set" back into "which array index did that byte come from" requires knowing whether array byte 0 became the long's least-significant byte (little-endian) or most-significant byte (big-endian) — laneIndexOf(long) branches on NATIVE_IS_LITTLE once, at class-init time, precisely to get this right on either host.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final long
    Sentinel returned by parseDecimalStrict(byte[], int, int) on any malformed or out-of-range input.
  • Method Summary

    Modifier and Type
    Method
    Description
    static boolean
    equalsIgnoreCase(dev.relism.fpr.core.ByteView view, int start, int end, String target)
    Case-insensitive (ASCII) equality of view[start, end) against target.
    static boolean
    equalsIgnoreCaseAscii(byte[] a, int aStart, int aLen, byte[] b, int bStart, int bLen)
    Case-insensitive (ASCII) equality of two byte-array ranges.
    static boolean
    equalsIgnoreCaseAscii(byte[] buf, int start, int end, String target)
    Case-insensitive (ASCII) equality of buf[start, end) against target.
    static int
    hashNameIgnoreCaseAscii(byte[] buf, int start, int len)
    Case-insensitive (ASCII fold) 32-bit FNV-1a hash of buf[start, start + len).
    static int
    Same hash as hashNameIgnoreCaseAscii(byte[], int, int), computed directly from a lookup-key String (e.g.
    static int
    indexOf(byte[] buf, int from, int to, byte target)
    Index of the first occurrence of target in buf[from, to), or -1.
    static int
    indexOfCrLfCrLf(byte[] buf, int from, int to)
    Index of the first "\r\n\r\n" in buf[from, to), or -1.
    static boolean
    isTChar(byte b)
    Whether b is a valid RFC 9110 §5.6.2 tchar (a legal header-name byte).
    static long
    parseDecimalStrict(byte[] buf, int start, int end)
    Strict, overflow-safe unsigned decimal parse of buf[start, end): rejects an empty range, any non-'0'..'9' byte, more than 19 digits, and arithmetic overflow past Long.MAX_VALUE.
    static long
    parseHexStrict(byte[] buf, int start, int end, int maxDigits)
    Parses up to maxDigits hex digits (ASCII, either case) from buf[start, end) as an unsigned value.
    static boolean
    tokenEqualsIgnoreCase(dev.relism.fpr.core.ByteView view, int start, int end, String token)
    Case-insensitive compare of view[start, end), trimming trailing spaces, against token.
    static boolean
    tokenListContains(dev.relism.fpr.core.ByteView view, String token)
    Whether the comma-separated, OWS-tolerant token list view contains token (case-insensitive).

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Method Details

    • isTChar

      public static boolean isTChar(byte b)
      Whether b is a valid RFC 9110 §5.6.2 tchar (a legal header-name byte).
    • indexOf

      public static int indexOf(byte[] buf, int from, int to, byte target)
      Index of the first occurrence of target in buf[from, to), or -1. SWAR-accelerated: touches 8 bytes per word while no match has been found, falling back to a byte-at-a-time tail once fewer than 8 bytes remain.
    • indexOfCrLfCrLf

      public static int indexOfCrLfCrLf(byte[] buf, int from, int to)
      Index of the first "\r\n\r\n" in buf[from, to), or -1. SWAR pre-filter (find a candidate CR byte 8 at a time) plus a cheap scalar 3-byte verify at each candidate — see the class Javadoc for the technique and
    • equalsIgnoreCaseAscii

      public static boolean equalsIgnoreCaseAscii(byte[] buf, int start, int end, String target)
      Case-insensitive (ASCII) equality of buf[start, end) against target.
    • equalsIgnoreCaseAscii

      public static boolean equalsIgnoreCaseAscii(byte[] a, int aStart, int aLen, byte[] b, int bStart, int bLen)
      Case-insensitive (ASCII) equality of two byte-array ranges.
    • equalsIgnoreCase

      public static boolean equalsIgnoreCase(dev.relism.fpr.core.ByteView view, int start, int end, String target)
      Case-insensitive (ASCII) equality of view[start, end) against target.
    • tokenListContains

      public static boolean tokenListContains(dev.relism.fpr.core.ByteView view, String token)
      Whether the comma-separated, OWS-tolerant token list view contains token (case-insensitive). The shared scanner behind both Http1KeepAlive.isKeepAlive and drift apart the way a whole-value equals check once did.
    • tokenEqualsIgnoreCase

      public static boolean tokenEqualsIgnoreCase(dev.relism.fpr.core.ByteView view, int start, int end, String token)
      Case-insensitive compare of view[start, end), trimming trailing spaces, against token.
    • hashNameIgnoreCaseAscii

      public static int hashNameIgnoreCaseAscii(byte[] buf, int start, int len)
      Case-insensitive (ASCII fold) 32-bit FNV-1a hash of buf[start, start + len). Used by Http1HeaderMap's per-request index to compare a cheap hash before falling back to a full case-insensitive memcmp-equivalent (equalsIgnoreCaseAscii(byte[], int, int, java.lang.String)) — two header names that differ anywhere hash differently with overwhelming probability, so the common "not the header I'm looking for" case resolves in one hash compare instead of a byte-by-byte scan.
    • hashNameIgnoreCaseAscii

      public static int hashNameIgnoreCaseAscii(String name)
      Same hash as hashNameIgnoreCaseAscii(byte[], int, int), computed directly from a lookup-key String (e.g. "Content-Type") instead of already-scanned bytes — the two must agree bit-for-bit on equivalent ASCII content for Http1HeaderMap's index (hash the request-declared bytes once at reset(); hash the caller's lookup key once per first()/all() call; compare the two cheap hashes before ever touching a full case-insensitive comparison).
    • parseDecimalStrict

      public static long parseDecimalStrict(byte[] buf, int start, int end)
      Strict, overflow-safe unsigned decimal parse of buf[start, end): rejects an empty range, any non-'0'..'9' byte, more than 19 digits, and arithmetic overflow past Long.MAX_VALUE. Returns PARSE_INVALID rather than throwing — the same shape RequestParser's own Content-Length parser already hand-rolls (kept separate there since it also needs to throw a specific, differently-worded MalformedRequestException per failure mode); this is the general-purpose version for callers (HPACK integer decoding, frame-length fields) that just need a valid/invalid signal.
    • parseHexStrict

      public static long parseHexStrict(byte[] buf, int start, int end, int maxDigits)
      Parses up to maxDigits hex digits (ASCII, either case) from buf[start, end) as an unsigned value. Returns PARSE_INVALID if the range is empty, contains a non-hex-digit byte, or would need more than maxDigits digits to represent (the caller's bound against, e.g., a chunk-size line with an implausible number of digits).