comparison dowa/d_string.c @ 260:1f9877b637e9

Add Copilot-powered cyberpunk JRPG chat Integrate the production JRPG chat with Seobeo streaming, Deita persistence, and a Bazel-managed Copilot SDK and LiteLLM inference stack. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <mrjunejune@users.noreply.github.com>
date Wed, 05 Aug 2026 09:19:41 -0700
parents a2720eac50ce
children 04fee26ecce0
comparison
equal deleted inserted replaced
259:667156fcd3e3 260:1f9877b637e9
176 return NULL; 176 return NULL;
177 177
178 (*pos)++; 178 (*pos)++;
179 int32 start = *pos; 179 int32 start = *pos;
180 180
181 while (*pos < len && json[*pos] != '"') 181 while (*pos < len)
182 {
183 if (json[*pos] == '\\' && *pos + 1 < len)
184 {
185 *pos += 2;
186 continue;
187 }
188 if (json[*pos] == '"')
189 break;
182 (*pos)++; 190 (*pos)++;
191 }
183 192
184 int32 slen = *pos - start; 193 int32 slen = *pos - start;
185 char *str = arena ? Dowa_Arena_Allocate(arena, slen + 1) : malloc(slen + 1); 194 char *str = arena ? Dowa_Arena_Allocate(arena, slen + 1) : malloc(slen + 1);
186 if (!str) return NULL; 195 if (!str) return NULL;
187 196
408 Dowa_JSON_Value *val = Dowa_JSON_Get(map, key); 417 Dowa_JSON_Value *val = Dowa_JSON_Get(map, key);
409 if (!val || val->type != DOWA_JSON_BOOL) 418 if (!val || val->type != DOWA_JSON_BOOL)
410 return FALSE; 419 return FALSE;
411 return val->bool_val; 420 return val->bool_val;
412 } 421 }
422
423 char *Dowa_JSON_Escape_String(
424 const char *value,
425 size_t length,
426 Dowa_Arena *p_arena)
427 {
428 if (!value || !p_arena)
429 return NULL;
430 if (length == 0)
431 length = strlen(value);
432
433 if (length > (((size_t)-1) - 1) / 6)
434 return NULL;
435 char *escaped = Dowa_Arena_Allocate(p_arena, length * 6 + 1);
436 if (!escaped)
437 return NULL;
438
439 static const char hex[] = "0123456789abcdef";
440 size_t output = 0;
441 for (size_t i = 0; i < length; i++)
442 {
443 uint8 c = (uint8)value[i];
444 switch (c)
445 {
446 case '"': escaped[output++] = '\\'; escaped[output++] = '"'; break;
447 case '\\': escaped[output++] = '\\'; escaped[output++] = '\\'; break;
448 case '\b': escaped[output++] = '\\'; escaped[output++] = 'b'; break;
449 case '\f': escaped[output++] = '\\'; escaped[output++] = 'f'; break;
450 case '\n': escaped[output++] = '\\'; escaped[output++] = 'n'; break;
451 case '\r': escaped[output++] = '\\'; escaped[output++] = 'r'; break;
452 case '\t': escaped[output++] = '\\'; escaped[output++] = 't'; break;
453 default:
454 if (c < 0x20)
455 {
456 escaped[output++] = '\\';
457 escaped[output++] = 'u';
458 escaped[output++] = '0';
459 escaped[output++] = '0';
460 escaped[output++] = hex[c >> 4];
461 escaped[output++] = hex[c & 0x0f];
462 }
463 else
464 {
465 escaped[output++] = (char)c;
466 }
467 break;
468 }
469 }
470 escaped[output] = '\0';
471 return escaped;
472 }