Libraries developed by Linder Hard- und Software and licensed to the public under LGPL v2.1 Version 2.1: .
  • PureBasic 100%
Find a file
René Linder 079e694f97 LHSLIB-7: RFC-8259 Strictness-Followup (5 Codex-Findings)
Codex-Review 2026-05-17 hat 5 RFC-Luecken identifiziert. Alle gefixt:

Fix #1: UTF-8 Validation (RFC 3629 / RFC 8259 §8.1)
  Neuer _IsValidUtf8(*data, len, *errPos) Helper. Parse() validiert
  jetzt strikt UTF-8 vor _ParseValue. Rejected: overlong-Encodings,
  stray Continuation-Bytes, Surrogates (U+D800..U+DFFF), Codepoints
  > U+10FFFF. Bei Fehler: JSON_ERR_UTF8 + exact Byte-Position.

Fix #2: Builder State-Machine
  Neue _CtxAllowsKey/_CtxAllowsValue/_CtxAllowsObjEnd/_CtxAllowsArrEnd
  Helpers. Builder broken bei:
    - Key* in Array-Context
    - Push* in Object-Context (kein Key)
    - ArrEnd in Object / ObjEnd in Array
    - Mehrfacher Root-Wert (had_root-Flag)
    - End-Operation bei depth=0
  FinalizeToBytes/String + IsValid pruefen jetzt depth=0 UND had_root.

Fix #3: Object-Keys decoded gespeichert (RFC-8259 semantisch)
  Neuer _DecodeRawToArena(*src, len, arena, *out_ptr, *out_len)
  Helper (Escape + Surrogate-Pair-Decoding aus AsString extrahiert).
  _ParseObject dekodiert Keys jetzt beim Parse in die Arena.
  Damit findet ObjectGet(root, "a/b") jetzt Key "a\/b" semantisch.
  KeyString liefert dekodierten String.

Fix #4: Float Non-Finite Rejection
  Neuer _IsFiniteFloat(val) Helper (PB-Trick: val*0.0<>0.0 fuer NaN/Inf).
  KeyFloat/PushFloat setzen broken bei NaN/Infinity statt ungueltiges
  JSON-Token auszugeben.

Fix #5: OOM in _WriteEscaped markiert Builder broken
  Bei AllocateMemory-Failure jetzt *b\broken = #True (vorher: silent
  return mit "key": ohne Value).

Smoke-Tests:
  +20 neue Asserts (Section 15) fuer alle 5 Fixes
  +2 Asserts (Section 10) angepasst (alte laxe Semantik)
  102/102 PASS

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 12:43:00 +02:00
DATA LHSLIB-7: RFC-8259 Strictness-Followup (5 Codex-Findings) 2026-05-17 12:43:00 +02:00
GUI lhs_uuid + lhs_dialog: Rebase als saubere Module 2026-05-16 01:22:23 +02:00
SYS lhs_log_adv: Multi-Producer lock-free Hot-Path-Logger (Phase C) 2026-05-16 04:09:06 +02:00
.gitignore Initial commit 2019-05-20 13:16:18 +02:00
LICENSE Initial commit 2019-05-20 13:16:18 +02:00
README.md Move tests/ to separate lhs_lib_full wrapper repo 2026-05-14 14:28:07 +02:00

lhs_lib

Includes entwickelt und erweitert aus bestehenden Sourcen um PureBasic-Funktionalitäten zu erweitern.

Module

SYS/

Modul Beschreibung C-Backend
lhs_log.pbi / lhs_log_ext.pbi Logging-Modul (single- bzw. multi-threaded Logger) nein
lhs_sys_debug_wrapper.pbi Debug-Wrapper für PB-Default-Debug, lhs_log, lhs_log_ext nein
lhs_uuid.pbi UUID-Generator (v1, v3, v4, v5) nein
lhs_arena.pbi Arena-Allocator mit case-insensitive HashMap und FlatList — Hot-Path-Performance für Result-Sets, HTTP-Header-Maps, Per-Request-Pools ja
lhs_atomic.pbi Lock-free Atomics über GCC builtins (CAS, AtomicLoad/Store, Increment/Decrement, Add, Memory-Barriers) ja
lhs_lockfree_queue.pbi MPMC-bounded Queue (Dmitry-Vyukov-Algorithmus), benötigt lhs_atomic ja

GUI/

