mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-08-31 17:55:23 +02:00
New events, all read-only (never mutate kernel state, no cleanup/sort calls - see HLEKernelObjectSubscriber.cpp's header comment): - hle.object.list: every live kernel object of every type at once (uid, type, name, one-line quickInfo), with an optional 'type' filter. Uses KernelObjectPool::IterateAll(), a new type-agnostic sibling of the existing Iterate<T>(). - hle.eventflag.list/info, hle.mutex.list/info, hle.semaphore.list/info, hle.msgpipe.list/info, hle.callback.list/info: per-type full detail (all Native* status struct fields plus waiting-thread lists), reading straight off the classes exposed in the previous commit. Also adds JsonWriter::DictScope/ArrayScope (Common/Data/Format/JSONWriter.h) - RAII push/pop for pushDict()/pushArray(), used throughout the new handlers. A forgotten or early-returned pop() previously just produced silently malformed JSON; with 11 new handlers each writing a handful of nested arrays/dicts, that seemed worth fixing at the API level rather than trusting every call site to pair things up by hand. Existing handlers are untouched - this is purely additive. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
117 lines
3.2 KiB
C++
117 lines
3.2 KiB
C++
// Minimal-state JSON writer. Consumes almost no memory
|
|
// apart from the string being built-up, which could easily be replaced
|
|
// with a file stream (although I've chosen not to do that just yet).
|
|
//
|
|
// Writes nicely 2-space indented output with correct comma-placement
|
|
// in arrays and dictionaries.
|
|
//
|
|
// Does not deal with encodings in any way.
|
|
//
|
|
// Zero dependencies apart from stdlib (if you remove the vhjson usage.)
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <sstream>
|
|
|
|
struct JsonNode;
|
|
|
|
namespace json {
|
|
|
|
class JsonWriter {
|
|
public:
|
|
JsonWriter(int flags = NORMAL);
|
|
~JsonWriter();
|
|
void begin();
|
|
void beginArray();
|
|
void beginRaw();
|
|
void end();
|
|
void pushDict();
|
|
void pushDict(const std::string &name);
|
|
void pushArray();
|
|
void pushArray(const std::string &name);
|
|
void pop();
|
|
void writeBool(bool value);
|
|
void writeBool(const std::string &name, bool value);
|
|
void writeInt(int value);
|
|
void writeInt(const std::string &name, int value);
|
|
void writeUint(uint32_t value);
|
|
void writeUint(const std::string &name, uint32_t value);
|
|
void writeFloat(double value);
|
|
void writeFloat(const std::string &name, double value);
|
|
void writeString(const std::string &value);
|
|
void writeString(const std::string &name, const std::string &value);
|
|
void writeRaw(const std::string &value);
|
|
void writeRaw(const std::string &name, const std::string &value);
|
|
void writeNull();
|
|
void writeNull(const std::string &name);
|
|
|
|
std::string str() const {
|
|
return str_.str();
|
|
}
|
|
|
|
std::string flush() {
|
|
std::string result = str_.str();
|
|
str_.str("");
|
|
return result;
|
|
}
|
|
|
|
// RAII helpers: push in the constructor, pop in the destructor. Prefer these over manually
|
|
// paired pushDict()/pushArray() + pop() calls - a forgotten or early-returned pop() silently
|
|
// produces malformed JSON (extra or missing closing brace/bracket) rather than a compile or
|
|
// even runtime error, and that gets easy to miss once nesting goes a few levels deep (e.g.
|
|
// an array of per-item dicts, each with their own nested array).
|
|
class DictScope {
|
|
public:
|
|
explicit DictScope(JsonWriter &w) : w_(w) { w_.pushDict(); }
|
|
DictScope(JsonWriter &w, const std::string &name) : w_(w) { w_.pushDict(name); }
|
|
~DictScope() { w_.pop(); }
|
|
DictScope(const DictScope &) = delete;
|
|
DictScope &operator=(const DictScope &) = delete;
|
|
private:
|
|
JsonWriter &w_;
|
|
};
|
|
class ArrayScope {
|
|
public:
|
|
explicit ArrayScope(JsonWriter &w) : w_(w) { w_.pushArray(); }
|
|
ArrayScope(JsonWriter &w, const std::string &name) : w_(w) { w_.pushArray(name); }
|
|
~ArrayScope() { w_.pop(); }
|
|
ArrayScope(const ArrayScope &) = delete;
|
|
ArrayScope &operator=(const ArrayScope &) = delete;
|
|
private:
|
|
JsonWriter &w_;
|
|
};
|
|
|
|
enum {
|
|
NORMAL = 0,
|
|
PRETTY = 1,
|
|
};
|
|
|
|
private:
|
|
const char *indent(int n) const;
|
|
const char *comma() const;
|
|
const char *arrayComma() const;
|
|
const char *indent() const;
|
|
const char *arrayIndent() const;
|
|
void writeEscapedString(const std::string &s);
|
|
|
|
enum BlockType {
|
|
ARRAY,
|
|
DICT,
|
|
RAW,
|
|
};
|
|
struct StackEntry {
|
|
StackEntry(BlockType t) : type(t), first(true) {}
|
|
BlockType type;
|
|
bool first;
|
|
};
|
|
std::vector<StackEntry> stack_;
|
|
std::ostringstream str_;
|
|
bool pretty_;
|
|
};
|
|
|
|
std::string json_stringify(const JsonNode *json);
|
|
|
|
} // namespace json
|