Commit Graph
15 Commits
Author SHA1 Message Date
Brad ArantandClaude Sonnet 5 5b6d4ea8ab Fix ambiguous MString << JString::Proxy overload resolution
JString::Proxy offers several implicit conversion operators (ZString,
MString, std::string, double, bool) so a single $[...]-style access can
be used wherever any of those types is expected. That flexibility made
"MString << Proxy" genuinely ambiguous: operator ZString() and
operator MString() (via its own implicit upcast to ZString) both satisfy
MString::operator<<(ZString), and operator double()/operator bool() both
satisfy MString::operator<<(int) via a standard numeric conversion, so
the compiler had no basis to prefer one conversion path over another.

Fixed the same way Proxy already solves this exact problem for
std::cout << proxy - a dedicated friend operator<<(MString&, const
Proxy&) that needs no conversion at all, so it's always the preferred
candidate. Verified by actually running testing/jstring_test.cpp (not
just compiling it) - the line that used to fail to compile now correctly
prints "this is a test: this is a comment".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 15:11:56 -07:00
Brad Arant 28feaff3d7 Rewrite JString for real JSON compliance
The previous implementation was a narrow path-accessor, not a JSON parser:
numbers/booleans/null were unhandled entirely (self-acknowledged by a
// TODO: Handle numbers... comment), string escape sequences were never
encoded or decoded, updating an existing non-string-valued key threw a
hard-coded Fix me exception, and skipping past an uninteresting key threw
Unrecognized data type for anything but string/array/object. Full
analysis given to the user before this rewrite; nothing here was guessed.

Added:
- JSONType enum + getType()/exists()/isNull() for type introspection.
- Typed read access: getString() (escape-decoded), getNumber(), getInt(),
  getBool() - each validates the value at the path is actually that type.
- Typed write access: setString() (escapes automatically), setNumber(),
  setInt(), setBool(), setNull() - and Proxy operator= overloads for
  double/int/long/bool so  produces a real JSON number, not
  a quoted string the way the old single MString-typed operator= did.
- jsonEscape()/jsonUnescape(): full escape codec including \uXXXX and
  UTF-16 surrogate pairs (astral characters, e.g. emoji) decoded to
  correct UTF-8.
- skipValue()/skipString()/skipContainer()/skipNumber() and their
  capture (span-returning) counterparts: escape-aware structural
  skipping, so a string value containing a literal { } [ ] , or : can
  no longer desync object/array nesting depth - this affected both
  locate()s internal key-skipping and find()s array/object extraction
  (the latter still relied on the base ZString::getContainer(), which
  has this exact bug and was not touched - see the ZString commit in
  this same session - so a JString-specific escape-aware capture was
  added instead of depending on it for this purpose).
- set() rewritten to use skipValue() to correctly locate and replace an
  EXISTING values full span regardless of its current type, instead of
  only handling the case where the existing value was already a quoted
  string.

Bugs found and fixed along the way, surfaced by writing real tests
against realistic JSON rather than just getting it to compile:
- The array-index-then-further-path case (e.g. b[2].c) always returned
  true immediately after reaching the index, so any path segment past
  the index was silently ignored - dead code after an unconditional
  return/throw meant the intended continuation logic could never run.
- The array selector syntax (label[key=value]) was only reachable as a
  top-level special case, never as part of a normal nested path (e.g.
  items[id=x].val) - unified both under the same bracket handling.
- Once reachable, the selector-match subkey check (find(key) on each
  array element) always searched from the document root, not the
  current array element, because find() unconditionally calls reset().
  Split into public find() (resets) and internal findRelative() (does
  not), and pointed both selector-matching call sites at the latter.
- path[0].getTokenExclude(...) in the array-selector path parser
  indexed into a list vector that split() never populated - undefined
  behavior. Removed the erroneous [0].

Verified via a dedicated test program (not included in this commit)
covering: string escape round-trip, numbers, booleans, null, exists(),
\uXXXX including a real surrogate pair decoded to correct 4-byte UTF-8,
nested dotted+bracketed navigation, a string value containing every
structural JSON character, replacing an existing key with a different
type, multi-key documents, pretty() not corrupting structural characters
inside a string, and the array selector syntax on both a matching first
and second element - 30/30 assertions pass. Full CoreUtils compile pass
unchanged apart from JString.cpp itself now succeeding (14/20 clean, same
7 pre-existing StreamReader.h-blocked failures as always, nothing new
broken).
2026-08-22 20:53:54 -07:00
barant 10df4a6a99 added changed event handler. 2024-12-18 11:26:58 -08:00
barant 7eb2417456 added a pretty output to JString. 2024-12-18 09:49:34 -08:00
barant d74fa9689d added a pretty output to JString. Initial. 2024-12-17 16:56:05 -08:00
barant d1e5e41ab2 JString fix to compress initial assignment JSON. 2024-12-17 09:58:56 -08:00
barant 95254310f0 JString fix to compress initial assignment JSON. 2024-12-17 09:56:55 -08:00
barant 0d60cce8dc more serious work on JString. 2024-12-12 12:22:46 -08:00
barant c6e0486c14 Serious work on JString and some minor MString ajustments. 2024-12-11 16:58:34 -08:00
barant 7531c885a7 JString now streams properly. 2024-12-11 09:55:40 -08:00
barant 0baa44d076 messing around with jstring. 2024-12-10 17:10:49 -08:00
Brad Arant d020363bc9 Trying to fix MString assignments. 2023-10-10 15:49:46 -07:00
Brad Arant 74ab316e64 Working flat JString sorta 2023-10-09 19:31:12 -07:00
Brad Arant 8a9c1c3bd7 Worked on ZString, MString and JString 2023-10-05 17:57:01 -07:00
Brad Arant 2a8cfcee2a testing changes and JString 2023-03-08 17:59:53 -08:00