Modul Beschreibung
lhs_dialog.pbi Erweiterte Dialog-Bausteine

Tests / Benchmarks

Liegen im separaten Wrapper-Repo lhs_lib_full (lhs_lib selbst eingebunden als Git-Submodule). Enthält:

  • lhs_arena_bench.pb — Performance-Benchmark gegen PB-Native Map/List mit Realworld-Szenarien (HTTP Lifecycle, Mixed Workload, Concurrent, PPQL Result-Sets, Search-Index, Cookie-Parser, Header-Match)
  • lhs_arena_memprof.pb — Memory-Footprint-Profiler (Peak-RSS, Page-Faults)
  • build_csv.sh — Vergleichstabellen-Generator
  • Bench-Outputs für verschiedene Hardware (Ryzen, Xeon X5650, …)

Build-Hinweise

Module mit C-Backend-Pflicht (lhs_arena, lhs_atomic, lhs_lockfree_queue) müssen mit dem PureBasic-C-Backend gebaut werden:

pbcompilerc dein_programm.pb --thread --optimizer --executable dein_programm

Das C-Backend ist auf Linux, macOS, Windows und ARM verfügbar. Der ASM-Backend wird für diese Module nicht unterstützt (GCC-builtin-Atomics und Inline-C-Hotpaths sind C-spezifisch).

Programming recommendations in this collection

Debugging

Es empfiehlt sich, SYS/lhs_sys_debug_wrapper.pbi zu verwenden statt direkt Debug:

Initial:

  Global LoggerUUID.s = ""
  Global Log_Level_Info = 0
  Global Log_Level_Debug = 0
  Global Log_Level_Error = 2

Im Code:

  ldl::Logging("Something on Info Log", LoggerUUID, Log_Level_Info)

Arena (HTTP/PPQL Hot-Path)

Pro Request/Query eine Arena, am Ende Reset (Speicher bleibt für nächsten Cycle wiederverwendbar) oder Destroy:

XIncludeFile "lhs_lib/SYS/lhs_arena.pbi"

Define *arena.lhs_arena::Arena = lhs_arena::Create(65536)

; HashMap mit case-insensitive Key-Vergleich (ideal für HTTP-Header)
Define *headers.lhs_arena::HashMap = lhs_arena::MapCreate(*arena, 32)
lhs_arena::MapSet(*headers, "Content-Type", "text/html")
v.s = lhs_arena::MapGet(*headers, "content-type")    ; → "text/html"

; Zero-UTF-Boundary für Bytes direkt aus Socket-Buffer (HTTP-Parser-Pfad)
lhs_arena::MapSetBytes(*headers, *key_ptr, key_len, *val_ptr, val_len)
*vp = lhs_arena::MapGetBytes(*headers, *key_ptr, key_len, @vlen)

lhs_arena::Reset(*arena)     ; Alles zurück, Chunks behalten
lhs_arena::Destroy(*arena)   ; Alles freigeben

Benchmark-Auszug (Ryzen AI 9 HX 370, 24 Cores) gegen PB-Native bei 100 000 Map-Einträgen:

Test PB-Native Arena Speedup
Map-Lifecycle (Insert + Lookup + Cleanup) 269 ms 27.6 ms 9.7×
Concurrent (1000 Threads × 5k ops, 90% read) 4.62 s 102 ms 45×
PPQL Result-Set 50k Rows × 10 Cols 9.89 s 69 ms 143×
HTTP Header-Match (500 known, Bytes-API) 1.4 µs/op 43 ns/op 32×

Details, X5650-Vergleich und Memory-Footprint: siehe tests/.

Lock-Free Queue (MPMC)

XIncludeFile "lhs_lib/SYS/lhs_atomic.pbi"
XIncludeFile "lhs_lib/SYS/lhs_lockfree_queue.pbi"

Define *q = lhs_lockfree_queue::Create(1024)   ; Power-of-2 capacity

; Producer (mehrere Threads ok)
lhs_lockfree_queue::Push(*q, *work_item)

; Consumer (mehrere Threads ok)
*item = lhs_lockfree_queue::Pop(*q)
If *item
  ; arbeiten ...
EndIf

lhs_lockfree_queue::Free(*q)

Autoren

René Linder [Ground0]

Lizenz

Sofern in den Sourcen nicht anders erwähnt gilt:

SPDX-License-Identifier: LGPL-2.1-or-later OR Commercial