mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1023778 part 1 - Add JSONParserBase base class. r=Waldo
This commit is contained in:
parent
fcbaa23ac2
commit
5ec377d208
@ -174,7 +174,7 @@ TryEvalJSON(JSContext *cx, JSScript *callerScript,
|
||||
if (cp == end) {
|
||||
bool isArray = (chars[0] == '[');
|
||||
JSONParser parser(cx, isArray ? chars : chars + 1U, isArray ? length : length - 2,
|
||||
JSONParser::NoError);
|
||||
JSONParserBase::NoError);
|
||||
RootedValue tmp(cx);
|
||||
if (!parser.parse(&tmp))
|
||||
return EvalJSON_Failure;
|
||||
|
@ -576,7 +576,7 @@ AutoGCRooter::trace(JSTracer *trc)
|
||||
}
|
||||
|
||||
case JSONPARSER:
|
||||
static_cast<js::JSONParser *>(this)->trace(trc);
|
||||
static_cast<js::JSONParserBase *>(this)->trace(trc);
|
||||
return;
|
||||
|
||||
case CUSTOM:
|
||||
|
@ -23,7 +23,7 @@ using namespace js;
|
||||
|
||||
using mozilla::RangedPtr;
|
||||
|
||||
JSONParser::~JSONParser()
|
||||
JSONParserBase::~JSONParserBase()
|
||||
{
|
||||
for (size_t i = 0; i < stack.length(); i++) {
|
||||
if (stack[i].state == FinishArrayElement)
|
||||
@ -40,7 +40,7 @@ JSONParser::~JSONParser()
|
||||
}
|
||||
|
||||
void
|
||||
JSONParser::trace(JSTracer *trc)
|
||||
JSONParserBase::trace(JSTracer *trc)
|
||||
{
|
||||
for (size_t i = 0; i < stack.length(); i++) {
|
||||
if (stack[i].state == FinishArrayElement) {
|
||||
@ -97,13 +97,13 @@ JSONParser::error(const char *msg)
|
||||
}
|
||||
|
||||
bool
|
||||
JSONParser::errorReturn()
|
||||
JSONParserBase::errorReturn()
|
||||
{
|
||||
return errorHandling == NoError;
|
||||
}
|
||||
|
||||
template<JSONParser::StringType ST>
|
||||
JSONParser::Token
|
||||
template<JSONParserBase::StringType ST>
|
||||
JSONParserBase::Token
|
||||
JSONParser::readString()
|
||||
{
|
||||
JS_ASSERT(current < end);
|
||||
@ -236,7 +236,7 @@ JSONParser::readString()
|
||||
return token(Error);
|
||||
}
|
||||
|
||||
JSONParser::Token
|
||||
JSONParserBase::Token
|
||||
JSONParser::readNumber()
|
||||
{
|
||||
JS_ASSERT(current < end);
|
||||
@ -341,7 +341,7 @@ IsJSONWhitespace(jschar c)
|
||||
return c == '\t' || c == '\r' || c == '\n' || c == ' ';
|
||||
}
|
||||
|
||||
JSONParser::Token
|
||||
JSONParserBase::Token
|
||||
JSONParser::advance()
|
||||
{
|
||||
while (current < end && IsJSONWhitespace(*current))
|
||||
@ -422,7 +422,7 @@ JSONParser::advance()
|
||||
}
|
||||
}
|
||||
|
||||
JSONParser::Token
|
||||
JSONParserBase::Token
|
||||
JSONParser::advanceAfterObjectOpen()
|
||||
{
|
||||
JS_ASSERT(current[-1] == '{');
|
||||
@ -473,7 +473,7 @@ AssertPastValue(const RangedPtr<const jschar> current)
|
||||
JS7_ISDEC(current[-1]));
|
||||
}
|
||||
|
||||
JSONParser::Token
|
||||
JSONParserBase::Token
|
||||
JSONParser::advanceAfterArrayElement()
|
||||
{
|
||||
AssertPastValue(current);
|
||||
@ -499,7 +499,7 @@ JSONParser::advanceAfterArrayElement()
|
||||
return token(Error);
|
||||
}
|
||||
|
||||
JSONParser::Token
|
||||
JSONParserBase::Token
|
||||
JSONParser::advancePropertyName()
|
||||
{
|
||||
JS_ASSERT(current[-1] == ',');
|
||||
@ -518,7 +518,7 @@ JSONParser::advancePropertyName()
|
||||
return token(Error);
|
||||
}
|
||||
|
||||
JSONParser::Token
|
||||
JSONParserBase::Token
|
||||
JSONParser::advancePropertyColon()
|
||||
{
|
||||
JS_ASSERT(current[-1] == '"');
|
||||
@ -539,7 +539,7 @@ JSONParser::advancePropertyColon()
|
||||
return token(Error);
|
||||
}
|
||||
|
||||
JSONParser::Token
|
||||
JSONParserBase::Token
|
||||
JSONParser::advanceAfterProperty()
|
||||
{
|
||||
AssertPastValue(current);
|
||||
@ -566,7 +566,7 @@ JSONParser::advanceAfterProperty()
|
||||
}
|
||||
|
||||
JSObject *
|
||||
JSONParser::createFinishedObject(PropertyVector &properties)
|
||||
JSONParserBase::createFinishedObject(PropertyVector &properties)
|
||||
{
|
||||
/*
|
||||
* Look for an existing cached type and shape for objects with this set of
|
||||
@ -611,7 +611,7 @@ JSONParser::createFinishedObject(PropertyVector &properties)
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSONParser::finishObject(MutableHandleValue vp, PropertyVector &properties)
|
||||
JSONParserBase::finishObject(MutableHandleValue vp, PropertyVector &properties)
|
||||
{
|
||||
JS_ASSERT(&properties == &stack.back().properties());
|
||||
|
||||
@ -627,7 +627,7 @@ JSONParser::finishObject(MutableHandleValue vp, PropertyVector &properties)
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSONParser::finishArray(MutableHandleValue vp, ElementVector &elements)
|
||||
JSONParserBase::finishArray(MutableHandleValue vp, ElementVector &elements)
|
||||
{
|
||||
JS_ASSERT(&elements == &stack.back().elements());
|
||||
|
||||
|
@ -16,20 +16,21 @@
|
||||
|
||||
namespace js {
|
||||
|
||||
class MOZ_STACK_CLASS JSONParser : private JS::AutoGCRooter
|
||||
// JSONParser base class. JSONParser is templatized to work on either Latin1
|
||||
// or TwoByte input strings, JSONParserBase holds all state and methods that
|
||||
// can be shared between the two encodings.
|
||||
class MOZ_STACK_CLASS JSONParserBase : private JS::AutoGCRooter
|
||||
{
|
||||
public:
|
||||
enum ErrorHandling { RaiseError, NoError };
|
||||
|
||||
private:
|
||||
/* Data members */
|
||||
|
||||
JSContext * const cx;
|
||||
JS::ConstTwoByteChars current;
|
||||
const JS::ConstTwoByteChars begin, end;
|
||||
|
||||
Value v;
|
||||
|
||||
protected:
|
||||
JSContext * const cx;
|
||||
|
||||
const ErrorHandling errorHandling;
|
||||
|
||||
enum Token { String, Number, True, False, Null,
|
||||
@ -105,17 +106,9 @@ class MOZ_STACK_CLASS JSONParser : private JS::AutoGCRooter
|
||||
Token lastToken;
|
||||
#endif
|
||||
|
||||
public:
|
||||
/* Public API */
|
||||
|
||||
/* Create a parser for the provided JSON data. */
|
||||
JSONParser(JSContext *cx, JS::ConstTwoByteChars data, size_t length,
|
||||
ErrorHandling errorHandling = RaiseError)
|
||||
: AutoGCRooter(cx, JSONPARSER),
|
||||
JSONParserBase(JSContext *cx, ErrorHandling errorHandling)
|
||||
: JS::AutoGCRooter(cx, JSONPARSER),
|
||||
cx(cx),
|
||||
current(data),
|
||||
begin(data),
|
||||
end((data + length).get(), data.get(), length),
|
||||
errorHandling(errorHandling),
|
||||
stack(cx),
|
||||
freeElements(cx),
|
||||
@ -123,25 +116,9 @@ class MOZ_STACK_CLASS JSONParser : private JS::AutoGCRooter
|
||||
#ifdef DEBUG
|
||||
, lastToken(Error)
|
||||
#endif
|
||||
{
|
||||
JS_ASSERT(current <= end);
|
||||
}
|
||||
{}
|
||||
~JSONParserBase();
|
||||
|
||||
~JSONParser();
|
||||
|
||||
/*
|
||||
* Parse the JSON data specified at construction time. If it parses
|
||||
* successfully, store the prescribed value in *vp and return true. If an
|
||||
* internal error (e.g. OOM) occurs during parsing, return false.
|
||||
* Otherwise, if invalid input was specifed but no internal error occurred,
|
||||
* behavior depends upon the error handling specified at construction: if
|
||||
* error handling is RaiseError then throw a SyntaxError and return false,
|
||||
* otherwise return true and set *vp to |undefined|. (JSON syntax can't
|
||||
* represent |undefined|, so the JSON data couldn't have specified it.)
|
||||
*/
|
||||
bool parse(MutableHandleValue vp);
|
||||
|
||||
private:
|
||||
Value numberValue() const {
|
||||
JS_ASSERT(lastToken == Number);
|
||||
JS_ASSERT(v.isNumber());
|
||||
@ -185,6 +162,55 @@ class MOZ_STACK_CLASS JSONParser : private JS::AutoGCRooter
|
||||
}
|
||||
|
||||
enum StringType { PropertyName, LiteralValue };
|
||||
|
||||
bool errorReturn();
|
||||
|
||||
bool finishObject(MutableHandleValue vp, PropertyVector &properties);
|
||||
bool finishArray(MutableHandleValue vp, ElementVector &elements);
|
||||
|
||||
private:
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
void trace(JSTracer *trc);
|
||||
|
||||
JSObject *createFinishedObject(PropertyVector &properties);
|
||||
|
||||
JSONParserBase(const JSONParserBase &other) MOZ_DELETE;
|
||||
void operator=(const JSONParserBase &other) MOZ_DELETE;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS JSONParser : public JSONParserBase
|
||||
{
|
||||
private:
|
||||
JS::ConstTwoByteChars current;
|
||||
const JS::ConstTwoByteChars begin, end;
|
||||
|
||||
public:
|
||||
/* Public API */
|
||||
|
||||
/* Create a parser for the provided JSON data. */
|
||||
JSONParser(JSContext *cx, JS::ConstTwoByteChars data, size_t length,
|
||||
ErrorHandling errorHandling = RaiseError)
|
||||
: JSONParserBase(cx, errorHandling),
|
||||
current(data),
|
||||
begin(data),
|
||||
end((data + length).get(), data.get(), length)
|
||||
{
|
||||
JS_ASSERT(current <= end);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the JSON data specified at construction time. If it parses
|
||||
* successfully, store the prescribed value in *vp and return true. If an
|
||||
* internal error (e.g. OOM) occurs during parsing, return false.
|
||||
* Otherwise, if invalid input was specifed but no internal error occurred,
|
||||
* behavior depends upon the error handling specified at construction: if
|
||||
* error handling is RaiseError then throw a SyntaxError and return false,
|
||||
* otherwise return true and set *vp to |undefined|. (JSON syntax can't
|
||||
* represent |undefined|, so the JSON data couldn't have specified it.)
|
||||
*/
|
||||
bool parse(MutableHandleValue vp);
|
||||
|
||||
private:
|
||||
template<StringType ST> Token readString();
|
||||
|
||||
Token readNumber();
|
||||
@ -197,17 +223,9 @@ class MOZ_STACK_CLASS JSONParser : private JS::AutoGCRooter
|
||||
Token advanceAfterArrayElement();
|
||||
|
||||
void error(const char *msg);
|
||||
bool errorReturn();
|
||||
|
||||
JSObject *createFinishedObject(PropertyVector &properties);
|
||||
bool finishObject(MutableHandleValue vp, PropertyVector &properties);
|
||||
bool finishArray(MutableHandleValue vp, ElementVector &elements);
|
||||
|
||||
void getTextPosition(uint32_t *column, uint32_t *line);
|
||||
|
||||
friend void AutoGCRooter::trace(JSTracer *trc);
|
||||
void trace(JSTracer *trc);
|
||||
|
||||
private:
|
||||
JSONParser(const JSONParser &other) MOZ_DELETE;
|
||||
void operator=(const JSONParser &other) MOZ_DELETE;
|
||||
|
Loading…
Reference in New Issue
Block a user