mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 387522. Native JSON support. r=crowder/jst, sr=brendan
This commit is contained in:
parent
3fda481a95
commit
43999e482b
@ -58,6 +58,7 @@ DIRS = \
|
|||||||
ls \
|
ls \
|
||||||
xul \
|
xul \
|
||||||
storage \
|
storage \
|
||||||
|
json \
|
||||||
offline
|
offline
|
||||||
|
|
||||||
ifdef MOZ_SVG
|
ifdef MOZ_SVG
|
||||||
|
57
dom/public/idl/json/Makefile.in
Normal file
57
dom/public/idl/json/Makefile.in
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
# the License. You may obtain a copy of the License at
|
||||||
|
# http://www.mozilla.org/MPL/
|
||||||
|
#
|
||||||
|
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
# for the specific language governing rights and limitations under the
|
||||||
|
# License.
|
||||||
|
#
|
||||||
|
# The Original Code is mozilla.org code.
|
||||||
|
#
|
||||||
|
# The Initial Developer of the Original Code is Mozilla Corporation.
|
||||||
|
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||||
|
# the Initial Developer. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Contributor(s):
|
||||||
|
# Robert Sayre <sayrer@gmail.com>
|
||||||
|
#
|
||||||
|
# Alternatively, the contents of this file may be used under the terms of
|
||||||
|
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
# of those above. If you wish to allow use of your version of this file only
|
||||||
|
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
# use your version of this file under the terms of the MPL, indicate your
|
||||||
|
# decision by deleting the provisions above and replace them with the notice
|
||||||
|
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
# the provisions above, a recipient may use your version of this file under
|
||||||
|
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
DEPTH = ../../../..
|
||||||
|
topsrcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
|
MODULE = dom
|
||||||
|
XPIDL_MODULE = dom_json
|
||||||
|
GRE_MODULE = 1
|
||||||
|
|
||||||
|
XPIDLSRCS = \
|
||||||
|
nsIJSON.idl \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
SDK_XPIDLSRCS = \
|
||||||
|
nsIJSON.idl \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/rules.mk
|
66
dom/public/idl/json/nsIJSON.idl
Normal file
66
dom/public/idl/json/nsIJSON.idl
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Robert Sayre <sayrer@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "domstubs.idl"
|
||||||
|
|
||||||
|
interface nsIInputStream;
|
||||||
|
interface nsIOutputStream;
|
||||||
|
interface nsIScriptGlobalObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode and decode JSON text.
|
||||||
|
*/
|
||||||
|
[scriptable, uuid(45464c36-efde-4cb5-8e00-07480533ff35)]
|
||||||
|
interface nsIJSON : nsISupports
|
||||||
|
{
|
||||||
|
AString encode(/* in JSObject value,
|
||||||
|
/* [optional] in JSObject whitelist */);
|
||||||
|
|
||||||
|
void encodeToStream(in nsIOutputStream stream,
|
||||||
|
in string charset,
|
||||||
|
in boolean writeBOM
|
||||||
|
/* in JSObject value,
|
||||||
|
/* [optional] in JSObject optFilter */);
|
||||||
|
|
||||||
|
void /* JSObject */ decode(in AString str
|
||||||
|
/* , [optional] in JSObject whitelist */);
|
||||||
|
|
||||||
|
void /* JSObject */ decodeFromStream(in nsIInputStream stream,
|
||||||
|
in long contentLength
|
||||||
|
/*[optional] in JSObject optFilter */);
|
||||||
|
};
|
@ -42,7 +42,7 @@ VPATH = @srcdir@
|
|||||||
|
|
||||||
include $(DEPTH)/config/autoconf.mk
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
DIRS = base jsurl events storage offline
|
DIRS = base jsurl events storage offline json
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
|
80
dom/src/json/Makefile.in
Normal file
80
dom/src/json/Makefile.in
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
# the License. You may obtain a copy of the License at
|
||||||
|
# http://www.mozilla.org/MPL/
|
||||||
|
#
|
||||||
|
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
# for the specific language governing rights and limitations under the
|
||||||
|
# License.
|
||||||
|
#
|
||||||
|
# The Original Code is mozilla.org code.
|
||||||
|
#
|
||||||
|
# The Initial Developer of the Original Code is Mozilla Corporation.
|
||||||
|
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||||
|
# the Initial Developer. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Contributor(s):
|
||||||
|
# Robert Sayre <sayrer@gmail.com>
|
||||||
|
#
|
||||||
|
# Alternatively, the contents of this file may be used under the terms of
|
||||||
|
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
# of those above. If you wish to allow use of your version of this file only
|
||||||
|
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
# use your version of this file under the terms of the MPL, indicate your
|
||||||
|
# decision by deleting the provisions above and replace them with the notice
|
||||||
|
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
# the provisions above, a recipient may use your version of this file under
|
||||||
|
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
DEPTH = ../../..
|
||||||
|
topsrcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
|
MODULE = dom
|
||||||
|
LIBRARY_NAME = json_s
|
||||||
|
LIBXUL_LIBRARY = 1
|
||||||
|
|
||||||
|
REQUIRES = xpcom \
|
||||||
|
string \
|
||||||
|
content \
|
||||||
|
caps \
|
||||||
|
js \
|
||||||
|
locale \
|
||||||
|
layout \
|
||||||
|
necko \
|
||||||
|
pref \
|
||||||
|
uconv \
|
||||||
|
unicharutil \
|
||||||
|
widget \
|
||||||
|
xpconnect \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
CPPSRCS = \
|
||||||
|
nsJSON.cpp \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
FORCE_STATIC_LIB = 1
|
||||||
|
|
||||||
|
LOCAL_INCLUDES = \
|
||||||
|
-I$(srcdir)/../base \
|
||||||
|
-I$(topsrcdir)/content/events/src
|
||||||
|
|
||||||
|
DEFINES += -D_IMPL_NS_LAYOUT
|
||||||
|
|
||||||
|
ifdef ENABLE_TESTS
|
||||||
|
DIRS += test
|
||||||
|
endif
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/rules.mk
|
1245
dom/src/json/nsJSON.cpp
Normal file
1245
dom/src/json/nsJSON.cpp
Normal file
File diff suppressed because it is too large
Load Diff
164
dom/src/json/nsJSON.h
Normal file
164
dom/src/json/nsJSON.h
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Mozilla Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Robert Sayre <sayrer@gmail.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef nsJSON_h__
|
||||||
|
#define nsJSON_h__
|
||||||
|
|
||||||
|
#include "jsprvtd.h"
|
||||||
|
#include "nsIJSON.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsIOutputStream.h"
|
||||||
|
#include "nsIUnicodeEncoder.h"
|
||||||
|
#include "nsIUnicodeDecoder.h"
|
||||||
|
#include "nsIRequestObserver.h"
|
||||||
|
#include "nsIStreamListener.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
#define JSON_MAX_DEPTH 2048
|
||||||
|
#define JSON_PARSER_BUFSIZE 1024
|
||||||
|
class nsJSONWriter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsJSONWriter();
|
||||||
|
nsJSONWriter(nsIOutputStream *aStream);
|
||||||
|
virtual ~nsJSONWriter();
|
||||||
|
nsresult SetCharset(const char *aCharset);
|
||||||
|
nsString mBuffer;
|
||||||
|
nsCOMPtr<nsIOutputStream> mStream;
|
||||||
|
nsresult WriteString(const PRUnichar* aBuffer, PRUint32);
|
||||||
|
nsresult Write(const PRUnichar *aBuffer, PRUint32 aLength);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsresult WriteToStream(nsIOutputStream *aStream, nsIUnicodeEncoder *encoder,
|
||||||
|
const PRUnichar *aBuffer, PRUint32 aLength);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIUnicodeEncoder> mEncoder;
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsJSON : public nsIJSON
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsJSON();
|
||||||
|
virtual ~nsJSON();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIJSON
|
||||||
|
|
||||||
|
protected:
|
||||||
|
JSBool ToJSON(JSContext *cx, jsval *vp);
|
||||||
|
nsresult EncodeObject(JSContext *cx, jsval *vp, nsJSONWriter *writer,
|
||||||
|
JSObject *whitelist, PRUint32 depth);
|
||||||
|
nsresult EncodeInternal(nsJSONWriter *writer);
|
||||||
|
nsresult DecodeInternal(nsIInputStream *aStream,
|
||||||
|
PRInt32 aContentLength,
|
||||||
|
PRBool aNeedsConverter);
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
||||||
|
|
||||||
|
enum JSONParserState {
|
||||||
|
JSON_PARSE_STATE_INIT,
|
||||||
|
JSON_PARSE_STATE_VALUE,
|
||||||
|
JSON_PARSE_STATE_OBJECT,
|
||||||
|
JSON_PARSE_STATE_OBJECT_PAIR,
|
||||||
|
JSON_PARSE_STATE_OBJECT_IN_PAIR,
|
||||||
|
JSON_PARSE_STATE_ARRAY,
|
||||||
|
JSON_PARSE_STATE_STRING,
|
||||||
|
JSON_PARSE_STATE_STRING_ESCAPE,
|
||||||
|
JSON_PARSE_STATE_STRING_HEX,
|
||||||
|
JSON_PARSE_STATE_NUMBER,
|
||||||
|
JSON_PARSE_STATE_KEYWORD,
|
||||||
|
JSON_PARSE_STATE_FINISHED
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsJSONObjectStack : public nsTArray<JSObject *>,
|
||||||
|
public JSTempValueRooter
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsJSONListener : public nsIStreamListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsJSONListener(JSContext *cx, jsval *rootVal, PRBool needsConverter);
|
||||||
|
virtual ~nsJSONListener();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIREQUESTOBSERVER
|
||||||
|
NS_DECL_NSISTREAMLISTENER
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PRUint32 mLineNum;
|
||||||
|
PRUint32 mColumn;
|
||||||
|
|
||||||
|
/* Used while handling \uNNNN in strings */
|
||||||
|
PRUnichar mHexChar;
|
||||||
|
PRUint8 mNumHex;
|
||||||
|
|
||||||
|
JSContext *mCx;
|
||||||
|
jsval *mRootVal;
|
||||||
|
PRBool mNeedsConverter;
|
||||||
|
nsCOMPtr<nsIUnicodeDecoder> mDecoder;
|
||||||
|
JSONParserState *mStatep;
|
||||||
|
JSONParserState mStateStack[JSON_MAX_DEPTH];
|
||||||
|
nsString mStringBuffer;
|
||||||
|
nsCString mSniffBuffer;
|
||||||
|
|
||||||
|
nsresult PushState(JSONParserState state);
|
||||||
|
nsresult PopState();
|
||||||
|
nsresult ProcessBytes(const char* aBuffer, PRUint32 aByteLength);
|
||||||
|
nsresult ConsumeConverted(const char* aBuffer, PRUint32 aByteLength);
|
||||||
|
nsresult Consume(const PRUnichar *data, PRUint32 len);
|
||||||
|
|
||||||
|
// These handle parsed tokens. Could be split to separate interface.
|
||||||
|
nsJSONObjectStack mObjectStack;
|
||||||
|
|
||||||
|
nsresult PushValue(JSObject *aParent, jsval aValue);
|
||||||
|
nsresult PushObject(JSObject *aObj);
|
||||||
|
nsresult OpenObject();
|
||||||
|
nsresult CloseObject();
|
||||||
|
nsresult OpenArray();
|
||||||
|
nsresult CloseArray();
|
||||||
|
nsresult HandleString();
|
||||||
|
nsresult HandleNumber();
|
||||||
|
nsresult HandleKeyword();
|
||||||
|
nsString mObjectKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
49
dom/src/json/test/Makefile.in
Normal file
49
dom/src/json/test/Makefile.in
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
# the License. You may obtain a copy of the License at
|
||||||
|
# http://www.mozilla.org/MPL/
|
||||||
|
#
|
||||||
|
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
# for the specific language governing rights and limitations under the
|
||||||
|
# License.
|
||||||
|
#
|
||||||
|
# The Original Code is mozilla.org code.
|
||||||
|
#
|
||||||
|
# The Initial Developer of the Original Code is Mozilla Corporation.
|
||||||
|
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||||
|
# the Initial Developer. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Contributor(s):
|
||||||
|
# Robert Sayre <sayrer@gmail.com>
|
||||||
|
#
|
||||||
|
# Alternatively, the contents of this file may be used under the terms of
|
||||||
|
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
# of those above. If you wish to allow use of your version of this file only
|
||||||
|
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
# use your version of this file under the terms of the MPL, indicate your
|
||||||
|
# decision by deleting the provisions above and replace them with the notice
|
||||||
|
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
# the provisions above, a recipient may use your version of this file under
|
||||||
|
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
DEPTH = ../../../..
|
||||||
|
topsrcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
|
MODULE = json_test
|
||||||
|
|
||||||
|
XPCSHELL_TESTS = unit
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/rules.mk
|
263
dom/src/json/test/json2.js
Normal file
263
dom/src/json/test/json2.js
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
json2.js
|
||||||
|
2007-11-06
|
||||||
|
|
||||||
|
Public Domain
|
||||||
|
|
||||||
|
See http://www.JSON.org/js.html
|
||||||
|
|
||||||
|
This file creates a global JSON object containing two methods:
|
||||||
|
|
||||||
|
JSON.stringify(value, whitelist)
|
||||||
|
value any JavaScript value, usually an object or array.
|
||||||
|
|
||||||
|
whitelist an optional that determines how object values are
|
||||||
|
stringified.
|
||||||
|
|
||||||
|
This method produces a JSON text from a JavaScript value.
|
||||||
|
There are three possible ways to stringify an object, depending
|
||||||
|
on the optional whitelist parameter.
|
||||||
|
|
||||||
|
If an object has a toJSON method, then the toJSON() method will be
|
||||||
|
called. The value returned from the toJSON method will be
|
||||||
|
stringified.
|
||||||
|
|
||||||
|
Otherwise, if the optional whitelist parameter is an array, then
|
||||||
|
the elements of the array will be used to select members of the
|
||||||
|
object for stringification.
|
||||||
|
|
||||||
|
Otherwise, if there is no whitelist parameter, then all of the
|
||||||
|
members of the object will be stringified.
|
||||||
|
|
||||||
|
Values that do not have JSON representaions, such as undefined or
|
||||||
|
functions, will not be serialized. Such values in objects will be
|
||||||
|
dropped, in arrays will be replaced with null. JSON.stringify()
|
||||||
|
returns undefined. Dates will be stringified as quoted ISO dates.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
var text = JSON.stringify(['e', {pluribus: 'unum'}]);
|
||||||
|
// text is '["e",{"pluribus":"unum"}]'
|
||||||
|
|
||||||
|
JSON.parse(text, filter)
|
||||||
|
This method parses a JSON text to produce an object or
|
||||||
|
array. It can throw a SyntaxError exception.
|
||||||
|
|
||||||
|
The optional filter parameter is a function that can filter and
|
||||||
|
transform the results. It receives each of the keys and values, and
|
||||||
|
its return value is used instead of the original value. If it
|
||||||
|
returns what it received, then structure is not modified. If it
|
||||||
|
returns undefined then the member is deleted.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
// Parse the text. If a key contains the string 'date' then
|
||||||
|
// convert the value to a date.
|
||||||
|
|
||||||
|
myData = JSON.parse(text, function (key, value) {
|
||||||
|
return key.indexOf('date') >= 0 ? new Date(value) : value;
|
||||||
|
});
|
||||||
|
|
||||||
|
This is a reference implementation. You are free to copy, modify, or
|
||||||
|
redistribute.
|
||||||
|
|
||||||
|
Use your own copy. It is extremely unwise to load third party
|
||||||
|
code into your pages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*jslint evil: true */
|
||||||
|
/*extern JSON */
|
||||||
|
|
||||||
|
if (!this.JSON) {
|
||||||
|
|
||||||
|
JSON = function () {
|
||||||
|
|
||||||
|
function f(n) { // Format integers to have at least two digits.
|
||||||
|
return n < 10 ? '0' + n : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
Date.prototype.toJSON = function () {
|
||||||
|
|
||||||
|
// Eventually, this method will be based on the date.toISOString method.
|
||||||
|
|
||||||
|
return this.getUTCFullYear() + '-' +
|
||||||
|
f(this.getUTCMonth() + 1) + '-' +
|
||||||
|
f(this.getUTCDate()) + 'T' +
|
||||||
|
f(this.getUTCHours()) + ':' +
|
||||||
|
f(this.getUTCMinutes()) + ':' +
|
||||||
|
f(this.getUTCSeconds()) + 'Z';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var m = { // table of character substitutions
|
||||||
|
'\b': '\\b',
|
||||||
|
'\t': '\\t',
|
||||||
|
'\n': '\\n',
|
||||||
|
'\f': '\\f',
|
||||||
|
'\r': '\\r',
|
||||||
|
'"' : '\\"',
|
||||||
|
'\\': '\\\\'
|
||||||
|
};
|
||||||
|
|
||||||
|
function stringify(value, whitelist) {
|
||||||
|
var a, // The array holding the partial texts.
|
||||||
|
i, // The loop counter.
|
||||||
|
k, // The member key.
|
||||||
|
l, // Length.
|
||||||
|
r = /["\\\x00-\x1f\x7f-\x9f]/g,
|
||||||
|
v; // The member value.
|
||||||
|
|
||||||
|
switch (typeof value) {
|
||||||
|
case 'string':
|
||||||
|
|
||||||
|
// If the string contains no control characters, no quote characters, and no
|
||||||
|
// backslash characters, then we can safely slap some quotes around it.
|
||||||
|
// Otherwise we must also replace the offending characters with safe sequences.
|
||||||
|
|
||||||
|
return r.test(value) ?
|
||||||
|
'"' + value.replace(r, function (a) {
|
||||||
|
var c = m[a];
|
||||||
|
if (c) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
c = a.charCodeAt();
|
||||||
|
return '\\u00' + Math.floor(c / 16).toString(16) +
|
||||||
|
(c % 16).toString(16);
|
||||||
|
}) + '"' :
|
||||||
|
'"' + value + '"';
|
||||||
|
|
||||||
|
case 'number':
|
||||||
|
|
||||||
|
// JSON numbers must be finite. Encode non-finite numbers as null.
|
||||||
|
|
||||||
|
return isFinite(value) ? String(value) : 'null';
|
||||||
|
|
||||||
|
case 'boolean':
|
||||||
|
case 'null':
|
||||||
|
return String(value);
|
||||||
|
|
||||||
|
case 'object':
|
||||||
|
|
||||||
|
// Due to a specification blunder in ECMAScript,
|
||||||
|
// typeof null is 'object', so watch out for that case.
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the object has a toJSON method, call it, and stringify the result.
|
||||||
|
|
||||||
|
if (typeof value.toJSON === 'function') {
|
||||||
|
return stringify(value.toJSON());
|
||||||
|
}
|
||||||
|
a = [];
|
||||||
|
if (typeof value.length === 'number' &&
|
||||||
|
!(value.propertyIsEnumerable('length'))) {
|
||||||
|
|
||||||
|
// The object is an array. Stringify every element. Use null as a placeholder
|
||||||
|
// for non-JSON values.
|
||||||
|
|
||||||
|
l = value.length;
|
||||||
|
for (i = 0; i < l; i += 1) {
|
||||||
|
a.push(stringify(value[i], whitelist) || 'null');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join all of the elements together and wrap them in brackets.
|
||||||
|
|
||||||
|
return '[' + a.join(',') + ']';
|
||||||
|
}
|
||||||
|
if (whitelist) {
|
||||||
|
|
||||||
|
// If a whitelist (array of keys) is provided, use it to select the components
|
||||||
|
// of the object.
|
||||||
|
|
||||||
|
l = whitelist.length;
|
||||||
|
for (i = 0; i < l; i += 1) {
|
||||||
|
k = whitelist[i];
|
||||||
|
if (typeof k === 'string') {
|
||||||
|
v = stringify(value[k], whitelist);
|
||||||
|
if (v) {
|
||||||
|
a.push(stringify(k) + ':' + v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Otherwise, iterate through all of the keys in the object.
|
||||||
|
|
||||||
|
for (k in value) {
|
||||||
|
if (typeof k === 'string') {
|
||||||
|
v = stringify(value[k], whitelist);
|
||||||
|
if (v) {
|
||||||
|
a.push(stringify(k) + ':' + v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join all of the member texts together and wrap them in braces.
|
||||||
|
|
||||||
|
return '{' + a.join(',') + '}';
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
stringify: stringify,
|
||||||
|
parse: function (text, filter) {
|
||||||
|
var j;
|
||||||
|
|
||||||
|
function walk(k, v) {
|
||||||
|
var i, n;
|
||||||
|
if (v && typeof v === 'object') {
|
||||||
|
for (i in v) {
|
||||||
|
if (Object.prototype.hasOwnProperty.apply(v, [i])) {
|
||||||
|
n = walk(i, v[i]);
|
||||||
|
if (n !== undefined) {
|
||||||
|
v[i] = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filter(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parsing happens in three stages. In the first stage, we run the text against
|
||||||
|
// regular expressions that look for non-JSON patterns. We are especially
|
||||||
|
// concerned with '()' and 'new' because they can cause invocation, and '='
|
||||||
|
// because it can cause mutation. But just to be safe, we want to reject all
|
||||||
|
// unexpected forms.
|
||||||
|
|
||||||
|
// We split the first stage into 4 regexp operations in order to work around
|
||||||
|
// crippling inefficiencies in IE's and Safari's regexp engines. First we
|
||||||
|
// replace all backslash pairs with '@' (a non-JSON character). Second, we
|
||||||
|
// replace all simple value tokens with ']' characters. Third, we delete all
|
||||||
|
// open brackets that follow a colon or comma or that begin the text. Finally,
|
||||||
|
// we look to see that the remaining characters are only whitespace or ']' or
|
||||||
|
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
|
||||||
|
|
||||||
|
if (/^[\],:{}\s]*$/.test(text.replace(/\\./g, '@').
|
||||||
|
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
|
||||||
|
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
|
||||||
|
|
||||||
|
// In the second stage we use the eval function to compile the text into a
|
||||||
|
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
|
||||||
|
// in JavaScript: it can begin a block or an object literal. We wrap the text
|
||||||
|
// in parens to eliminate the ambiguity.
|
||||||
|
|
||||||
|
j = eval('(' + text + ')');
|
||||||
|
|
||||||
|
// In the optional third stage, we recursively walk the new structure, passing
|
||||||
|
// each name/value pair to a filter function for possible transformation.
|
||||||
|
|
||||||
|
return typeof filter === 'function' ? walk('', j) : j;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the text is not JSON parseable, then a SyntaxError is thrown.
|
||||||
|
|
||||||
|
throw new SyntaxError('parseJSON');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
}
|
58
dom/src/json/test/pass1.json
Normal file
58
dom/src/json/test/pass1.json
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
[
|
||||||
|
"JSON Test Pattern pass1",
|
||||||
|
{"object with 1 member":["array with 1 element"]},
|
||||||
|
{},
|
||||||
|
[],
|
||||||
|
-42,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
"integer": 1234567890,
|
||||||
|
"real": -9876.543210,
|
||||||
|
"e": 0.123456789e-12,
|
||||||
|
"E": 1.234567890E+34,
|
||||||
|
"": 23456789012E66,
|
||||||
|
"zero": 0,
|
||||||
|
"one": 1,
|
||||||
|
"space": " ",
|
||||||
|
"quote": "\"",
|
||||||
|
"backslash": "\\",
|
||||||
|
"controls": "\b\f\n\r\t",
|
||||||
|
"slash": "/ & \/",
|
||||||
|
"alpha": "abcdefghijklmnopqrstuvwyz",
|
||||||
|
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
|
||||||
|
"digit": "0123456789",
|
||||||
|
"0123456789": "digit",
|
||||||
|
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
|
||||||
|
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
|
||||||
|
"true": true,
|
||||||
|
"false": false,
|
||||||
|
"null": null,
|
||||||
|
"array":[ ],
|
||||||
|
"object":{ },
|
||||||
|
"address": "50 St. James Street",
|
||||||
|
"url": "http://www.JSON.org/",
|
||||||
|
"comment": "// /* <!-- --",
|
||||||
|
"# -- --> */": " ",
|
||||||
|
" s p a c e d " :[1,2 , 3
|
||||||
|
|
||||||
|
,
|
||||||
|
|
||||||
|
4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
|
||||||
|
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
|
||||||
|
"quotes": "" \u0022 %22 0x22 034 "",
|
||||||
|
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
|
||||||
|
: "A key can be any string"
|
||||||
|
},
|
||||||
|
0.5 ,98.6
|
||||||
|
,
|
||||||
|
99.44
|
||||||
|
,
|
||||||
|
|
||||||
|
1066,
|
||||||
|
1e1,
|
||||||
|
0.1e1,
|
||||||
|
1e-1,
|
||||||
|
1e00,2e+00,2e-00
|
||||||
|
,"rosebud"]
|
7
dom/src/json/test/pass3.json
Normal file
7
dom/src/json/test/pass3.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"JSON Test Pattern pass3": {
|
||||||
|
"The outermost value": "must be an object or array.",
|
||||||
|
"In this test": "It is an object."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
19
dom/src/json/test/unit/head_json.js
Normal file
19
dom/src/json/test/unit/head_json.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
var Ci = Components.interfaces;
|
||||||
|
var Cc = Components.classes;
|
||||||
|
|
||||||
|
var nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
|
||||||
|
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
|
||||||
|
var workingDir = dirSvc.get("TmpD", Ci.nsIFile);
|
||||||
|
|
||||||
|
var outputName = "json-test-output";
|
||||||
|
var outputDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||||
|
outputDir.initWithFile(workingDir);
|
||||||
|
outputDir.append(outputName);
|
||||||
|
|
||||||
|
if (!outputDir.exists()) {
|
||||||
|
outputDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
|
||||||
|
} else if (!outputDir.isDirectory()) {
|
||||||
|
do_throw(outputName + " is not a directory?")
|
||||||
|
}
|
||||||
|
var JSON = null;
|
||||||
|
do_import_script("dom/src/json/test/json2.js");
|
161
dom/src/json/test/unit/test_decode.js
Normal file
161
dom/src/json/test/unit/test_decode.js
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
function decode_strings() {
|
||||||
|
// empty object
|
||||||
|
var x = nativeJSON.decode("{}");
|
||||||
|
do_check_eq(typeof x, "object");
|
||||||
|
|
||||||
|
// empty array
|
||||||
|
x = nativeJSON.decode("[]");
|
||||||
|
do_check_eq(typeof x, "object");
|
||||||
|
do_check_eq(x.length, 0);
|
||||||
|
do_check_eq(x.constructor, Array);
|
||||||
|
|
||||||
|
// one element array
|
||||||
|
x = nativeJSON.decode("[[]]");
|
||||||
|
do_check_eq(typeof x, "object");
|
||||||
|
do_check_eq(x.length, 1);
|
||||||
|
do_check_eq(x.constructor, Array);
|
||||||
|
do_check_eq(x[0].constructor, Array);
|
||||||
|
|
||||||
|
// multiple arrays
|
||||||
|
x = nativeJSON.decode("[[],[],[]]");
|
||||||
|
do_check_eq(typeof x, "object");
|
||||||
|
do_check_eq(x.length, 3);
|
||||||
|
do_check_eq(x.constructor, Array);
|
||||||
|
do_check_eq(x[0].constructor, Array);
|
||||||
|
do_check_eq(x[1].constructor, Array);
|
||||||
|
do_check_eq(x[2].constructor, Array);
|
||||||
|
|
||||||
|
// array key/value
|
||||||
|
x = nativeJSON.decode('{"foo":[]}');
|
||||||
|
do_check_eq(typeof x, "object");
|
||||||
|
do_check_eq(typeof x.foo, "object");
|
||||||
|
do_check_eq(x.foo.constructor, Array);
|
||||||
|
x = nativeJSON.decode('{"foo":[], "bar":[]}');
|
||||||
|
do_check_eq(typeof x, "object");
|
||||||
|
do_check_eq(typeof x.foo, "object");
|
||||||
|
do_check_eq(x.foo.constructor, Array);
|
||||||
|
do_check_eq(typeof x.bar, "object");
|
||||||
|
do_check_eq(x.bar.constructor, Array);
|
||||||
|
|
||||||
|
// nesting
|
||||||
|
x = nativeJSON.decode('{"foo":[{}]}');
|
||||||
|
do_check_eq(x.foo.constructor, Array);
|
||||||
|
do_check_eq(x.foo.length, 1);
|
||||||
|
do_check_eq(typeof x.foo[0], "object");
|
||||||
|
x = nativeJSON.decode('{"foo":[{"foo":[{"foo":{}}]}]}');
|
||||||
|
do_check_eq(x.foo[0].foo[0].foo.constructor, Object);
|
||||||
|
x = nativeJSON.decode('{"foo":[{"foo":[{"foo":[]}]}]}');
|
||||||
|
do_check_eq(x.foo[0].foo[0].foo.constructor, Array);
|
||||||
|
|
||||||
|
// strings
|
||||||
|
x = nativeJSON.decode('{"foo":"bar"}');
|
||||||
|
do_check_eq(x.foo, "bar");
|
||||||
|
x = nativeJSON.decode('["foo", "bar", "baz"]');
|
||||||
|
do_check_eq(x[0], "foo");
|
||||||
|
do_check_eq(x[1], "bar");
|
||||||
|
do_check_eq(x[2], "baz");
|
||||||
|
|
||||||
|
// numbers
|
||||||
|
x = nativeJSON.decode('{"foo":5.5, "bar":5}');
|
||||||
|
do_check_eq(x.foo, 5.5);
|
||||||
|
do_check_eq(x.bar, 5);
|
||||||
|
|
||||||
|
// keywords
|
||||||
|
x = nativeJSON.decode('{"foo": true, "bar":false, "baz":null}');
|
||||||
|
do_check_eq(x.foo, true);
|
||||||
|
do_check_eq(x.bar, false);
|
||||||
|
do_check_eq(x.baz, null);
|
||||||
|
|
||||||
|
// short escapes
|
||||||
|
x = nativeJSON.decode('{"foo": "\\"", "bar":"\\\\", "baz":"\\b","qux":"\\f", "quux":"\\n", "quuux":"\\r","quuuux":"\\t"}');
|
||||||
|
do_check_eq(x.foo, '"');
|
||||||
|
do_check_eq(x.bar, '\\');
|
||||||
|
do_check_eq(x.baz, '\b');
|
||||||
|
do_check_eq(x.qux, '\f');
|
||||||
|
do_check_eq(x.quux, "\n");
|
||||||
|
do_check_eq(x.quuux, "\r");
|
||||||
|
do_check_eq(x.quuuux, "\t");
|
||||||
|
|
||||||
|
// unicode escape
|
||||||
|
x = nativeJSON.decode('{"foo":"hmm\\u006dmm"}');
|
||||||
|
do_check_eq("hmm\u006dmm", x.foo);
|
||||||
|
|
||||||
|
x = nativeJSON.decode('{"JSON Test Pattern pass3": {"The outermost value": "must be an object or array.","In this test": "It is an object." }}');
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_files() {
|
||||||
|
function read_file(path) {
|
||||||
|
try {
|
||||||
|
var f = do_get_file(path);
|
||||||
|
var istream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
|
||||||
|
istream.init(f, -1, -1, false);
|
||||||
|
var x = nativeJSON.decodeFromStream(istream, istream.available());
|
||||||
|
} finally {
|
||||||
|
istream.close();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
var x = read_file("/dom/src/json/test/pass3.json");
|
||||||
|
do_check_eq(x["JSON Test Pattern pass3"]["The outermost value"], "must be an object or array.");
|
||||||
|
do_check_eq(x["JSON Test Pattern pass3"]["In this test"], "It is an object.");
|
||||||
|
|
||||||
|
x = read_file("/dom/src/json/test/pass1.json");
|
||||||
|
do_check_eq(x[0], "JSON Test Pattern pass1");
|
||||||
|
do_check_eq(x[1]["object with 1 member"][0], "array with 1 element");
|
||||||
|
do_check_eq(x[2].constructor, Object);
|
||||||
|
do_check_eq(x[3].constructor, Array);
|
||||||
|
do_check_eq(x[4], -42);
|
||||||
|
do_check_eq(x[5], true);
|
||||||
|
do_check_eq(x[6], false);
|
||||||
|
do_check_eq(x[7], null);
|
||||||
|
do_check_eq(x[8].constructor, Object);
|
||||||
|
do_check_eq(x[8]["integer"], 1234567890);
|
||||||
|
do_check_eq(x[8]["real"], -9876.543210);
|
||||||
|
do_check_eq(x[8]["e"], 0.123456789e-12);
|
||||||
|
do_check_eq(x[8]["E"], 1.234567890E+34);
|
||||||
|
do_check_eq(x[8][""], 23456789012E66);
|
||||||
|
do_check_eq(x[8]["zero"], 0);
|
||||||
|
do_check_eq(x[8]["one"], 1);
|
||||||
|
do_check_eq(x[8]["space"], " ");
|
||||||
|
do_check_eq(x[8]["quote"], "\"");
|
||||||
|
do_check_eq(x[8]["backslash"], "\\");
|
||||||
|
do_check_eq(x[8]["controls"], "\b\f\n\r\t");
|
||||||
|
do_check_eq(x[8]["slash"], "/ & /");
|
||||||
|
do_check_eq(x[8]["alpha"], "abcdefghijklmnopqrstuvwyz");
|
||||||
|
do_check_eq(x[8]["ALPHA"], "ABCDEFGHIJKLMNOPQRSTUVWYZ");
|
||||||
|
do_check_eq(x[8]["digit"], "0123456789");
|
||||||
|
do_check_eq(x[8]["0123456789"], "digit");
|
||||||
|
do_check_eq(x[8]["special"], "`1~!@#$%^&*()_+-={':[,]}|;.</>?");
|
||||||
|
do_check_eq(x[8]["hex"], "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A");
|
||||||
|
do_check_eq(x[8]["true"], true);
|
||||||
|
do_check_eq(x[8]["false"], false);
|
||||||
|
do_check_eq(x[8]["null"], null);
|
||||||
|
do_check_eq(x[8]["array"].length, 0);
|
||||||
|
do_check_eq(x[8]["object"].constructor, Object);
|
||||||
|
do_check_eq(x[8]["address"], "50 St. James Street");
|
||||||
|
do_check_eq(x[8]["url"], "http://www.JSON.org/");
|
||||||
|
do_check_eq(x[8]["comment"], "// /* <!-- --");
|
||||||
|
do_check_eq(x[8]["# -- --> */"], " ");
|
||||||
|
do_check_eq(x[8][" s p a c e d "].length, 7);
|
||||||
|
do_check_eq(x[8]["compact"].length, 7);
|
||||||
|
do_check_eq(x[8]["jsontext"], "{\"object with 1 member\":[\"array with 1 element\"]}");
|
||||||
|
do_check_eq(x[8]["quotes"], "" \u0022 %22 0x22 034 "");
|
||||||
|
do_check_eq(x[8]["\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"], "A key can be any string");
|
||||||
|
do_check_eq(x[9], 0.5);
|
||||||
|
do_check_eq(x[10], 98.6);
|
||||||
|
do_check_eq(x[11], 99.44);
|
||||||
|
do_check_eq(x[12], 1066);
|
||||||
|
do_check_eq(x[13], 1e1);
|
||||||
|
do_check_eq(x[14], 0.1e1);
|
||||||
|
do_check_eq(x[15], 1e-1);
|
||||||
|
do_check_eq(x[16], 1e00);
|
||||||
|
do_check_eq(x[17], 2e+00);
|
||||||
|
do_check_eq(x[18], 2e-00);
|
||||||
|
do_check_eq(x[19], "rosebud");
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
decode_strings();
|
||||||
|
test_files();
|
||||||
|
}
|
237
dom/src/json/test/unit/test_encode.js
Normal file
237
dom/src/json/test/unit/test_encode.js
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
// returns a list of [string, object] pairs to test encoding
|
||||||
|
function getTestPairs() {
|
||||||
|
var testPairs = [
|
||||||
|
["{}", {}],
|
||||||
|
["[]", []],
|
||||||
|
['{"foo":"bar"}', {"foo":"bar"}],
|
||||||
|
['{"null":null}', {"null":null}],
|
||||||
|
['{"five":5}', {"five":5}],
|
||||||
|
['{"five":5,"six":6}', {"five":5, "six":6}],
|
||||||
|
['{"x":{"y":"z"}}', {"x":{"y":"z"}}],
|
||||||
|
['{"w":{"x":{"y":"z"}}}', {"w":{"x":{"y":"z"}}}],
|
||||||
|
['[1,2,3]', [1,2,3]],
|
||||||
|
['{"w":{"x":{"y":[1,2,3]}}}', {"w":{"x":{"y":[1,2,3]}}}],
|
||||||
|
['{"false":false}', {"false":false}],
|
||||||
|
['{"true":true}', {"true":true}],
|
||||||
|
['{"child has two members":{"this":"one","2":"and this one"}}',
|
||||||
|
{"child has two members": {"this":"one", 2:"and this one"}}],
|
||||||
|
['{"x":{"a":"b","c":{"y":"z"},"f":"g"}}',
|
||||||
|
{"x":{"a":"b","c":{"y":"z"},"f":"g"}}],
|
||||||
|
['{"x":[1,{"y":"z"},3]}', {"x":[1,{"y":"z"},3]}],
|
||||||
|
//['{"0":"h","1":"m","2":"m"}', new String("hmm")],
|
||||||
|
['[1,null,3]',[1,,3]],
|
||||||
|
[null, function test(){}],
|
||||||
|
[null, dump],
|
||||||
|
['{"mm\\\"mm":"hmm"}',{"mm\"mm":"hmm"}],
|
||||||
|
['{"mm\\\"mm\\\"mm":"hmm"}',{"mm\"mm\"mm":"hmm"}],
|
||||||
|
['{"\\\"":"hmm"}',{'"':"hmm"}],
|
||||||
|
['{"\\\\":"hmm"}',{'\\':"hmm"}],
|
||||||
|
['{"mmm\\\\mmm":"hmm"}',{'mmm\\mmm':"hmm"}],
|
||||||
|
['{"mmm\\\\mmm\\\\mmm":"hmm"}',{'mmm\\mmm\\mmm':"hmm"}],
|
||||||
|
['{"mm\\u000bmm":"hmm"}',{"mm\u000bmm":"hmm"}],
|
||||||
|
['{"mm\\u0000mm":"hmm"}',{"mm\u0000mm":"hmm"}]
|
||||||
|
];
|
||||||
|
|
||||||
|
var x = {"free":"variable"}
|
||||||
|
testPairs.push(['{"free":"variable"}', x]);
|
||||||
|
testPairs.push(['{"y":{"free":"variable"}}', {"y":x}]);
|
||||||
|
|
||||||
|
// array prop
|
||||||
|
var x = {
|
||||||
|
a: [1,2,3]
|
||||||
|
}
|
||||||
|
testPairs.push(['{"a":[1,2,3]}', x])
|
||||||
|
|
||||||
|
var y = {
|
||||||
|
foo: function(hmm) { return hmm; }
|
||||||
|
}
|
||||||
|
testPairs.push(['{"y":{}}',{"y":y}]);
|
||||||
|
|
||||||
|
// test toJSON
|
||||||
|
var hmm = {
|
||||||
|
toJSON: function() { return {"foo":"bar"}}
|
||||||
|
}
|
||||||
|
testPairs.push(['{"hmm":{"foo":"bar"}}', {"hmm":hmm}]);
|
||||||
|
testPairs.push(['{"foo":"bar"}', hmm]); // on the root
|
||||||
|
|
||||||
|
// toJSON on prototype
|
||||||
|
var Y = function() {
|
||||||
|
this.d = "e";
|
||||||
|
}
|
||||||
|
Y.prototype = {
|
||||||
|
not:"there?",
|
||||||
|
toJSON: function() { return {"foo":"bar"}}
|
||||||
|
};
|
||||||
|
var y = new Y();
|
||||||
|
testPairs.push(['{"foo":"bar"}', y.toJSON()]);
|
||||||
|
testPairs.push(['{"foo":"bar"}', y]);
|
||||||
|
|
||||||
|
// return undefined from toJSON
|
||||||
|
var hmm = {
|
||||||
|
toJSON: function() { return; }
|
||||||
|
}
|
||||||
|
testPairs.push(['{}', {"hmm":hmm}]);
|
||||||
|
|
||||||
|
// array with named prop
|
||||||
|
var x= new Array();
|
||||||
|
x[0] = 1;
|
||||||
|
x.foo = "bar";
|
||||||
|
//testPairs.push(['[1]', x]);
|
||||||
|
|
||||||
|
// prototype
|
||||||
|
var X = function() { this.a = "b" }
|
||||||
|
X.prototype = {c:"d"}
|
||||||
|
var y = new X();
|
||||||
|
testPairs.push(['{"a":"b","c":"d"}', y]);
|
||||||
|
|
||||||
|
// useless roots will be dropped
|
||||||
|
testPairs.push([null, null]);
|
||||||
|
testPairs.push([null, ""]);
|
||||||
|
testPairs.push([null, undefined]);
|
||||||
|
testPairs.push([null, 5]);
|
||||||
|
|
||||||
|
// custom iterator: JS 1.7+
|
||||||
|
var x = {
|
||||||
|
"a": "foo",
|
||||||
|
b: "not included",
|
||||||
|
c: "bar",
|
||||||
|
"4": "qux",
|
||||||
|
__iterator__: function() { return (function() { yield "a"; yield "c"; yield 4; })() }
|
||||||
|
}
|
||||||
|
do_check_eq('{"a":"foo","c":"bar","4":"qux"}', nativeJSON.encode(x));
|
||||||
|
|
||||||
|
return testPairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testStringEncode() {
|
||||||
|
// test empty arg
|
||||||
|
do_check_eq(null, nativeJSON.encode());
|
||||||
|
|
||||||
|
var pairs = getTestPairs();
|
||||||
|
for each(pair in pairs) {
|
||||||
|
var nativeResult = nativeJSON.encode(pair[1]);
|
||||||
|
var crockfordResult = JSON.stringify(pair[1]);
|
||||||
|
do_check_eq(pair[0], nativeResult);
|
||||||
|
|
||||||
|
// Don't follow json2.js handling of non-objects
|
||||||
|
if (pair[1] && (typeof pair[1] == "object")) {
|
||||||
|
do_check_eq(crockfordResult, nativeResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testOutputStreams() {
|
||||||
|
function writeToFile(obj, charset, writeBOM) {
|
||||||
|
var jsonFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||||
|
jsonFile.initWithFile(outputDir);
|
||||||
|
jsonFile.append("test.json");
|
||||||
|
jsonFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
|
||||||
|
var stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
|
||||||
|
try {
|
||||||
|
stream.init(jsonFile, 0x04 | 0x08 | 0x20, 0600, 0); // write, create, truncate
|
||||||
|
nativeJSON.encodeToStream(stream, charset, writeBOM, obj);
|
||||||
|
} finally {
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
return jsonFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pairs = getTestPairs();
|
||||||
|
for each(pair in pairs) {
|
||||||
|
if (pair[1] && (typeof pair[1] == "object")) {
|
||||||
|
var utf8File = writeToFile(pair[1], "UTF-8", false);
|
||||||
|
var utf16LEFile = writeToFile(pair[1], "UTF-16LE", false);
|
||||||
|
var utf16BEFile = writeToFile(pair[1], "UTF-16BE", false);
|
||||||
|
var utf32LEFile = writeToFile(pair[1], "UTF-32LE", false);
|
||||||
|
var utf32BEFile = writeToFile(pair[1], "UTF-32BE", false);
|
||||||
|
|
||||||
|
// all ascii with no BOMs, so this will work
|
||||||
|
do_check_eq(utf16LEFile.fileSize / 2, utf8File.fileSize);
|
||||||
|
do_check_eq(utf32LEFile.fileSize / 4, utf8File.fileSize);
|
||||||
|
do_check_eq(utf16LEFile.fileSize, utf16BEFile.fileSize);
|
||||||
|
do_check_eq(utf32LEFile.fileSize, utf32BEFile.fileSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check BOMs
|
||||||
|
var f = writeToFile({},"UTF-8", true);
|
||||||
|
do_check_eq(f.fileSize, 5);
|
||||||
|
var f = writeToFile({},"UTF-16LE", true);
|
||||||
|
do_check_eq(f.fileSize, 6);
|
||||||
|
var f = writeToFile({},"UTF-16BE", true);
|
||||||
|
do_check_eq(f.fileSize, 6);
|
||||||
|
var f = writeToFile({},"UTF-32LE", true);
|
||||||
|
do_check_eq(f.fileSize, 12);
|
||||||
|
var f = writeToFile({},"UTF-32BE", true);
|
||||||
|
do_check_eq(f.fileSize, 12);
|
||||||
|
|
||||||
|
outputDir.remove(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function throwingToJSON() {
|
||||||
|
var a = {
|
||||||
|
"b": 1,
|
||||||
|
"c": 2,
|
||||||
|
toJSON: function() { throw("uh oh"); }
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var y = nativeJSON.encode(a);
|
||||||
|
} catch (ex) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function throwingIterator() {
|
||||||
|
var a = {
|
||||||
|
"b": 1,
|
||||||
|
"c": 2,
|
||||||
|
__iterator__: function() { yield "b"; throw("uh oh"); }
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var y = nativeJSON.encode(a);
|
||||||
|
} catch (ex) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deletingIter(x) {
|
||||||
|
return function() {
|
||||||
|
yield "dd";
|
||||||
|
print("after first yield");
|
||||||
|
delete x["a"]["c"];
|
||||||
|
gc();
|
||||||
|
print("about to yield second");
|
||||||
|
yield "ddddd";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteDuringEncode() {
|
||||||
|
var x = {};
|
||||||
|
x.a = {
|
||||||
|
b: 1,
|
||||||
|
bb: 2,
|
||||||
|
bbb: 3,
|
||||||
|
c: {
|
||||||
|
cc: 2,
|
||||||
|
ccc: 3,
|
||||||
|
d: {
|
||||||
|
dd: 2,
|
||||||
|
ddd: 3,
|
||||||
|
__iterator__: deletingIter(x),
|
||||||
|
dddd: 4,
|
||||||
|
ddddd: 5
|
||||||
|
},
|
||||||
|
cccc: 4,
|
||||||
|
ccccc: 5
|
||||||
|
},
|
||||||
|
bbbb: 4,
|
||||||
|
bbbbb: 5,
|
||||||
|
bbbbbb: 6
|
||||||
|
};
|
||||||
|
var z = nativeJSON.encode(x);
|
||||||
|
print(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
testStringEncode();
|
||||||
|
testOutputStreams();
|
||||||
|
throwingToJSON();
|
||||||
|
throwingIterator();
|
||||||
|
deleteDuringEncode();
|
||||||
|
}
|
@ -136,6 +136,7 @@ EXPORTS = \
|
|||||||
jsdate.h \
|
jsdate.h \
|
||||||
jsdbgapi.h \
|
jsdbgapi.h \
|
||||||
jsdhash.h \
|
jsdhash.h \
|
||||||
|
jsdtoa.h \
|
||||||
jsemit.h \
|
jsemit.h \
|
||||||
jsfun.h \
|
jsfun.h \
|
||||||
jsgc.h \
|
jsgc.h \
|
||||||
|
@ -328,7 +328,7 @@ js_GetNativeIteratorFlags(JSContext *cx, JSObject *iterobj)
|
|||||||
* Call ToObject(v).__iterator__(keyonly) if ToObject(v).__iterator__ exists.
|
* Call ToObject(v).__iterator__(keyonly) if ToObject(v).__iterator__ exists.
|
||||||
* Otherwise construct the defualt iterator.
|
* Otherwise construct the defualt iterator.
|
||||||
*/
|
*/
|
||||||
JSBool
|
JS_FRIEND_API(JSBool)
|
||||||
js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp)
|
js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp)
|
||||||
{
|
{
|
||||||
JSObject *obj;
|
JSObject *obj;
|
||||||
@ -439,7 +439,7 @@ js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSBool
|
JS_FRIEND_API(JSBool)
|
||||||
js_CloseIterator(JSContext *cx, jsval v)
|
js_CloseIterator(JSContext *cx, jsval v)
|
||||||
{
|
{
|
||||||
JSObject *obj;
|
JSObject *obj;
|
||||||
@ -593,7 +593,7 @@ CallEnumeratorNext(JSContext *cx, JSObject *iterobj, uintN flags, jsval *rval)
|
|||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSBool
|
JS_FRIEND_API(JSBool)
|
||||||
js_CallIteratorNext(JSContext *cx, JSObject *iterobj, jsval *rval)
|
js_CallIteratorNext(JSContext *cx, JSObject *iterobj, jsval *rval)
|
||||||
{
|
{
|
||||||
uintN flags;
|
uintN flags;
|
||||||
|
@ -58,17 +58,17 @@ JS_BEGIN_EXTERN_C
|
|||||||
* for-in semantics are required, and when the caller can guarantee that the
|
* for-in semantics are required, and when the caller can guarantee that the
|
||||||
* iterator will never be exposed to scripts.
|
* iterator will never be exposed to scripts.
|
||||||
*/
|
*/
|
||||||
extern JSBool
|
extern JS_FRIEND_API(JSBool)
|
||||||
js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp);
|
js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp);
|
||||||
|
|
||||||
extern JSBool
|
extern JS_FRIEND_API(JSBool)
|
||||||
js_CloseIterator(JSContext *cx, jsval v);
|
js_CloseIterator(JSContext *cx, jsval v);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given iterobj, call iterobj.next(). If the iterator stopped, set *rval to
|
* Given iterobj, call iterobj.next(). If the iterator stopped, set *rval to
|
||||||
* JSVAL_HOLE. Otherwise set it to the result of the next call.
|
* JSVAL_HOLE. Otherwise set it to the result of the next call.
|
||||||
*/
|
*/
|
||||||
extern JSBool
|
extern JS_FRIEND_API(JSBool)
|
||||||
js_CallIteratorNext(JSContext *cx, JSObject *iterobj, jsval *rval);
|
js_CallIteratorNext(JSContext *cx, JSObject *iterobj, jsval *rval);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -141,6 +141,7 @@ SHARED_LIBRARY_LIBS = \
|
|||||||
$(DEPTH)/view/src/$(LIB_PREFIX)gkview_s.$(LIB_SUFFIX) \
|
$(DEPTH)/view/src/$(LIB_PREFIX)gkview_s.$(LIB_SUFFIX) \
|
||||||
$(DEPTH)/dom/src/base/$(LIB_PREFIX)jsdombase_s.$(LIB_SUFFIX) \
|
$(DEPTH)/dom/src/base/$(LIB_PREFIX)jsdombase_s.$(LIB_SUFFIX) \
|
||||||
$(DEPTH)/dom/src/events/$(LIB_PREFIX)jsdomevents_s.$(LIB_SUFFIX) \
|
$(DEPTH)/dom/src/events/$(LIB_PREFIX)jsdomevents_s.$(LIB_SUFFIX) \
|
||||||
|
$(DEPTH)/dom/src/json/$(LIB_PREFIX)json_s.$(LIB_SUFFIX) \
|
||||||
$(DEPTH)/dom/src/jsurl/$(LIB_PREFIX)jsurl_s.$(LIB_SUFFIX) \
|
$(DEPTH)/dom/src/jsurl/$(LIB_PREFIX)jsurl_s.$(LIB_SUFFIX) \
|
||||||
$(DEPTH)/dom/src/storage/$(LIB_PREFIX)jsdomstorage_s.$(LIB_SUFFIX) \
|
$(DEPTH)/dom/src/storage/$(LIB_PREFIX)jsdomstorage_s.$(LIB_SUFFIX) \
|
||||||
$(DEPTH)/dom/src/offline/$(LIB_PREFIX)jsdomoffline_s.$(LIB_SUFFIX) \
|
$(DEPTH)/dom/src/offline/$(LIB_PREFIX)jsdomoffline_s.$(LIB_SUFFIX) \
|
||||||
@ -277,6 +278,7 @@ LOCAL_INCLUDES += -I$(srcdir)/../base \
|
|||||||
-I$(topsrcdir)/content/xbl/src \
|
-I$(topsrcdir)/content/xbl/src \
|
||||||
-I$(topsrcdir)/view/src \
|
-I$(topsrcdir)/view/src \
|
||||||
-I$(topsrcdir)/dom/src/base \
|
-I$(topsrcdir)/dom/src/base \
|
||||||
|
-I$(topsrcdir)/dom/src/json \
|
||||||
-I$(topsrcdir)/dom/src/jsurl \
|
-I$(topsrcdir)/dom/src/jsurl \
|
||||||
-I$(topsrcdir)/dom/src/storage \
|
-I$(topsrcdir)/dom/src/storage \
|
||||||
-I$(topsrcdir)/dom/src/offline \
|
-I$(topsrcdir)/dom/src/offline \
|
||||||
|
@ -222,4 +222,7 @@
|
|||||||
#define NS_XULPOPUPMANAGER_CID \
|
#define NS_XULPOPUPMANAGER_CID \
|
||||||
{ 0x14632191, 0xac21, 0x4bdf, { 0x83, 0xe7, 0x23, 0x63, 0xad, 0x17, 0xe8, 0x38 } }
|
{ 0x14632191, 0xac21, 0x4bdf, { 0x83, 0xe7, 0x23, 0x63, 0xad, 0x17, 0xe8, 0x38 } }
|
||||||
|
|
||||||
|
// {93ad72a6-02cd-4716-9626-d47d5ec275ec}
|
||||||
|
#define NS_DOMJSON_CID \
|
||||||
|
{ 0x93ad72a6, 0x02cd, 0x4716, { 0x96, 0x26, 0xd4, 0x7d, 0x5e, 0xc2, 0x75, 0xec } }
|
||||||
#endif /* nsLayoutCID_h__ */
|
#endif /* nsLayoutCID_h__ */
|
||||||
|
@ -125,6 +125,7 @@
|
|||||||
#include "nsIControllerContext.h"
|
#include "nsIControllerContext.h"
|
||||||
#include "nsDOMScriptObjectFactory.h"
|
#include "nsDOMScriptObjectFactory.h"
|
||||||
#include "nsDOMStorage.h"
|
#include "nsDOMStorage.h"
|
||||||
|
#include "nsJSON.h"
|
||||||
|
|
||||||
// Editor stuff
|
// Editor stuff
|
||||||
#include "nsEditorCID.h"
|
#include "nsEditorCID.h"
|
||||||
@ -1321,6 +1322,11 @@ static const nsModuleComponentInfo gComponents[] = {
|
|||||||
"@mozilla.org/dom/storagemanager;1",
|
"@mozilla.org/dom/storagemanager;1",
|
||||||
nsDOMStorageManagerConstructor },
|
nsDOMStorageManagerConstructor },
|
||||||
|
|
||||||
|
{ "DOM JSON",
|
||||||
|
NS_DOMJSON_CID,
|
||||||
|
"@mozilla.org/dom/json;1",
|
||||||
|
NS_NewJSON },
|
||||||
|
|
||||||
{ "Text Editor",
|
{ "Text Editor",
|
||||||
NS_TEXTEDITOR_CID,
|
NS_TEXTEDITOR_CID,
|
||||||
"@mozilla.org/editor/texteditor;1",
|
"@mozilla.org/editor/texteditor;1",
|
||||||
|
@ -463,34 +463,8 @@ static nsresult GetCharsetFromData(const unsigned char* aStyleSheetData,
|
|||||||
step = 1;
|
step = 1;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
else if (aStyleSheetData[0] == 0xEF &&
|
|
||||||
aStyleSheetData[1] == 0xBB &&
|
|
||||||
aStyleSheetData[2] == 0xBF) {
|
|
||||||
// UTF-8 BOM
|
|
||||||
step = 1;
|
|
||||||
pos = 3;
|
|
||||||
aCharset = "UTF-8";
|
|
||||||
}
|
|
||||||
// Check for a 4-byte encoding BOM before checking for a 2-byte one,
|
// Check for a 4-byte encoding BOM before checking for a 2-byte one,
|
||||||
// since the latter can be a proper subset of the former.
|
// since the latter can be a proper subset of the former.
|
||||||
else if (aStyleSheetData[0] == 0x00 &&
|
|
||||||
aStyleSheetData[1] == 0x00 &&
|
|
||||||
aStyleSheetData[2] == 0xFE &&
|
|
||||||
aStyleSheetData[3] == 0xFF) {
|
|
||||||
// big-endian 4-byte encoding BOM
|
|
||||||
step = 4;
|
|
||||||
pos = 7;
|
|
||||||
aCharset = "UTF-32BE";
|
|
||||||
}
|
|
||||||
else if (aStyleSheetData[0] == 0xFF &&
|
|
||||||
aStyleSheetData[1] == 0xFE &&
|
|
||||||
aStyleSheetData[2] == 0x00 &&
|
|
||||||
aStyleSheetData[3] == 0x00) {
|
|
||||||
// little-endian 4-byte encoding BOM
|
|
||||||
step = 4;
|
|
||||||
pos = 4;
|
|
||||||
aCharset = "UTF-32LE";
|
|
||||||
}
|
|
||||||
else if (aStyleSheetData[0] == 0x00 &&
|
else if (aStyleSheetData[0] == 0x00 &&
|
||||||
aStyleSheetData[1] == 0x00 &&
|
aStyleSheetData[1] == 0x00 &&
|
||||||
aStyleSheetData[2] == 0xFF &&
|
aStyleSheetData[2] == 0xFF &&
|
||||||
@ -511,17 +485,28 @@ static nsresult GetCharsetFromData(const unsigned char* aStyleSheetData,
|
|||||||
pos = 5;
|
pos = 5;
|
||||||
aCharset = "UTF-32";
|
aCharset = "UTF-32";
|
||||||
}
|
}
|
||||||
else if (aStyleSheetData[0] == 0xFE && aStyleSheetData[1] == 0xFF) {
|
else if (nsContentUtils::CheckForBOM(aStyleSheetData,
|
||||||
// big-endian 2-byte encoding BOM
|
aDataLength, aCharset)) {
|
||||||
step = 2;
|
if (aCharset.Equals("UTF-8")) {
|
||||||
pos = 3;
|
step = 1;
|
||||||
aCharset = "UTF-16BE";
|
pos = 3;
|
||||||
}
|
}
|
||||||
else if (aStyleSheetData[0] == 0xFF && aStyleSheetData[1] == 0xFE) {
|
else if (aCharset.Equals("UTF-32BE")) {
|
||||||
// little-endian 2-byte encoding BOM
|
step = 4;
|
||||||
step = 2;
|
pos = 7;
|
||||||
pos = 2;
|
}
|
||||||
aCharset = "UTF-16LE";
|
else if (aCharset.Equals("UTF-32LE")) {
|
||||||
|
step = 4;
|
||||||
|
pos = 4;
|
||||||
|
}
|
||||||
|
else if (aCharset.Equals("UTF-16BE")) {
|
||||||
|
step = 2;
|
||||||
|
pos = 3;
|
||||||
|
}
|
||||||
|
else if (aCharset.Equals("UTF-16LE")) {
|
||||||
|
step = 2;
|
||||||
|
pos = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (aStyleSheetData[0] == 0x00 &&
|
else if (aStyleSheetData[0] == 0x00 &&
|
||||||
aStyleSheetData[1] == 0x00 &&
|
aStyleSheetData[1] == 0x00 &&
|
||||||
|
@ -111,7 +111,7 @@ done
|
|||||||
for t in $testdir/test_*.js
|
for t in $testdir/test_*.js
|
||||||
do
|
do
|
||||||
echo -n "$t: "
|
echo -n "$t: "
|
||||||
NATIVE_TOPSRCDIR="$native_topsrcdir" TOPSRCDIR="$topsrcdir" $xpcshell -s $headfiles -f $t $tailfiles 2> $t.log 1>&2
|
NATIVE_TOPSRCDIR="$native_topsrcdir" TOPSRCDIR="$topsrcdir" $xpcshell -v 180 -s $headfiles -f $t $tailfiles 2> $t.log 1>&2
|
||||||
rv="$?"
|
rv="$?"
|
||||||
if [ ! "$rv" = "0" -o \
|
if [ ! "$rv" = "0" -o \
|
||||||
`grep -c '\*\*\* PASS' $t.log` = 0 ]
|
`grep -c '\*\*\* PASS' $t.log` = 0 ]
|
||||||
|
Loading…
Reference in New Issue
Block a user