Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'json_optimization'

  • Loading branch information...
commit cc66f99a0d9bfce46b437f51acd16014ba890367 2 parents c99a4ea + 064139a
@darronschall darronschall authored
Showing with 636 additions and 621 deletions.
  1. +3 −0  .gitignore
  2. +7 −35 build/build.properties
  3. +145 −77 build/build.xml
  4. BIN  build/libs/flexUnitTasks-4.0.0.jar
  5. BIN  build/libs/flexunit-4.0.0.swc
  6. BIN  build/libs/flexunit-aircilistener-4.0.0.swc
  7. BIN  build/libs/flexunit-cilistener-4.0.0.swc
  8. BIN  build/libs/flexunit-flexcoverlistener-4.0.0.swc
  9. BIN  build/libs/flexunit-uilistener-4.0.0.swc
  10. +1 −1  src/com/adobe/air/crypto/EncryptionKeyGenerator.as
  11. +1 −1  src/com/adobe/net/IURIResolver.as
  12. +5 −5 src/com/adobe/net/URI.as
  13. +6 −6 src/com/adobe/serialization/json/JSON.as
  14. +84 −59 src/com/adobe/serialization/json/JSONDecoder.as
  15. +84 −73 src/com/adobe/serialization/json/JSONEncoder.as
  16. +15 −10 src/com/adobe/serialization/json/JSONParseError.as
  17. +28 −40 src/com/adobe/serialization/json/JSONToken.as
  18. +0 −69 src/com/adobe/serialization/json/JSONTokenType.as
  19. +101 −95 src/com/adobe/serialization/json/JSONTokenizer.as
  20. +98 −0 tests/src/AllCoreLibTests.as
  21. +0 −138 tests/src/CoreLibTestRunner.as
  22. +40 −12 tests/src/CoreLibTestRunner.mxml
  23. +18 −0 tests/src/com/adobe/serialization/json/JSONTest.as
