mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1823326 - Part 11: Add JSONPerHandlerParser. r=bthrall
To support handler for syntax parser, make the parser templatized for handler. Differential Revision: https://phabricator.services.mozilla.com/D174569
This commit is contained in:
parent
eb884636ed
commit
26dd772281
@ -99,7 +99,7 @@ JSONToken JSONTokenizer<CharT, ParserT, StringBuilderT>::readString() {
|
||||
* of unescaped characters into a temporary buffer, then an escaped
|
||||
* character, and repeat until the entire string is consumed.
|
||||
*/
|
||||
StringBuilderT builder(parser->handler.cx);
|
||||
StringBuilderT builder(parser->handler.context());
|
||||
do {
|
||||
if (start < current && !builder.append(start.get(), current.get())) {
|
||||
return token(JSONToken::OOM);
|
||||
@ -585,9 +585,9 @@ inline void JSONFullParseHandlerAnyChar::freeStackEntry(StackEntry& entry) {
|
||||
|
||||
template <typename CharT>
|
||||
void JSONParser<CharT>::trace(JSTracer* trc) {
|
||||
handler.trace(trc);
|
||||
this->handler.trace(trc);
|
||||
|
||||
for (auto& elem : stack) {
|
||||
for (auto& elem : this->stack) {
|
||||
if (elem.state == JSONParserState::FinishArrayElement) {
|
||||
elem.elements().trace(trc);
|
||||
} else {
|
||||
@ -750,13 +750,13 @@ void JSONFullParseHandler<CharT>::reportError(const char* msg,
|
||||
msg, lineString, columnString);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
void JSONParser<CharT>::outOfMemory() {
|
||||
ReportOutOfMemory(handler.cx);
|
||||
template <typename CharT, typename HandlerT>
|
||||
void JSONPerHandlerParser<CharT, HandlerT>::outOfMemory() {
|
||||
ReportOutOfMemory(handler.context());
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
void JSONParser<CharT>::error(const char* msg) {
|
||||
template <typename CharT, typename HandlerT>
|
||||
void JSONPerHandlerParser<CharT, HandlerT>::error(const char* msg) {
|
||||
if (handler.ignoreError()) {
|
||||
return;
|
||||
}
|
||||
@ -784,26 +784,30 @@ bool JSONFullParseHandler<CharT>::StringBuilder::append(const CharT* begin,
|
||||
return buffer.append(begin, end);
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
JSONParser<CharT>::~JSONParser() {
|
||||
template <typename CharT, typename HandlerT>
|
||||
JSONPerHandlerParser<CharT, HandlerT>::~JSONPerHandlerParser() {
|
||||
for (size_t i = 0; i < stack.length(); i++) {
|
||||
handler.freeStackEntry(stack[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
bool JSONParser<CharT>::parse(MutableHandleValue vp) {
|
||||
RootedValue value(handler.cx);
|
||||
MOZ_ASSERT(stack.empty());
|
||||
template class js::JSONPerHandlerParser<Latin1Char,
|
||||
js::JSONFullParseHandler<Latin1Char>>;
|
||||
template class js::JSONPerHandlerParser<char16_t,
|
||||
js::JSONFullParseHandler<char16_t>>;
|
||||
|
||||
vp.setUndefined();
|
||||
template <typename CharT, typename HandlerT>
|
||||
template <typename TempValueT, typename ResultSetter>
|
||||
bool JSONPerHandlerParser<CharT, HandlerT>::parseImpl(TempValueT& value,
|
||||
ResultSetter setResult) {
|
||||
MOZ_ASSERT(stack.empty());
|
||||
|
||||
JSONToken token;
|
||||
JSONParserState state = JSONParserState::JSONValue;
|
||||
while (true) {
|
||||
switch (state) {
|
||||
case JSONParserState::FinishObjectMember: {
|
||||
typename Handler::PropertyVector* properties;
|
||||
typename HandlerT::PropertyVector* properties;
|
||||
handler.finishObjectMember(stack, value, &properties);
|
||||
|
||||
token = tokenizer.advanceAfterProperty();
|
||||
@ -854,7 +858,7 @@ bool JSONParser<CharT>::parse(MutableHandleValue vp) {
|
||||
return handler.errorReturn();
|
||||
|
||||
case JSONParserState::FinishArrayElement: {
|
||||
typename Handler::ElementVector* elements;
|
||||
typename HandlerT::ElementVector* elements;
|
||||
if (!handler.arrayElement(stack, value, &elements)) {
|
||||
return false;
|
||||
}
|
||||
@ -894,7 +898,7 @@ bool JSONParser<CharT>::parse(MutableHandleValue vp) {
|
||||
break;
|
||||
|
||||
case JSONToken::ArrayOpen: {
|
||||
typename Handler::ElementVector* elements;
|
||||
typename HandlerT::ElementVector* elements;
|
||||
if (!handler.arrayOpen(stack, &elements)) {
|
||||
return false;
|
||||
}
|
||||
@ -910,7 +914,7 @@ bool JSONParser<CharT>::parse(MutableHandleValue vp) {
|
||||
}
|
||||
|
||||
case JSONToken::ObjectOpen: {
|
||||
typename Handler::PropertyVector* properties;
|
||||
typename HandlerT::PropertyVector* properties;
|
||||
if (!handler.objectOpen(stack, &properties)) {
|
||||
return false;
|
||||
}
|
||||
@ -958,9 +962,19 @@ bool JSONParser<CharT>::parse(MutableHandleValue vp) {
|
||||
MOZ_ASSERT(tokenizer.finished());
|
||||
MOZ_ASSERT(stack.empty());
|
||||
|
||||
vp.set(value);
|
||||
setResult(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
bool JSONParser<CharT>::parse(MutableHandleValue vp) {
|
||||
RootedValue tempValue(this->handler.cx);
|
||||
|
||||
vp.setUndefined();
|
||||
|
||||
return this->parseImpl(tempValue,
|
||||
[&](JS::Handle<JS::Value> value) { vp.set(value); });
|
||||
}
|
||||
|
||||
template class js::JSONParser<Latin1Char>;
|
||||
template class js::JSONParser<char16_t>;
|
||||
|
@ -179,8 +179,7 @@ class MOZ_STACK_CLASS JSONFullParseHandlerAnyChar {
|
||||
|
||||
Value v;
|
||||
|
||||
protected:
|
||||
const ParseType parseType;
|
||||
ParseType parseType = ParseType::JSONParse;
|
||||
|
||||
private:
|
||||
// Unused element and property vectors for previous in progress arrays and
|
||||
@ -190,8 +189,8 @@ class MOZ_STACK_CLASS JSONFullParseHandlerAnyChar {
|
||||
Vector<PropertyVector*, 5> freeProperties;
|
||||
|
||||
public:
|
||||
JSONFullParseHandlerAnyChar(JSContext* cx, ParseType parseType)
|
||||
: cx(cx), parseType(parseType), freeElements(cx), freeProperties(cx) {}
|
||||
explicit JSONFullParseHandlerAnyChar(JSContext* cx)
|
||||
: cx(cx), freeElements(cx), freeProperties(cx) {}
|
||||
~JSONFullParseHandlerAnyChar();
|
||||
|
||||
// Allow move construction for use with Rooted.
|
||||
@ -206,6 +205,8 @@ class MOZ_STACK_CLASS JSONFullParseHandlerAnyChar {
|
||||
delete;
|
||||
void operator=(const JSONFullParseHandlerAnyChar& other) = delete;
|
||||
|
||||
JSContext* context() { return cx; }
|
||||
|
||||
Value numberValue() const {
|
||||
MOZ_ASSERT(v.isNumber());
|
||||
return v;
|
||||
@ -266,6 +267,8 @@ class MOZ_STACK_CLASS JSONFullParseHandler
|
||||
using CharPtr = mozilla::RangedPtr<const CharT>;
|
||||
|
||||
public:
|
||||
using ContextT = JSContext;
|
||||
|
||||
class StringBuilder {
|
||||
public:
|
||||
JSStringBuilder buffer;
|
||||
@ -276,8 +279,7 @@ class MOZ_STACK_CLASS JSONFullParseHandler
|
||||
bool append(const CharT* begin, const CharT* end);
|
||||
};
|
||||
|
||||
JSONFullParseHandler(JSContext* cx, ParseType parseType)
|
||||
: Base(cx, parseType) {}
|
||||
explicit JSONFullParseHandler(JSContext* cx) : Base(cx) {}
|
||||
|
||||
JSONFullParseHandler(JSONFullParseHandler&& other) noexcept
|
||||
: Base(std::move(other)) {}
|
||||
@ -294,23 +296,53 @@ class MOZ_STACK_CLASS JSONFullParseHandler
|
||||
const char* columnString);
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
class MOZ_STACK_CLASS JSONParser {
|
||||
using Handler = JSONFullParseHandler<CharT>;
|
||||
template <typename CharT, typename HandlerT>
|
||||
class MOZ_STACK_CLASS JSONPerHandlerParser {
|
||||
using ContextT = typename HandlerT::ContextT;
|
||||
|
||||
using Tokenizer = JSONTokenizer<CharT, JSONPerHandlerParser<CharT, HandlerT>,
|
||||
typename HandlerT::StringBuilder>;
|
||||
|
||||
public:
|
||||
using StringBuilder = typename Handler::StringBuilder;
|
||||
|
||||
private:
|
||||
using Tokenizer = JSONTokenizer<CharT, JSONParser<CharT>, StringBuilder>;
|
||||
using StringBuilder = typename HandlerT::StringBuilder;
|
||||
|
||||
public:
|
||||
Handler handler;
|
||||
HandlerT handler;
|
||||
Tokenizer tokenizer;
|
||||
|
||||
// All in progress arrays and objects being parsed, in order from outermost
|
||||
// to innermost.
|
||||
Vector<typename Handler::StackEntry, 10> stack;
|
||||
Vector<typename HandlerT::StackEntry, 10> stack;
|
||||
|
||||
public:
|
||||
JSONPerHandlerParser(ContextT* context, mozilla::Range<const CharT> data)
|
||||
: handler(context), tokenizer(data, this), stack(context) {}
|
||||
|
||||
JSONPerHandlerParser(JSONPerHandlerParser&& other) noexcept
|
||||
: handler(std::move(other.handler)),
|
||||
tokenizer(std::move(other.tokenizer)),
|
||||
stack(handler.context()) {
|
||||
tokenizer.fixupParser(this);
|
||||
}
|
||||
|
||||
~JSONPerHandlerParser();
|
||||
|
||||
JSONPerHandlerParser(const JSONPerHandlerParser<CharT, HandlerT>& other) =
|
||||
delete;
|
||||
void operator=(const JSONPerHandlerParser<CharT, HandlerT>& other) = delete;
|
||||
|
||||
template <typename TempValueT, typename ResultSetter>
|
||||
inline bool parseImpl(TempValueT& value, ResultSetter setResult);
|
||||
|
||||
void outOfMemory();
|
||||
|
||||
void error(const char* msg);
|
||||
};
|
||||
|
||||
template <typename CharT>
|
||||
class MOZ_STACK_CLASS JSONParser
|
||||
: JSONPerHandlerParser<CharT, JSONFullParseHandler<CharT>> {
|
||||
using Base = JSONPerHandlerParser<CharT, JSONFullParseHandler<CharT>>;
|
||||
|
||||
public:
|
||||
using ParseType = JSONFullParseHandlerAnyChar::ParseType;
|
||||
@ -320,17 +352,15 @@ class MOZ_STACK_CLASS JSONParser {
|
||||
/* Create a parser for the provided JSON data. */
|
||||
JSONParser(JSContext* cx, mozilla::Range<const CharT> data,
|
||||
ParseType parseType)
|
||||
: handler(cx, parseType), tokenizer(data, this), stack(cx) {}
|
||||
|
||||
/* Allow move construction for use with Rooted. */
|
||||
JSONParser(JSONParser&& other)
|
||||
: handler(std::move(other.handler)),
|
||||
tokenizer(std::move(other.tokenizer)),
|
||||
stack(std::move(other.stack)) {
|
||||
tokenizer.fixupParser(this);
|
||||
: Base(cx, data) {
|
||||
this->handler.parseType = parseType;
|
||||
}
|
||||
|
||||
~JSONParser();
|
||||
/* Allow move construction for use with Rooted. */
|
||||
JSONParser(JSONParser&& other) noexcept : Base(std::move(other)) {}
|
||||
|
||||
JSONParser(const JSONParser& other) = delete;
|
||||
void operator=(const JSONParser& other) = delete;
|
||||
|
||||
/*
|
||||
* Parse the JSON data specified at construction time. If it parses
|
||||
@ -345,14 +375,6 @@ class MOZ_STACK_CLASS JSONParser {
|
||||
bool parse(MutableHandleValue vp);
|
||||
|
||||
void trace(JSTracer* trc);
|
||||
|
||||
void outOfMemory();
|
||||
|
||||
void error(const char* msg);
|
||||
|
||||
private:
|
||||
JSONParser(const JSONParser& other) = delete;
|
||||
void operator=(const JSONParser& other) = delete;
|
||||
};
|
||||
|
||||
template <typename CharT, typename Wrapper>
|
||||
|
Loading…
Reference in New Issue
Block a user