View
3  .gitignore
@@ -15,6 +15,9 @@ profile
.settings
bin/*
bin-debug/*
+report/*
+bin-test/*
+docs/*
.flexLibProperties
#Java Noise
View
42 build/build.properties
@@ -1,48 +1,20 @@
-# -----------------------------------------------------------------
-# User-Defined Paths
-#
-# Modify these path values to reflect paths on your system
-# -----------------------------------------------------------------
-
-# The path to the flexunit.swc -- Required when trying to build/run unit
-# tests for this library. The below path assumes there's an "as3flexunitlib"
-# folder along side of this library's root folder, with the .swc file in the
-# bin subdirectory.
-flexunit.swc = ${basedir}/../as3flexunitlib/bin/as3flexunitlib.swc
-
-# The location of the Flex 2 SDK on your sytem.
-flex2sdk.bin.dir = C:/Program Files/Adobe/Flex Builder 2 Plug-in/Flex SDK 2/bin
-flex2sdk.lib.dir = C:/Program Files/Adobe/Flex Builder 2 Plug-in/Flex SDK 2/frameworks/libs
-
-# Note that the locale dir uses the {locale} token at the end to specify the directory
-# of language-specific files. This is replaced by the compiler with the locale defined
-# by the locale property below.
-flex2sdk.locale = en_US
-flex2sdk.locale.dir = C:/Program Files/Adobe/Flex Builder 2 Plug-in/Flex SDK 2/frameworks/locale/{locale}
-
-#note we have to use aasdoc since the library not includes some AIR files.
-asdoc.exe = aasdoc
-compc.exe = ${flex2sdk.bin.dir}/compc.exe
-mxmlc.exe = ${flex2sdk.bin.dir}/mxmlc.exe
-
-# The debug player is necessary here because it writes trace statements to a flashlog.txt
-# file. This allows us to examine the .txt file and determine the status of unit tests
-# in an automated fashion.
-flashDebugPlayer.exe = C:/Program Files/Adobe/Flex Builder 2 Plug-in/Player/debug/SAFlashPlayer.exe
# -----------------------------------------------------------------
# File Names - DO NOT MODIFY
# -----------------------------------------------------------------
-testRunner.dir = .
-testRunner.name = CoreLibTestRunner
+test.application.name = CoreLibTestRunner
-library.name = corelib
+library.name = as3corelib
# -----------------------------------------------------------------
# Project Paths - DO NOT MODIFY
# -----------------------------------------------------------------
build.dir = ${basedir}/build
+build.libs.dir = ${basedir}/build/libs
src.dir = ${basedir}/src
-tests.dir = ${basedir}/tests
+test.src.dir = ${basedir}/tests/src
bin.dir = ${basedir}/bin
+test.bin.dir = ${basedir}/bin-test
+report.dir = ${basedir}/report
+report.html.dir = ${basedir}/report/html
docs.dir = ${basedir}/docs
View
222 build/build.xml
@@ -1,104 +1,172 @@
<?xml version="1.0"?>
-<project name="as3corelib" basedir="../" default="lib">
+<project name="as3corelib" basedir="../" default="compile">
- <!-- Define variables/paths used in this build script -->
- <property file="./build/build.properties" />
+ <!-- ============================== -->
+ <!-- Configuration -->
+ <!-- ============================== -->
- <!--
- Have you edit the properties file to make sure the paths are right oo your system?
- -->
- <target name="properties">
- <fail unless="asdoc.exe">The "asdoc.exe" property must be set in ${build.dir}/build.properties.</fail>
- <fail unless="compc.exe">The "compc.exe" property must be set in ${build.dir}/build.properties.</fail>
- <fail unless="mxmlc.exe">The "mxmlc.exe" property must be set in ${build.dir}/build.properties.</fail>
+ <property environment="env" />
+
+ <fail unless="env.FLEX_HOME" message="FLEX_HOME needs to be defined as an environment variable or in the Ant build." />
+
+ <!-- Configuration -->
+ <property file="${basedir}/build/build.properties" />
+
+ <!-- Setup Flex Ant Resources -->
+ <!--property name="FLEX_HOME" location="${flex.sdk}" /-->
+ <property name="FLEX_HOME" location="${env.FLEX_HOME}" />
+ <taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
+
+ <!-- ============================== -->
+ <!-- Clean and Init Targets -->
+ <!-- ============================== -->
+
+ <target name="clean" description="Removes artifacts from previous builds">
+ <delete includeemptydirs="true" failonerror="false">
+ <fileset dir="${bin.dir}" defaultexcludes="false">
+ <include name="**/*" />
+ </fileset>
+ <fileset dir="${test.bin.dir}" defaultexcludes="false">
+ <include name="**/*" />
+ </fileset>
+ <fileset dir="${docs.dir}" defaultexcludes="false">
+ <include name="**/*" />
+ </fileset>
+ <fileset dir="${report.dir}" defaultexcludes="false">
+ <include name="**/*" />
+ </fileset>
+ </delete>
</target>
+
+ <target name="init" description="Initializes project and destination folders">
+ <echo message="Project: ${ant.project.name}" />
+ <echo message="Flex SDK: ${FLEX_HOME}" />
+
+ <!-- Create direectories -->
+ <mkdir dir="${bin.dir}" />
+ <mkdir dir="${test.bin.dir}" />
+ <mkdir dir="${docs.dir}" />
+ <mkdir dir="${report.dir}" />
+ </target>
- <!--
- Compile the unit tests for the library, placing the test runner .swf file
- in the bin directory.
- -->
- <target name="compileTests" depends="properties">
- <exec executable="${mxmlc.exe}" dir="${basedir}">
- <!-- Point to the main test runner's application mxml file -->
- <arg line="'${tests.dir}/${testRunner.dir}/${testRunner.name}.mxml'" />
-
- <!-- Use AIR configuration file -->
- <arg line="-load-config '${flex2sdk.lib.dir}/../air-config.xml'" />
-
- <!-- Place the built .swf file in the "bin" directory -->
- <arg line="-o '${bin.dir}/${testRunner.name}.swf'" />
-
- <!-- Define source directories for "src" and "tests" -->
- <arg line="-sp ${src.dir}" />
- <arg line="-sp ${tests.dir}/src" />
+ <!-- ======================================= -->
+ <!-- Unit Test Targets -->
+ <!-- ======================================= -->
+
+ <target name="compileTestRunner" depends="init" description="Compiles the test runner application.">
+
+ <!-- Compile TestRunner MXML as a SWF -->
+ <mxmlc file="${test.src.dir}/${test.application.name}.mxml"
+ output="${test.bin.dir}/${test.application.name}.swf">
- <!-- Include the necessary framework libraries in the class path -->
- <arg line="-l '${flex2sdk.lib.dir}'" />
+ <load-config filename="${FLEX_HOME}/frameworks/air-config.xml" />
- <!-- Include in the flexunit.swc in the class path -->
- <arg line="-l ${flexunit.swc}" />
+ <source-path path-element="${src.dir}" />
+ <source-path path-element="${test.src.dir}" />
+
+ <!--
+ Define JSON Constants
+ -->
+ <define name="JSON_TOKEN::UNKNOWN" value="-1" />
+ <define name="JSON_TOKEN::COMMA" value="0" />
+ <define name="JSON_TOKEN::LEFT_BRACE" value="1" />
+ <define name="JSON_TOKEN::RIGHT_BRACE" value="2" />
+ <define name="JSON_TOKEN::LEFT_BRACKET" value="3" />
+ <define name="JSON_TOKEN::RIGHT_BRACKET" value="4" />
+ <define name="JSON_TOKEN::COLON" value="6" />
+ <define name="JSON_TOKEN::TRUE" value="7" />
+ <define name="JSON_TOKEN::FALSE" value="8" />
+ <define name="JSON_TOKEN::NULL" value="9" />
+ <define name="JSON_TOKEN::STRING" value="10" />
+ <define name="JSON_TOKEN::NUMBER" value="11" />
+ <define name="JSON_TOKEN::NAN" value="12" />
- <!-- Include locale-specific items in the path -->
- <arg line="-locale ${flex2sdk.locale}" />
- <arg line="-l '${flex2sdk.locale.dir}'" />
- </exec>
+ <!-- The TestRunner needs the flexunit libraries in the build/libs folder -->
+ <library-path dir="${build.libs.dir}" append="true">
+ <include name="*.swc" />
+ </library-path>
+
+ <!-- Sets java.awt.headless=true so font compilation works in headless environments -->
+ <compiler.headless-server>true</compiler.headless-server>
+ </mxmlc>
+
+ <echo message="The ${test.application.name}.swf test runner has been created in ${test.bin.dir}" />
</target>
- <!--
- Runs the unit tests for the library in the stand-alone Flash Player
- -->
- <target name="test" depends="compileTests">
- <!--
- If/When we add support for determinig the status of unit tests
- as part of the ANT build process, we need to change the spawn to
- "no" so that ANT waits until the test runner closes before
- proceeding.
- -->
- <exec executable="${flashDebugPlayer.exe}" spawn="yes">
- <arg line="${bin.dir}/${testRunner.name}.swf" />
- </exec>
+ <target name="runTestsAndReport" depends="init" description="Launches the test runner, captures results, generates test report artifacts.">
+ <!-- Run FlexUnit Ant Task to execute the unit tests and capture reporting data -->
+ <taskdef resource="flexUnitTasks.tasks" classpath="${build.libs.dir}/flexUnitTasks-4.0.0.jar" />
+ <flexunit swf="${test.bin.dir}/${test.application.name}.swf" toDir="${report.dir}"
+ haltonfailure="false" verbose="false" localTrusted="false" player="air" />
+
+ <!-- Generate html JUnit-style reports based on test results -->
+ <junitreport todir="${report.dir}">
+ <fileset dir="${report.dir}">
+ <include name="TEST-*.xml" />
+ </fileset>
+ <report format="frames" todir="${report.html.dir}" />
+ </junitreport>
+
+ <echo message="The unit test reports have been created in ${report.dir}" />
</target>
+
+ <target name="test" depends="init, compileTestRunner, runTestsAndReport" description="Compiles unit tests and generates test report artiacts." />
+
+ <!-- ======================================= -->
+ <!-- Compile and Document -->
+ <!-- ======================================= -->
- <!--
- Compile all of the classes under the "src" tree into a .swc file
- -->
- <target name="lib" depends="properties">
- <exec executable="${compc.exe}" dir="${basedir}">
- <!-- Specify the name of the output file -->
- <arg line="-o '${bin.dir}/${library.name}.swc'" />
+ <target name="compile" depends="init" description="Compile the library .swc file">
+ <compc output="${bin.dir}/${library.name}.swc"
+ debug="false" optimize="true">
- <!-- Specify the main source path as "src" -->
- <arg line="-sp ${src.dir}" />
+ <load-config filename="${FLEX_HOME}/frameworks/air-config.xml" />
- <!-- Include all of the classes in the "src" tree -->
- <arg line="-is ${src.dir}" />
- </exec>
+ <!--
+ Define JSON Constants
+ -->
+ <define name="JSON_TOKEN::UNKNOWN" value="-1" />
+ <define name="JSON_TOKEN::COMMA" value="0" />
+ <define name="JSON_TOKEN::LEFT_BRACE" value="1" />
+ <define name="JSON_TOKEN::RIGHT_BRACE" value="2" />
+ <define name="JSON_TOKEN::LEFT_BRACKET" value="3" />
+ <define name="JSON_TOKEN::RIGHT_BRACKET" value="4" />
+ <define name="JSON_TOKEN::COLON" value="6" />
+ <define name="JSON_TOKEN::TRUE" value="7" />
+ <define name="JSON_TOKEN::FALSE" value="8" />
+ <define name="JSON_TOKEN::NULL" value="9" />
+ <define name="JSON_TOKEN::STRING" value="10" />
+ <define name="JSON_TOKEN::NUMBER" value="11" />
+ <define name="JSON_TOKEN::NAN" value="12" />
+
+ <source-path path-element="${src.dir}" />
+ <include-sources dir="${src.dir}" includes="*" />
+ </compc>
</target>
- <!--
- Generate ASDoc output for the library
- -->
- <target name="docs" depends="properties">
- <!-- Clean out the contents of the doc directory, without delete "docs" -->
- <!--
- <delete includeemptydirs="true">
- <fileset dir="${docs.dir}" includes="**/*" />
- </delete>
- -->
-
- <exec executable="${asdoc.exe}" spawn="no">
+ <target name="docs" depends="init" description="Generate ASDoc documentation">
+ <java jar="${FLEX_HOME}/lib/asdoc.jar"
+ dir="${FLEX_HOME}/frameworks" fork="true" failonerror="true">
+
+ <arg line="-load-config '${FLEX_HOME}/frameworks/air-config.xml'" />
+
<!-- Place the documentation in the "docs" directory -->
- <arg line="-o ${docs.dir}" />
+ <arg line="-output ${docs.dir}" />
<!-- Specify the main source path as "src" -->
- <arg line="-sp ${src.dir}" />
+ <arg line="-source-path ${src.dir}" />
<!-- Document all of the classes in the "src" tree -->
- <arg line="-ds ${src.dir} " />
+ <arg line="-doc-sources ${src.dir} " />
<!-- Include the library name in the window title -->
<arg line="-window-title 'Adobe ActionScript 3.0 Core Library - ${library.name}' "/>
- </exec>
+
+ <!-- Define JSON Constants -->
+ <arg line="-define+=JSON_TOKEN::UNKNOWN,-1 -define+=JSON_TOKEN::COMMA,0 -define+=JSON_TOKEN::LEFT_BRACE,1 -define+=JSON_TOKEN::RIGHT_BRACE,2 -define+=JSON_TOKEN::LEFT_BRACKET,3 -define+=JSON_TOKEN::RIGHT_BRACKET,4 -define+=JSON_TOKEN::COLON,6 -define+=JSON_TOKEN::TRUE,7 -define+=JSON_TOKEN::FALSE,8 -define+=JSON_TOKEN::NULL,9 -define+=JSON_TOKEN::STRING,10 -define+=JSON_TOKEN::NUMBER,11 -define+=JSON_TOKEN::NAN,12" />
+ </java>
+
+ <echo message="Documentation has been created in ${docs.dir}" />
</target>
</project>
View
BIN  build/libs/flexUnitTasks-4.0.0.jar
Binary file not shown
View
BIN  build/libs/flexunit-4.0.0.swc
Binary file not shown
View
BIN  build/libs/flexunit-aircilistener-4.0.0.swc
Binary file not shown
View
BIN  build/libs/flexunit-cilistener-4.0.0.swc
Binary file not shown
View
BIN  build/libs/flexunit-flexcoverlistener-4.0.0.swc
Binary file not shown
View
BIN  build/libs/flexunit-uilistener-4.0.0.swc
Binary file not shown
View
2  src/com/adobe/air/crypto/EncryptionKeyGenerator.as
@@ -146,7 +146,7 @@ package com.adobe.air.crypto
* <p>For any given
* password, calling the <code>getEncryptionKey()</code> method from the same AIR application
* running in the same user account on the same machine, the encryption key result is
- * the same.
+ * the same.</p>
*
* <p>This method is designed to create an encryption key suitable for providing the highest
* level of data privacy and security. In order to achieve that level of security, your
View
2  src/com/adobe/net/IURIResolver.as
@@ -54,7 +54,7 @@ package com.adobe.net
* of URI.</p>
*
* <p>URI will call this before performing URI comparisons in the
- * URI.getRelation() and URI.getCommonParent() functions.
+ * URI.getRelation() and URI.getCommonParent() functions.</p>
*
* @see URI.getRelation
* @see URI.getCommonParent
View
10 src/com/adobe/net/URI.as
@@ -51,7 +51,7 @@ package com.adobe.net
* <p>URI's fall into one of three categories:
* <ul>
* <li>&lt;scheme&gt;:&lt;scheme-specific-part&gt;#&lt;fragment&gt; (non-hierarchical)</li>
- * <li>&lt;scheme&gt;:<authority&gt;&lt;path&gt;?&lt;query&gt;#&lt;fragment&gt; (hierarchical)</li>
+ * <li>&lt;scheme&gt;:&lt;authority&gt;&lt;path&gt;?&lt;query&gt;#&lt;fragment&gt; (hierarchical)</li>
* <li>&lt;path&gt;?&lt;query&gt;#&lt;fragment&gt; (relative hierarchical)</li>
* </ul></p>
*
@@ -307,7 +307,7 @@ package com.adobe.net
*
* Given a URI in string format, parse that sucker into its basic
* components and assign them to this object. A URI is of the form:
- * <scheme>:<authority><path>?<query>#<fragment>
+ * &lt;scheme&gt;:&lt;authority&gt;&lt;path&gt;?&lt;query&gt;#&lt;fragment&gt;
*
* For simplicity, we parse the URI in the following order:
*
@@ -348,7 +348,7 @@ package com.adobe.net
* will result in parsing errors. This function can handle
* - absolute hierarchical (e.g. "http://something.com/index.html),
* - relative hierarchical (e.g. "../images/flower.gif"), or
- * - non-hierarchical URIs (e.g. "mailto:jsmith@fungoo.com").
+ * - non-hierarchical URIs (e.g. "mailto:jsmith&#64;fungoo.com").
*
* Anything else will probably result in a parsing error, or a bogus
* URI object.
@@ -893,8 +893,8 @@ package com.adobe.net
/**
* The non-hierarchical part of the URI. For example, if
- * this URI object represents "mailto:somebody@company.com",
- * this will contain "somebody@company.com". This is valid only
+ * this URI object represents "mailto:somebody&#64;company.com",
+ * this will contain "somebody&#64;company.com". This is valid only
* for non-hierarchical URI's.
*/
public function get nonHierarchical() : String
View
12 src/com/adobe/serialization/json/JSON.as
@@ -32,7 +32,7 @@
package com.adobe.serialization.json
{
-
+
/**
* This class provides encoding and decoding of the JSON format.
*
@@ -45,7 +45,7 @@ package com.adobe.serialization.json
* var myObject:Object = JSON.decode( jsonString );
* </code>
*/
- public class JSON
+ public final class JSON
{
/**
* Encodes a object into a JSON string.
@@ -57,13 +57,13 @@ package com.adobe.serialization.json
* @tiptext
*/
public static function encode( o:Object ):String
- {
+ {
return new JSONEncoder( o ).getString();
}
/**
* Decodes a JSON string into a native object.
- *
+ *
* @param s The JSON string representing the object
* @param strict Flag indicating if the decoder should strictly adhere
* to the JSON standard or not. The default of <code>true</code>
@@ -77,8 +77,8 @@ package com.adobe.serialization.json
* @tiptext
*/
public static function decode( s:String, strict:Boolean = true ):*
- {
- return new JSONDecoder( s, strict ).getValue();
+ {
+ return new JSONDecoder( s, strict ).getValue();
}
}
View
143 src/com/adobe/serialization/json/JSONDecoder.as
@@ -34,9 +34,9 @@ package com.adobe.serialization.json
{
public class JSONDecoder
- {
-
- /**
+ {
+
+ /**
* Flag indicating if the parser should be strict about the format
* of the JSON string it is attempting to decode.
*/
@@ -52,7 +52,7 @@ package com.adobe.serialization.json
private var token:JSONToken;
/**
- * Constructs a new JSONDecoder to parse a JSON string
+ * Constructs a new JSONDecoder to parse a JSON string
* into a native object.
*
* @param s The JSON string to be converted
@@ -64,7 +64,7 @@ package com.adobe.serialization.json
* @tiptext
*/
public function JSONDecoder( s:String, strict:Boolean )
- {
+ {
this.strict = strict;
tokenizer = new JSONTokenizer( s, strict );
@@ -97,15 +97,39 @@ package com.adobe.serialization.json
* Returns the next token from the tokenzier reading
* the JSON string
*/
- private function nextToken():JSONToken
+ private final function nextToken():JSONToken
{
return token = tokenizer.getNextToken();
}
/**
+ * Returns the next token from the tokenizer reading
+ * the JSON string and verifies that the token is valid.
+ */
+ private final function nextValidToken():JSONToken
+ {
+ token = tokenizer.getNextToken();
+ checkValidToken();
+
+ return token;
+ }
+
+ /**
+ * Verifies that the token is valid.
+ */
+ private final function checkValidToken():void
+ {
+ // Catch errors when the input stream ends abruptly
+ if ( token == null )
+ {
+ tokenizer.parseError( "Unexpected end of input" );
+ }
+ }
+
+ /**
* Attempt to parse an array.
*/
- private function parseArray():Array
+ private final function parseArray():Array
{
// create an array internally that we're going to attempt
// to parse from the tokenizer
@@ -113,25 +137,25 @@ package com.adobe.serialization.json
// grab the next token from the tokenizer to move
// past the opening [
- nextToken();
+ nextValidToken();
// check to see if we have an empty array
- if ( token.type == JSONTokenType.RIGHT_BRACKET )
+ if ( token.type == JSON_TOKEN::RIGHT_BRACKET )
{
// we're done reading the array, so return it
return a;
}
// in non-strict mode an empty array is also a comma
// followed by a right bracket
- else if ( !strict && token.type == JSONTokenType.COMMA )
+ else if ( !strict && token.type == JSON_TOKEN::COMMA )
{
// move past the comma
- nextToken();
+ nextValidToken();
// check to see if we're reached the end of the array
- if ( token.type == JSONTokenType.RIGHT_BRACKET )
+ if ( token.type == JSON_TOKEN::RIGHT_BRACKET )
{
- return a;
+ return a;
}
else
{
@@ -145,16 +169,16 @@ package com.adobe.serialization.json
{
// read in the value and add it to the array
a.push( parseValue() );
-
+
// after the value there should be a ] or a ,
- nextToken();
+ nextValidToken();
- if ( token.type == JSONTokenType.RIGHT_BRACKET )
+ if ( token.type == JSON_TOKEN::RIGHT_BRACKET )
{
// we're done reading the array, so return it
return a;
}
- else if ( token.type == JSONTokenType.COMMA )
+ else if ( token.type == JSON_TOKEN::COMMA )
{
// move past the comma and read another value
nextToken();
@@ -163,8 +187,10 @@ package com.adobe.serialization.json
// if the decoder is not in strict mode
if ( !strict )
{
+ checkValidToken();
+
// Reached ",]" as the end of the array, so return it
- if ( token.type == JSONTokenType.RIGHT_BRACKET )
+ if ( token.type == JSON_TOKEN::RIGHT_BRACKET )
{
return a;
}
@@ -175,40 +201,41 @@ package com.adobe.serialization.json
tokenizer.parseError( "Expecting ] or , but found " + token.value );
}
}
- return null;
+
+ return null;
}
/**
* Attempt to parse an object.
*/
- private function parseObject():Object
+ private final function parseObject():Object
{
// create the object internally that we're going to
// attempt to parse from the tokenizer
var o:Object = new Object();
-
+
// store the string part of an object member so
// that we can assign it a value in the object
var key:String
// grab the next token from the tokenizer
- nextToken();
+ nextValidToken();
// check to see if we have an empty object
- if ( token.type == JSONTokenType.RIGHT_BRACE )
+ if ( token.type == JSON_TOKEN::RIGHT_BRACE )
{
// we're done reading the object, so return it
return o;
}
// in non-strict mode an empty object is also a comma
// followed by a right bracket
- else if ( !strict && token.type == JSONTokenType.COMMA )
+ else if ( !strict && token.type == JSON_TOKEN::COMMA )
{
// move past the comma
- nextToken();
+ nextValidToken();
// check to see if we're reached the end of the object
- if ( token.type == JSONTokenType.RIGHT_BRACE )
+ if ( token.type == JSON_TOKEN::RIGHT_BRACE )
{
return o;
}
@@ -222,31 +249,31 @@ package com.adobe.serialization.json
// loop because we could have any amount of members
while ( true )
{
- if ( token.type == JSONTokenType.STRING )
+ if ( token.type == JSON_TOKEN::STRING )
{
// the string value we read is the key for the object
key = String( token.value );
// move past the string to see what's next
- nextToken();
+ nextValidToken();
// after the string there should be a :
- if ( token.type == JSONTokenType.COLON )
- {
+ if ( token.type == JSON_TOKEN::COLON )
+ {
// move past the : and read/assign a value for the key
nextToken();
- o[key] = parseValue();
+ o[ key ] = parseValue();
// move past the value to see what's next
- nextToken();
+ nextValidToken();
// after the value there's either a } or a ,
- if ( token.type == JSONTokenType.RIGHT_BRACE )
+ if ( token.type == JSON_TOKEN::RIGHT_BRACE )
{
// we're done reading the object, so return it
- return o;
+ return o;
}
- else if ( token.type == JSONTokenType.COMMA )
+ else if ( token.type == JSON_TOKEN::COMMA )
{
// skip past the comma and read another member
nextToken();
@@ -255,8 +282,10 @@ package com.adobe.serialization.json
// if the decoder is not in strict mode
if ( !strict )
{
+ checkValidToken();
+
// Reached ",}" as the end of the object, so return it
- if ( token.type == JSONTokenType.RIGHT_BRACE )
+ if ( token.type == JSON_TOKEN::RIGHT_BRACE )
{
return o;
}
@@ -273,40 +302,36 @@ package com.adobe.serialization.json
}
}
else
- {
+ {
tokenizer.parseError( "Expecting string but found " + token.value );
}
}
- return null;
+ return null;
}
/**
* Attempt to parse a value
*/
- private function parseValue():Object
+ private final function parseValue():Object
{
- // Catch errors when the input stream ends abruptly
- if ( token == null )
- {
- tokenizer.parseError( "Unexpected end of input" );
- }
-
+ checkValidToken();
+
switch ( token.type )
{
- case JSONTokenType.LEFT_BRACE:
+ case JSON_TOKEN::LEFT_BRACE:
return parseObject();
-
- case JSONTokenType.LEFT_BRACKET:
+
+ case JSON_TOKEN::LEFT_BRACKET:
return parseArray();
-
- case JSONTokenType.STRING:
- case JSONTokenType.NUMBER:
- case JSONTokenType.TRUE:
- case JSONTokenType.FALSE:
- case JSONTokenType.NULL:
+
+ case JSON_TOKEN::STRING:
+ case JSON_TOKEN::NUMBER:
+ case JSON_TOKEN::TRUE:
+ case JSON_TOKEN::FALSE:
+ case JSON_TOKEN::NULL:
return token.value;
-
- case JSONTokenType.NAN:
+
+ case JSON_TOKEN::NAN:
if ( !strict )
{
return token.value;
@@ -315,13 +340,13 @@ package com.adobe.serialization.json
{
tokenizer.parseError( "Unexpected " + token.value );
}
-
+
default:
tokenizer.parseError( "Unexpected " + token.value );
-
+
}
- return null;
+ return null;
}
}
}
View
157 src/com/adobe/serialization/json/JSONEncoder.as
@@ -8,11 +8,11 @@
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
-
+
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
-
+
* Neither the name of Adobe Systems Incorporated nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
@@ -30,13 +30,14 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-package com.adobe.serialization.json
+package com.adobe.serialization.json
{
-
+
import flash.utils.describeType;
-
- public class JSONEncoder {
+ public class JSONEncoder
+ {
+
/** The string that is going to represent the object we're encoding */
private var jsonString:String;
@@ -48,9 +49,9 @@ package com.adobe.serialization.json
* @playerversion Flash 9.0
* @tiptext
*/
- public function JSONEncoder( value:* ) {
+ public function JSONEncoder( value:* )
+ {
jsonString = convertToString( value );
-
}
/**
@@ -62,45 +63,47 @@ package com.adobe.serialization.json
* @playerversion Flash 9.0
* @tiptext
*/
- public function getString():String {
+ public function getString():String
+ {
return jsonString;
}
/**
* Converts a value to it's JSON string equivalent.
*
- * @param value The value to convert. Could be any
+ * @param value The value to convert. Could be any
* type (object, number, array, etc)
*/
- private function convertToString( value:* ):String {
-
+ private function convertToString( value:* ):String
+ {
// determine what value is and convert it based on it's type
- if ( value is String ) {
-
+ if ( value is String )
+ {
// escape the string so it's formatted correctly
return escapeString( value as String );
-
- } else if ( value is Number ) {
-
+ }
+ else if ( value is Number )
+ {
// only encode numbers that finate
- return isFinite( value as Number) ? value.toString() : "null";
-
- } else if ( value is Boolean ) {
-
+ return isFinite( value as Number ) ? value.toString() : "null";
+ }
+ else if ( value is Boolean )
+ {
// convert boolean to string easily
return value ? "true" : "false";
-
- } else if ( value is Array ) {
-
+ }
+ else if ( value is Array )
+ {
// call the helper method to convert an array
return arrayToString( value as Array );
-
- } else if ( value is Object && value != null ) {
-
+ }
+ else if ( value is Object && value != null )
+ {
// call the helper method to convert an object
return objectToString( value );
}
- return "null";
+
+ return "null";
}
/**
@@ -110,7 +113,8 @@ package com.adobe.serialization.json
* @return The string with escaped special characters
* according to the JSON specification
*/
- private function escapeString( str:String ):String {
+ private function escapeString( str:String ):String
+ {
// create a string to store the string's jsonstring value
var s:String = "";
// current character in the string we're processing
@@ -119,48 +123,49 @@ package com.adobe.serialization.json
var len:Number = str.length;
// loop over all of the characters in the string
- for ( var i:int = 0; i < len; i++ ) {
-
+ for ( var i:int = 0; i < len; i++ )
+ {
// examine the character to determine if we have to escape it
ch = str.charAt( i );
- switch ( ch ) {
-
- case '"': // quotation mark
+ switch ( ch )
+ {
+ case '"': // quotation mark
s += "\\\"";
break;
-
+
//case '/': // solidus
// s += "\\/";
// break;
-
- case '\\': // reverse solidus
+
+ case '\\': // reverse solidus
s += "\\\\";
break;
-
- case '\b': // bell
+
+ case '\b': // bell
s += "\\b";
break;
-
- case '\f': // form feed
+
+ case '\f': // form feed
s += "\\f";
break;
-
- case '\n': // newline
+
+ case '\n': // newline
s += "\\n";
break;
-
- case '\r': // carriage return
+
+ case '\r': // carriage return
s += "\\r";
break;
-
- case '\t': // horizontal tab
+
+ case '\t': // horizontal tab
s += "\\t";
break;
-
- default: // everything else
+
+ default: // everything else
// check for a control character and escape as unicode
- if ( ch < ' ' ) {
+ if ( ch < ' ' )
+ {
// get the hex digit(s) of the character (either 1 or 2 digits)
var hexCode:String = ch.charCodeAt( 0 ).toString( 16 );
@@ -170,16 +175,18 @@ package com.adobe.serialization.json
// create the unicode escape sequence with 4 hex digits
s += "\\u" + zeroPad + hexCode;
- } else {
-
+ }
+ else
+ {
+
// no need to do any special encoding, just pass-through
s += ch;
}
- } // end switch
+ } // end switch
- } // end for loop
-
+ } // end for loop
+
return "\"" + s + "\"";
}
@@ -189,22 +196,26 @@ package com.adobe.serialization.json
* @param a The array to convert
* @return The JSON string representation of <code>a</code>
*/
- private function arrayToString( a:Array ):String {
+ private function arrayToString( a:Array ):String
+ {
// create a string to store the array's jsonstring value
var s:String = "";
// loop over the elements in the array and add their converted
// values to the string
- for ( var i:int = 0; i < a.length; i++ ) {
+ var length:int = a.length;
+ for ( var i:int = 0; i < length; i++ )
+ {
// when the length is 0 we're adding the first element so
// no comma is necessary
- if ( s.length > 0 ) {
+ if ( s.length > 0 )
+ {
// we've already added an element, so add the comma separator
s += ","
}
// convert the value to a string
- s += convertToString( a[i] );
+ s += convertToString( a[ i ] );
}
// KNOWN ISSUE: In ActionScript, Arrays can also be associative
@@ -222,7 +233,7 @@ package com.adobe.serialization.json
// A possible solution is to instead encode the Array as an Object
// but then it won't get decoded correctly (and won't be an
// Array instance)
-
+
// close the array and return it's string value
return "[" + s + "]";
}
@@ -252,7 +263,7 @@ package com.adobe.serialization.json
for ( var key:String in o )
{
// assign value to a variable for quick lookup
- value = o[key];
+ value = o[ key ];
// don't add function's to the JSON string
if ( value is Function )
@@ -263,7 +274,8 @@ package com.adobe.serialization.json
// when the length is 0 we're adding the first item so
// no comma is necessary
- if ( s.length > 0 ) {
+ if ( s.length > 0 )
+ {
// we've already added an item, so add the comma separator
s += ","
}
@@ -275,13 +287,13 @@ package com.adobe.serialization.json
{
// Loop over all of the variables and accessors in the class and
// serialize them along with their values.
- for each ( var v:XML in classInfo..*.(
+ for each ( var v:XML in classInfo..*.(
name() == "variable"
||
- (
+ (
name() == "accessor"
// Issue #116 - Make sure accessors are readable
- && attribute( "access" ).charAt( 0 ) == "r" )
+ && attribute( "access" ).charAt( 0 ) == "r" )
) )
{
// Issue #110 - If [Transient] metadata exists, then we should skip
@@ -292,21 +304,20 @@ package com.adobe.serialization.json
// When the length is 0 we're adding the first item so
// no comma is necessary
- if ( s.length > 0 ) {
+ if ( s.length > 0 )
+ {
// We've already added an item, so add the comma separator
s += ","
}
- s += escapeString( v.@name.toString() ) + ":"
- + convertToString( o[ v.@name ] );
+ s += escapeString( v.@name.toString() ) + ":"
+ + convertToString( o[ v.@name ] );
}
-
}
return "{" + s + "}";
}
-
-
- }
-}
+ }
+
+}
View
25 src/com/adobe/serialization/json/JSONParseError.as
@@ -30,20 +30,22 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-package com.adobe.serialization.json {
-
+package com.adobe.serialization.json
+{
+
/**
*
*
*/
- public class JSONParseError extends Error {
-
+ public class JSONParseError extends Error
+ {
+
/** The location in the string where the error occurred */
private var _location:int;
/** The string in which the parse error occurred */
private var _text:String;
-
+
/**
* Constructs a new JSONParseError.
*
@@ -52,13 +54,14 @@ package com.adobe.serialization.json {
* @playerversion Flash 9.0
* @tiptext
*/
- public function JSONParseError( message:String = "", location:int = 0, text:String = "") {
+ public function JSONParseError( message:String = "", location:int = 0, text:String = "" )
+ {
super( message );
name = "JSONParseError";
_location = location;
_text = text;
}
-
+
/**
* Provides read-only access to the location variable.
*
@@ -67,7 +70,8 @@ package com.adobe.serialization.json {
* @playerversion Flash 9.0
* @tiptext
*/
- public function get location():int {
+ public function get location():int
+ {
return _location;
}
@@ -79,9 +83,10 @@ package com.adobe.serialization.json {
* @playerversion Flash 9.0
* @tiptext
*/
- public function get text():String {
+ public function get text():String
+ {
return _text;
}
}
-
+
}
View
68 src/com/adobe/serialization/json/JSONToken.as
@@ -30,75 +30,63 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-package com.adobe.serialization.json {
-
- public class JSONToken {
+package com.adobe.serialization.json
+{
- private var _type:int;
- private var _value:Object;
+ public final class JSONToken
+ {
/**
- * Creates a new JSONToken with a specific token type and value.
+ * The type of the token.
*
- * @param type The JSONTokenType of the token
- * @param value The value of the token
* @langversion ActionScript 3.0
* @playerversion Flash 9.0
* @tiptext
*/
- public function JSONToken( type:int = -1 /* JSONTokenType.UNKNOWN */, value:Object = null ) {
- _type = type;
- _value = value;
- }
+ public var type:int;
/**
- * Returns the type of the token.
+ * The value of the token
*
- * @see com.adobe.serialization.json.JSONTokenType
* @langversion ActionScript 3.0
* @playerversion Flash 9.0
* @tiptext
*/
- public function get type():int {
- return _type;
- }
+ public var value:Object;
/**
- * Sets the type of the token.
+ * Creates a new JSONToken with a specific token type and value.
*
- * @see com.adobe.serialization.json.JSONTokenType
+ * @param type The JSONTokenType of the token
+ * @param value The value of the token
* @langversion ActionScript 3.0
* @playerversion Flash 9.0
* @tiptext
*/
- public function set type( value:int ):void {
- _type = value;
+ public function JSONToken( type:int = JSON_TOKEN::UNKNOWN, value:Object = null )
+ {
+ this.type = type;
+ this.value = value;
}
/**
- * Gets the value of the token
- *
- * @see com.adobe.serialization.json.JSONTokenType
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
+ * Reusable token instance.
+ *
+ * @see #create()
*/
- public function get value():Object {
- return _value;
- }
+ internal static const token:JSONToken = new JSONToken();
/**
- * Sets the value of the token
- *
- * @see com.adobe.serialization.json.JSONTokenType
- * @langversion ActionScript 3.0
- * @playerversion Flash 9.0
- * @tiptext
+ * Factory method to create instances. Because we don't need more than one instance
+ * of a token at a time, we can always use the same instance to improve performance
+ * and reduce memory consumption during decoding.
*/
- public function set value ( v:Object ):void {
- _value = v;
+ internal static function create( type:int = JSON_TOKEN::UNKNOWN, value:Object = null ):JSONToken
+ {
+ token.type = type;
+ token.value = value;
+
+ return token;
}
-
}
-
}
View
69 src/com/adobe/serialization/json/JSONTokenType.as
@@ -1,69 +0,0 @@
-/*
- Copyright (c) 2008, Adobe Systems Incorporated
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of Adobe Systems Incorporated nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-package com.adobe.serialization.json {
-
- /**
- * Class containing constant values for the different types
- * of tokens in a JSON encoded string.
- */
- public class JSONTokenType {
-
- public static const UNKNOWN:int = -1;
-
- public static const COMMA:int = 0;
-
- public static const LEFT_BRACE:int = 1;
-
- public static const RIGHT_BRACE:int = 2;
-
- public static const LEFT_BRACKET:int = 3;
-
- public static const RIGHT_BRACKET:int = 4;
-
- public static const COLON:int = 6;
-
- public static const TRUE:int = 7;
-
- public static const FALSE:int = 8;
-
- public static const NULL:int = 9;
-
- public static const STRING:int = 10;
-
- public static const NUMBER:int = 11;
-
- public static const NAN:int = 12;
-
- }
-
-}
View
196 src/com/adobe/serialization/json/JSONTokenizer.as
@@ -30,18 +30,20 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-package com.adobe.serialization.json {
-
- public class JSONTokenizer {
+package com.adobe.serialization.json
+{
+
+ public class JSONTokenizer
+ {
- /**
+ /**
* Flag indicating if the tokenizer should only recognize
* standard JSON tokens. Setting to <code>false</code> allows
* tokens such as NaN and allows numbers to be formatted as
* hex, etc.
*/
private var strict:Boolean;
-
+
/** The object that will get parsed from the JSON string */
private var obj:Object;
@@ -54,14 +56,14 @@ package com.adobe.serialization.json {
/** The current character in the JSON string during parsing */
private var ch:String;
- /**
+ /**
* The regular expression used to make sure the string does not
* contain invalid control characters.
*/
- private var controlCharsRegExp:RegExp = /[\x00-\x1F]/;
+ private const controlCharsRegExp:RegExp = /[\x00-\x1F]/;
/**
- * Constructs a new JSONDecoder to parse a JSON string
+ * Constructs a new JSONDecoder to parse a JSON string
* into a native object.
*
* @param s The JSON string to be converted
@@ -79,62 +81,55 @@ package com.adobe.serialization.json {
/**
* Gets the next token in the input sting and advances
- * the character to the next character after the token
+ * the character to the next character after the token
*/
public function getNextToken():JSONToken
{
- var token:JSONToken = new JSONToken();
+ var token:JSONToken = null;
// skip any whitespace / comments since the last
// token was read
skipIgnored();
-
+
// examine the new character and see what we have...
switch ( ch )
- {
+ {
case '{':
- token.type = JSONTokenType.LEFT_BRACE;
- token.value = '{';
+ token = JSONToken.create( JSON_TOKEN::LEFT_BRACE, ch );
nextChar();
break
-
+
case '}':
- token.type = JSONTokenType.RIGHT_BRACE;
- token.value = '}';
+ token = JSONToken.create( JSON_TOKEN::RIGHT_BRACE, ch );
nextChar();
break
-
+
case '[':
- token.type = JSONTokenType.LEFT_BRACKET;
- token.value = '[';
+ token = JSONToken.create( JSON_TOKEN::LEFT_BRACKET, ch );
nextChar();
break
-
+
case ']':
- token.type = JSONTokenType.RIGHT_BRACKET;
- token.value = ']';
+ token = JSONToken.create( JSON_TOKEN::RIGHT_BRACKET, ch );
nextChar();
break
case ',':
- token.type = JSONTokenType.COMMA;
- token.value = ',';
+ token = JSONToken.create( JSON_TOKEN::COMMA, ch );
nextChar();
break
-
+
case ':':
- token.type = JSONTokenType.COLON;
- token.value = ':';
+ token = JSONToken.create( JSON_TOKEN::COLON, ch );
nextChar();
break;
-
+
case 't': // attempt to read true
var possibleTrue:String = "t" + nextChar() + nextChar() + nextChar();
if ( possibleTrue == "true" )
{
- token.type = JSONTokenType.TRUE;
- token.value = true;
+ token = JSONToken.create( JSON_TOKEN::TRUE, true );
nextChar();
}
else
@@ -143,14 +138,13 @@ package com.adobe.serialization.json {
}
break;
-
+
case 'f': // attempt to read false
var possibleFalse:String = "f" + nextChar() + nextChar() + nextChar() + nextChar();
if ( possibleFalse == "false" )
{
- token.type = JSONTokenType.FALSE;
- token.value = false;
+ token = JSONToken.create( JSON_TOKEN::FALSE, false );
nextChar();
}
else
@@ -159,14 +153,13 @@ package com.adobe.serialization.json {
}
break;
-
+
case 'n': // attempt to read null
var possibleNull:String = "n" + nextChar() + nextChar() + nextChar();
if ( possibleNull == "null" )
{
- token.type = JSONTokenType.NULL;
- token.value = null;
+ token = JSONToken.create( JSON_TOKEN::NULL, null );
nextChar();
}
else
@@ -175,14 +168,13 @@ package com.adobe.serialization.json {
}
break;
-
+
case 'N': // attempt to read NaN
var possibleNaN:String = "N" + nextChar() + nextChar();
if ( possibleNaN == "NaN" )
{
- token.type = JSONTokenType.NAN;
- token.value = NaN;
+ token = JSONToken.create( JSON_TOKEN::NAN, NaN );
nextChar();
}
else
@@ -191,12 +183,12 @@ package com.adobe.serialization.json {
}
break;
-
+
case '"': // the start of a string
token = readString();
break;
-
- default:
+
+ default:
// see if we can read a number
if ( isDigit( ch ) || ch == '-' )
{
@@ -205,10 +197,10 @@ package com.adobe.serialization.json {
else if ( ch == '' )
{
// check for reading past the end of the string
- return null;
+ token = null;
}
else
- {
+ {
// not sure what was in the input string - it's not
// anything we expected
parseError( "Unexpected " + ch + " encountered" );
@@ -226,7 +218,7 @@ package com.adobe.serialization.json {
* @return the JSONToken with the string value if a string could
* be read. Throws an error otherwise.
*/
- private function readString():JSONToken
+ private final function readString():JSONToken
{
// Rather than examine the string character-by-character, it's
// faster to use indexOf to try to and find the closing quote character
@@ -254,7 +246,7 @@ package com.adobe.serialization.json {
}
// If we have an even number of backslashes, that means this is the ending quote
- if ( backspaceCount % 2 == 0 )
+ if ( ( backspaceCount & 1 ) == 0 )
{
break;
}
@@ -271,10 +263,10 @@ package com.adobe.serialization.json {
// Unescape the string
// the token for the string we'll try to read
- var token:JSONToken = new JSONToken();
- token.type = JSONTokenType.STRING;
- // Attach resulting string to the token to return it
- token.value = unescapeString( jsonString.substr( loc, quoteIndex - loc ) );
+ var token:JSONToken = JSONToken.create(
+ JSON_TOKEN::STRING,
+ // Attach resulting string to the token to return it
+ unescapeString( jsonString.substr( loc, quoteIndex - loc ) ) );
// Move past the closing quote in the input string. This updates the next
// character in the input stream to be the character one after the closing quote
@@ -317,17 +309,26 @@ package com.adobe.serialization.json {
nextSubstringStartPosition = backslashIndex + 2;
// Check the next character so we know what to escape
- var afterBackslashIndex:int = backslashIndex + 1;
- var escapedChar:String = input.charAt( afterBackslashIndex );
+ var escapedChar:String = input.charAt( backslashIndex + 1 );
switch ( escapedChar )
- {
+ {
// Try to list the most common expected cases first to improve performance
- case '"': result += '"'; break; // quotation mark
- case '\\': result += '\\'; break; // reverse solidus
- case 'n': result += '\n'; break; // newline
- case 'r': result += '\r'; break; // carriage return
- case 't': result += '\t'; break; // horizontal tab
+ case '"':
+ result += escapedChar;
+ break; // quotation mark
+ case '\\':
+ result += escapedChar;
+ break; // reverse solidus
+ case 'n':
+ result += '\n';
+ break; // newline
+ case 'r':
+ result += '\r';
+ break; // carriage return
+ case 't':
+ result += '\t';
+ break; // horizontal tab
// Convert a unicode escape sequence to it's character value
case 'u':
@@ -335,14 +336,16 @@ package com.adobe.serialization.json {
// Save the characters as a string we'll convert to an int
var hexValue:String = "";
+ var unicodeEndPosition:int = nextSubstringStartPosition + 4;
+
// Make sure there are enough characters in the string leftover
- if ( nextSubstringStartPosition + 4 > len )
+ if ( unicodeEndPosition > len )
{
parseError( "Unexpected end of input. Expecting 4 hex digits after \\u." );
}
// Try to find 4 hex characters
- for ( var i:int = nextSubstringStartPosition; i < nextSubstringStartPosition + 4; i++ )
+ for ( var i:int = nextSubstringStartPosition; i < unicodeEndPosition; i++ )
{
// get the next character and determine
// if it's a valid hex digit or not
@@ -360,14 +363,22 @@ package com.adobe.serialization.json {
// integer value to create a character to add
// to our string.
result += String.fromCharCode( parseInt( hexValue, 16 ) );
+
// Move past the 4 hex digits that we just read
- nextSubstringStartPosition += 4;
+ nextSubstringStartPosition = unicodeEndPosition;
break;
- case 'f': result += '\f'; break; // form feed
- case '/': result += '/'; break; // solidus
- case 'b': result += '\b'; break; // bell
- default: result += '\\' + escapedChar; // Couldn't unescape the sequence, so just pass it through
+ case 'f':
+ result += '\f';
+ break; // form feed
+ case '/':
+ result += '/';
+ break; // solidus
+ case 'b':
+ result += '\b';
+ break; // bell
+ default:
+ result += '\\' + escapedChar; // Couldn't unescape the sequence, so just pass it through
}
}
else
@@ -386,11 +397,11 @@ package com.adobe.serialization.json {
* Attempts to read a number from the input string. Places
* the character location at the first character after the
* number.
- *
+ *
* @return The JSONToken with the number value if a number could
* be read. Throws an error otherwise.
*/
- private function readNumber():JSONToken
+ private final function readNumber():JSONToken
{
// the string to accumulate the number characters
// into that we'll convert to a number at the end
@@ -438,7 +449,7 @@ package com.adobe.serialization.json {
}
else
{
- parseError( "Number in hex format require at least one hex digit after \"0x\"" );
+ parseError( "Number in hex format require at least one hex digit after \"0x\"" );
}
// consume all of the hex values
@@ -497,7 +508,7 @@ package com.adobe.serialization.json {
{
parseError( "Scientific notation number needs exponent value" );
}
-
+
// read in the exponent
while ( isDigit( ch ) )
{
@@ -512,19 +523,16 @@ package com.adobe.serialization.json {
if ( isFinite( num ) && !isNaN( num ) )
{
// the token for the number that we've read
- var token:JSONToken = new JSONToken();
- token.type = JSONTokenType.NUMBER;
- token.value = num;
- return token;
+ return JSONToken.create( JSON_TOKEN::NUMBER, num );
}
else
{
parseError( "Number " + num + " is not valid!" );
}
- return null;
+ return null;
}
-
+
/**
* Reads the next character in the input
* string and advances the character location.
@@ -532,7 +540,7 @@ package com.adobe.serialization.json {
* @return The next character in the input string, or
* null if we've read past the end.
*/
- private function nextChar():String
+ private final function nextChar():String
{
return ch = jsonString.charAt( loc++ );
}
@@ -541,7 +549,7 @@ package com.adobe.serialization.json {
* Advances the character location past any
* sort of white space and comments
*/
- private function skipIgnored():void
+ private final function skipIgnored():void
{
var originalLoc:int;
@@ -552,8 +560,7 @@ package com.adobe.serialization.json {
originalLoc = loc;
skipWhite();
skipComments();
- }
- while ( originalLoc != loc );
+ } while ( originalLoc != loc );
}
/**
@@ -576,8 +583,7 @@ package com.adobe.serialization.json {
do
{
nextChar();
- }
- while ( ch != '\n' && ch != '' )
+ } while ( ch != '\n' && ch != '' )
// move past the \n
nextChar();
@@ -585,7 +591,7 @@ package com.adobe.serialization.json {
break;
case '*': // multi-line comment, read until closing */
-
+
// move past the opening *
nextChar();
@@ -596,7 +602,7 @@ package com.adobe.serialization.json {
{
// check to see if we have a closing /
nextChar();
- if ( ch == '/')
+ if ( ch == '/' )
{
// move past the end of the closing */
nextChar();
@@ -616,7 +622,7 @@ package com.adobe.serialization.json {
parseError( "Multi-line comment not closed" );
}
}
-
+
break;
// Can't match a comment after a /, so it's a parsing error
@@ -624,7 +630,7 @@ package com.adobe.serialization.json {
parseError( "Unexpected " + ch + " encountered (expecting '/' or '*' )" );
}
}
-
+
}
@@ -633,8 +639,8 @@ package com.adobe.serialization.json {
* the character to the first character after any possible
* whitespace.
*/
- private function skipWhite():void
- {
+ private final function skipWhite():void
+ {
// As long as there are spaces in the input
// stream, advance the current location pointer
// past them
@@ -642,7 +648,7 @@ package com.adobe.serialization.json {
{
nextChar();
}
-
+
}
/**
@@ -651,7 +657,7 @@ package com.adobe.serialization.json {
* @return True if the character passed in is a whitespace
* character
*/
- private function isWhiteSpace( ch:String ):Boolean
+ private final function isWhiteSpace( ch:String ):Boolean
{
// Check for the whitespace defined in the spec
if ( ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' )
@@ -672,7 +678,7 @@ package com.adobe.serialization.json {
*
* @return True if the character passed in is a digit
*/
- private function isDigit( ch:String ):Boolean
+ private final function isDigit( ch:String ):Boolean
{
return ( ch >= '0' && ch <= '9' );
}
@@ -682,21 +688,21 @@ package com.adobe.serialization.json {
*
* @return True if the character passed in is a hex digit
*/
- private function isHexDigit( ch:String ):Boolean
+ private final function isHexDigit( ch:String ):Boolean
{
return ( isDigit( ch ) || ( ch >= 'A' && ch <= 'F' ) || ( ch >= 'a' && ch <= 'f' ) );
}
-
+
/**
* Raises a parsing error with a specified message, tacking
* on the error location and the original string.
*
* @param message The message indicating why the error occurred
*/
- public function parseError( message:String ):void
+ public final function parseError( message:String ):void
{
throw new JSONParseError( message, loc, jsonString );
}
}
-
+
}
View
98 tests/src/AllCoreLibTests.as
@@ -0,0 +1,98 @@
+package
+{
+ import com.adobe.air.crypto.EncryptionKeyGeneratorTest;
+ import com.adobe.crypto.HMACMD5Test;
+ import com.adobe.crypto.HMACSHA1Test;
+ import com.adobe.crypto.MD5Test;
+ import com.adobe.crypto.SHA1Test;
+ import com.adobe.crypto.SHA224Test;
+ import com.adobe.crypto.SHA256Test;
+ import com.adobe.crypto.WSSEUsernameTokenTest;
+ import com.adobe.images.JPGEncoderTest;
+ import com.adobe.images.PNGEncoderTest;
+ import com.adobe.net.URITest;
+ import com.adobe.serialization.json.JSONTest;
+ import com.adobe.utils.ArrayUtilTest;
+ import com.adobe.utils.DateUtilTest;
+ import com.adobe.utils.DictionaryUtilTest;
+ import com.adobe.utils.IntUtilTest;
+ import com.adobe.utils.NumberFormatterTest;
+ import com.adobe.utils.StringUtilTest;
+ import com.adobe.utils.XMLUtilTest;
+ import com.adobe.air.filesystem.VolumeMonitorTest;
+ import com.adobe.air.filesystem.events.FileMonitorEventTest;
+ import com.adobe.air.net.events.ResourceCacheEventTest;
+ import com.adobe.protocols.events.ConnectedEventTest;
+ import com.adobe.protocols.events.DatabaseEventTest;
+ import com.adobe.protocols.events.DefinitionEventTest;
+ import com.adobe.protocols.events.DefinitionHeaderEventTest;
+ import com.adobe.protocols.events.DictionaryServerEventTest;
+ import com.adobe.protocols.events.DisconnectedEventTest;
+ import com.adobe.protocols.events.ErrorEventTest;
+ import com.adobe.protocols.events.MatchEventTest;
+ import com.adobe.protocols.events.MatchStrategiesEventTest;
+ import com.adobe.protocols.events.NoMatchEventTest;
+ import com.adobe.protocols.util.CompletedResponseEventTest;
+ import com.adobe.webapis.events.ServiceEventTest;
+ import com.adobe.air.filesystem.FileMonitorTest;
+
+ [Suite]
+ [RunWith( "org.flexunit.runners.Suite" )]
+ public class AllCoreLibTests
+ {
+ // utils
+ public var stringUtilTest:StringUtilTest;
+ public var vumberFormatterTest:NumberFormatterTest;
+ public var arrayUtilTest:ArrayUtilTest;
+ public var dateUtilTest:DateUtilTest;
+ public var intUtilTest:IntUtilTest;
+ public var xMLUtilTest:XMLUtilTest;
+ public var dictionaryUtilTest:DictionaryUtilTest;
+
+ // crypto
+ public var hMACSHA1Test:HMACSHA1Test;
+ public var hMACMD5Test:HMACMD5Test;
+ public var mD5Test:MD5Test;
+ public var sHA1Test:SHA1Test;
+ public var sHA224Test:SHA224Test;
+ public var sHA256Test:SHA256Test;
+ public var wSSEUsernameTokenTest:WSSEUsernameTokenTest;
+
+ // net
+ public var uRITest:URITest;
+
+ // serialization
+ public var jSONTest:JSONTest;
+
+ // images
+ public var jPGEncoderTest:JPGEncoderTest;
+ public var pNGEncoderTest:PNGEncoderTest;
+
+ // protocols.dict
+ public var connectedEventTest:ConnectedEventTest;
+ public var databaseEventTest:DatabaseEventTest;
+ public var definitionEventTest:DefinitionEventTest;
+ public var definitionHeaderEventTest:DefinitionHeaderEventTest;
+ public var dictionaryServerEventTest:DictionaryServerEventTest;
+ public var disconnectedEventTest:DisconnectedEventTest;
+ public var errorEventTest:ErrorEventTest;
+ public var matchEventTest:MatchEventTest;
+ public var matchStrategiesEventTest:MatchStrategiesEventTest;
+ public var noMatchEventTest:NoMatchEventTest;
+ public var completedResponseEventTest:CompletedResponseEventTest;
+
+ // webapis
+ public var serviceEventTest:ServiceEventTest;
+
+ // air.crypto
+ public var encryptionKeyGeneratorTest:EncryptionKeyGeneratorTest;
+
+ // air.filesystem
+ public var volumeMonitorTest:VolumeMonitorTest;
+ public var fileMonitorTest:FileMonitorTest;
+ public var fileMonitorEventTest:FileMonitorEventTest;
+
+ // air.net
+ public var resourceCacheEventTest:ResourceCacheEventTest;
+ }
+}
View
138 tests/src/CoreLibTestRunner.as
@@ -1,138 +0,0 @@
-/*
- Copyright (c) 2008, Adobe Systems Incorporated
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of Adobe Systems Incorporated nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-import com.adobe.air.crypto.EncryptionKeyGeneratorTest;
-import com.adobe.crypto.HMACMD5Test;
-import com.adobe.crypto.HMACSHA1Test;
-import com.adobe.crypto.MD5Test;
-import com.adobe.crypto.SHA1Test;
-import com.adobe.crypto.SHA224Test;
-import com.adobe.crypto.SHA256Test;
-import com.adobe.crypto.WSSEUsernameTokenTest;
-import com.adobe.images.JPGEncoderTest;
-import com.adobe.images.PNGEncoderTest;
-import com.adobe.net.URITest;
-import com.adobe.serialization.json.JSONTest;
-import com.adobe.utils.ArrayUtilTest;
-import com.adobe.utils.DateUtilTest;
-import com.adobe.utils.DictionaryUtilTest;
-import com.adobe.utils.IntUtilTest;
-import com.adobe.utils.NumberFormatterTest;
-import com.adobe.utils.StringUtilTest;
-import com.adobe.utils.XMLUtilTest;
-
-import flexunit.framework.TestSuite;
-import com.adobe.air.filesystem.VolumeMonitorTest;
-import com.adobe.air.filesystem.events.FileMonitorEventTest;
-import com.adobe.air.net.events.ResourceCacheEventTest;
-import com.adobe.protocols.events.ConnectedEventTest;
-import com.adobe.protocols.events.DatabaseEventTest;
-import com.adobe.protocols.events.DefinitionEventTest;
-import com.adobe.protocols.events.DefinitionHeaderEventTest;
-import com.adobe.protocols.events.DictionaryServerEventTest;
-import com.adobe.protocols.events.DisconnectedEventTest;
-import com.adobe.protocols.events.ErrorEventTest;
-import com.adobe.protocols.events.MatchEventTest;
-import com.adobe.protocols.events.MatchStrategiesEventTest;
-import com.adobe.protocols.events.NoMatchEventTest;
-import com.adobe.protocols.util.CompletedResponseEventTest;
-import com.adobe.webapis.events.ServiceEventTest;
-import com.adobe.air.filesystem.FileMonitorTest;
-
-
-private function onCreationComplete():void
-{
- testRunner.test = createSuite();
- testRunner.startTest();
-}
-
-private function createSuite():TestSuite
-{
- var ts:TestSuite = new TestSuite();
-
- // utils
- ts.addTestSuite( StringUtilTest );
- ts.addTestSuite( NumberFormatterTest );
- ts.addTestSuite( ArrayUtilTest );
- ts.addTestSuite( DateUtilTest );
- ts.addTestSuite( IntUtilTest );
- ts.addTestSuite( XMLUtilTest );
- ts.addTestSuite( DictionaryUtilTest );
-
- // crypto
- ts.addTestSuite( HMACSHA1Test );
- ts.addTestSuite( HMACMD5Test );
- ts.addTestSuite( MD5Test );
- ts.addTestSuite( SHA1Test );
- ts.addTestSuite( SHA224Test );
- ts.addTestSuite( SHA256Test );
- ts.addTestSuite( WSSEUsernameTokenTest );
-
- // net
- ts.addTestSuite( URITest );
-
- // serialization
- ts.addTestSuite( JSONTest );
-
- //images
- ts.addTestSuite( JPGEncoderTest );
- ts.addTestSuite( PNGEncoderTest );
-
- //protocols.dict
- ts.addTestSuite(ConnectedEventTest);
- ts.addTestSuite(DatabaseEventTest);
- ts.addTestSuite(DefinitionEventTest);
- ts.addTestSuite(DefinitionHeaderEventTest);
- ts.addTestSuite(DictionaryServerEventTest);
- ts.addTestSuite(DisconnectedEventTest);
- ts.addTestSuite(ErrorEventTest);
- ts.addTestSuite(MatchEventTest);
- ts.addTestSuite(MatchStrategiesEventTest);
- ts.addTestSuite(NoMatchEventTest);
- ts.addTestSuite(CompletedResponseEventTest);
-
- //webapis
- ts.addTestSuite(ServiceEventTest);