Dodanie aplikacji sorl.thumbnail i filebrowser.
[redakcja.git] / apps / filebrowser / media / filebrowser / uploadify / com / adobe / serialization / json / JSONTokenizer.as
diff --git a/apps/filebrowser/media/filebrowser/uploadify/com/adobe/serialization/json/JSONTokenizer.as b/apps/filebrowser/media/filebrowser/uploadify/com/adobe/serialization/json/JSONTokenizer.as
new file mode 100755 (executable)
index 0000000..dc36bfc
--- /dev/null
@@ -0,0 +1,583 @@
+/*\r
+  Copyright (c) 2008, Adobe Systems Incorporated\r
+  All rights reserved.\r
+\r
+  Redistribution and use in source and binary forms, with or without \r
+  modification, are permitted provided that the following conditions are\r
+  met:\r
+\r
+  * Redistributions of source code must retain the above copyright notice, \r
+    this list of conditions and the following disclaimer.\r
+  \r
+  * Redistributions in binary form must reproduce the above copyright\r
+    notice, this list of conditions and the following disclaimer in the \r
+    documentation and/or other materials provided with the distribution.\r
+  \r
+  * Neither the name of Adobe Systems Incorporated nor the names of its \r
+    contributors may be used to endorse or promote products derived from \r
+    this software without specific prior written permission.\r
+\r
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS\r
+  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
+  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \r
+  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+*/\r
+\r
+package com.adobe.serialization.json {\r
+\r
+       public class JSONTokenizer {\r
+       \r
+               /** The object that will get parsed from the JSON string */\r
+               private var obj:Object;\r
+               \r
+               /** The JSON string to be parsed */\r
+               private var jsonString:String;\r
+               \r
+               /** The current parsing location in the JSON string */\r
+               private var loc:int;\r
+               \r
+               /** The current character in the JSON string during parsing */\r
+               private var ch:String;\r
+               \r
+               /**\r
+                * Constructs a new JSONDecoder to parse a JSON string \r
+                * into a native object.\r
+                *\r
+                * @param s The JSON string to be converted\r
+                *              into a native object\r
+                */\r
+               public function JSONTokenizer( s:String ) {\r
+                       jsonString = s;\r
+                       loc = 0;\r
+                       \r
+                       // prime the pump by getting the first character\r
+                       nextChar();\r
+               }\r
+               \r
+               /**\r
+                * Gets the next token in the input sting and advances\r
+               * the character to the next character after the token\r
+                */\r
+               public function getNextToken():JSONToken {\r
+                       var token:JSONToken = new JSONToken();\r
+                       \r
+                       // skip any whitespace / comments since the last \r
+                       // token was read\r
+                       skipIgnored();\r
+                                               \r
+                       // examine the new character and see what we have...\r
+                       switch ( ch ) {\r
+                               \r
+                               case '{':\r
+                                       token.type = JSONTokenType.LEFT_BRACE;\r
+                                       token.value = '{';\r
+                                       nextChar();\r
+                                       break\r
+                                       \r
+                               case '}':\r
+                                       token.type = JSONTokenType.RIGHT_BRACE;\r
+                                       token.value = '}';\r
+                                       nextChar();\r
+                                       break\r
+                                       \r
+                               case '[':\r
+                                       token.type = JSONTokenType.LEFT_BRACKET;\r
+                                       token.value = '[';\r
+                                       nextChar();\r
+                                       break\r
+                                       \r
+                               case ']':\r
+                                       token.type = JSONTokenType.RIGHT_BRACKET;\r
+                                       token.value = ']';\r
+                                       nextChar();\r
+                                       break\r
+                               \r
+                               case ',':\r
+                                       token.type = JSONTokenType.COMMA;\r
+                                       token.value = ',';\r
+                                       nextChar();\r
+                                       break\r
+                                       \r
+                               case ':':\r
+                                       token.type = JSONTokenType.COLON;\r
+                                       token.value = ':';\r
+                                       nextChar();\r
+                                       break;\r
+                                       \r
+                               case 't': // attempt to read true\r
+                                       var possibleTrue:String = "t" + nextChar() + nextChar() + nextChar();\r
+                                       \r
+                                       if ( possibleTrue == "true" ) {\r
+                                               token.type = JSONTokenType.TRUE;\r
+                                               token.value = true;\r
+                                               nextChar();\r
+                                       } else {\r
+                                               parseError( "Expecting 'true' but found " + possibleTrue );\r
+                                       }\r
+                                       \r
+                                       break;\r
+                                       \r
+                               case 'f': // attempt to read false\r
+                                       var possibleFalse:String = "f" + nextChar() + nextChar() + nextChar() + nextChar();\r
+                                       \r
+                                       if ( possibleFalse == "false" ) {\r
+                                               token.type = JSONTokenType.FALSE;\r
+                                               token.value = false;\r
+                                               nextChar();\r
+                                       } else {\r
+                                               parseError( "Expecting 'false' but found " + possibleFalse );\r
+                                       }\r
+                                       \r
+                                       break;\r
+                                       \r
+                               case 'n': // attempt to read null\r
+                               \r
+                                       var possibleNull:String = "n" + nextChar() + nextChar() + nextChar();\r
+                                       \r
+                                       if ( possibleNull == "null" ) {\r
+                                               token.type = JSONTokenType.NULL;\r
+                                               token.value = null;\r
+                                               nextChar();\r
+                                       } else {\r
+                                               parseError( "Expecting 'null' but found " + possibleNull );\r
+                                       }\r
+                                       \r
+                                       break;\r
+                                       \r
+                               case '"': // the start of a string\r
+                                       token = readString();\r
+                                       break;\r
+                                       \r
+                               default: \r
+                                       // see if we can read a number\r
+                                       if ( isDigit( ch ) || ch == '-' ) {\r
+                                               token = readNumber();\r
+                                       } else if ( ch == '' ) {\r
+                                               // check for reading past the end of the string\r
+                                               return null;\r
+                                       } else {                                                \r
+                                               // not sure what was in the input string - it's not\r
+                                               // anything we expected\r
+                                               parseError( "Unexpected " + ch + " encountered" );\r
+                                       }\r
+                       }\r
+                       \r
+                       return token;\r
+               }\r
+               \r
+               /**\r
+                * Attempts to read a string from the input string.  Places\r
+                * the character location at the first character after the\r
+                * string.  It is assumed that ch is " before this method is called.\r
+                *\r
+                * @return the JSONToken with the string value if a string could\r
+                *              be read.  Throws an error otherwise.\r
+                */\r
+               private function readString():JSONToken {\r
+                       // the token for the string we'll try to read\r
+                       var token:JSONToken = new JSONToken();\r
+                       token.type = JSONTokenType.STRING;\r
+                       \r
+                       // the string to store the string we'll try to read\r
+                       var string:String = "";\r
+                       \r
+                       // advance past the first "\r
+                       nextChar();\r
+                       \r
+                       while ( ch != '"' && ch != '' ) {\r
+                                                               \r
+                               // unescape the escape sequences in the string\r
+                               if ( ch == '\\' ) {\r
+                                       \r
+                                       // get the next character so we know what\r
+                                       // to unescape\r
+                                       nextChar();\r
+                                       \r
+                                       switch ( ch ) {\r
+                                               \r
+                                               case '"': // quotation mark\r
+                                                       string += '"';\r
+                                                       break;\r
+                                               \r
+                                               case '/':       // solidus\r
+                                                       string += "/";\r
+                                                       break;\r
+                                                       \r
+                                               case '\\':      // reverse solidus\r
+                                                       string += '\\';\r
+                                                       break;\r
+                                                       \r
+                                               case 'b':       // bell\r
+                                                       string += '\b';\r
+                                                       break;\r
+                                                       \r
+                                               case 'f':       // form feed\r
+                                                       string += '\f';\r
+                                                       break;\r
+                                                       \r
+                                               case 'n':       // newline\r
+                                                       string += '\n';\r
+                                                       break;\r
+                                                       \r
+                                               case 'r':       // carriage return\r
+                                                       string += '\r';\r
+                                                       break;\r
+                                                       \r
+                                               case 't':       // horizontal tab\r
+                                                       string += '\t'\r
+                                                       break;\r
+                                               \r
+                                               case 'u':\r
+                                                       // convert a unicode escape sequence\r
+                                                       // to it's character value - expecting\r
+                                                       // 4 hex digits\r
+                                                       \r
+                                                       // save the characters as a string we'll convert to an int\r
+                                                       var hexValue:String = "";\r
+                                                       \r
+                                                       // try to find 4 hex characters\r
+                                                       for ( var i:int = 0; i < 4; i++ ) {\r
+                                                               // get the next character and determine\r
+                                                               // if it's a valid hex digit or not\r
+                                                               if ( !isHexDigit( nextChar() ) ) {\r
+                                                                       parseError( " Excepted a hex digit, but found: " + ch );\r
+                                                               }\r
+                                                               // valid, add it to the value\r
+                                                               hexValue += ch;\r
+                                                       }\r
+                                                       \r
+                                                       // convert hexValue to an integer, and use that\r
+                                                       // integrer value to create a character to add\r
+                                                       // to our string.\r
+                                                       string += String.fromCharCode( parseInt( hexValue, 16 ) );\r
+                                                       \r
+                                                       break;\r
+                                       \r
+                                               default:\r
+                                                       // couldn't unescape the sequence, so just\r
+                                                       // pass it through\r
+                                                       string += '\\' + ch;\r
+                                               \r
+                                       }\r
+                                       \r
+                               } else {\r
+                                       // didn't have to unescape, so add the character to the string\r
+                                       string += ch;\r
+                                       \r
+                               }\r
+                               \r
+                               // move to the next character\r
+                               nextChar();\r
+                               \r
+                       }\r
+                       \r
+                       // we read past the end of the string without closing it, which\r
+                       // is a parse error\r
+                       if ( ch == '' ) {\r
+                               parseError( "Unterminated string literal" );\r
+                       }\r
+                       \r
+                       // move past the closing " in the input string\r
+                       nextChar();\r
+                       \r
+                       // attach to the string to the token so we can return it\r
+                       token.value = string;\r
+                       \r
+                       return token;\r
+               }\r
+               \r
+               /**\r
+                * Attempts to read a number from the input string.  Places\r
+                * the character location at the first character after the\r
+                * number.\r
+                * \r
+                * @return The JSONToken with the number value if a number could\r
+                *              be read.  Throws an error otherwise.\r
+                */\r
+               private function readNumber():JSONToken {\r
+                       // the token for the number we'll try to read\r
+                       var token:JSONToken = new JSONToken();\r
+                       token.type = JSONTokenType.NUMBER;\r
+                       \r
+                       // the string to accumulate the number characters\r
+                       // into that we'll convert to a number at the end\r
+                       var input:String = "";\r
+                       \r
+                       // check for a negative number\r
+                       if ( ch == '-' ) {\r
+                               input += '-';\r
+                               nextChar();\r
+                       }\r
+                       \r
+                       // the number must start with a digit\r
+                       if ( !isDigit( ch ) )\r
+                       {\r
+                               parseError( "Expecting a digit" );\r
+                       }\r
+                       \r
+                       // 0 can only be the first digit if it\r
+                       // is followed by a decimal point\r
+                       if ( ch == '0' )\r
+                       {\r
+                               input += ch;\r
+                               nextChar();\r
+                               \r
+                               // make sure no other digits come after 0\r
+                               if ( isDigit( ch ) )\r
+                               {\r
+                                       parseError( "A digit cannot immediately follow 0" );\r
+                               }\r
+// Commented out - this should only be available when "strict" is false\r
+//                             // unless we have 0x which starts a hex number\\r
+//                             else if ( ch == 'x' )\r
+//                             {\r
+//                                     // include the x in the input\r
+//                                     input += ch;\r
+//                                     nextChar();\r
+//                                     \r
+//                                     // need at least one hex digit after 0x to\r
+//                                     // be valid\r
+//                                     if ( isHexDigit( ch ) )\r
+//                                     {\r
+//                                             input += ch;\r
+//                                             nextChar();\r
+//                                     }\r
+//                                     else\r
+//                                     {\r
+//                                             parseError( "Number in hex format require at least one hex digit after \"0x\"" );       \r
+//                                     }\r
+//                                     \r
+//                                     // consume all of the hex values\r
+//                                     while ( isHexDigit( ch ) )\r
+//                                     {\r
+//                                             input += ch;\r
+//                                             nextChar();\r
+//                                     }\r
+//                             }\r
+                       }\r
+                       else\r
+                       {\r
+                               // read numbers while we can\r
+                               while ( isDigit( ch ) ) {\r
+                                       input += ch;\r
+                                       nextChar();\r
+                               }\r
+                       }\r
+                       \r
+                       // check for a decimal value\r
+                       if ( ch == '.' ) {\r
+                               input += '.';\r
+                               nextChar();\r
+                               \r
+                               // after the decimal there has to be a digit\r
+                               if ( !isDigit( ch ) )\r
+                               {\r
+                                       parseError( "Expecting a digit" );\r
+                               }\r
+                               \r
+                               // read more numbers to get the decimal value\r
+                               while ( isDigit( ch ) ) {\r
+                                       input += ch;\r
+                                       nextChar();\r
+                               }\r
+                       }\r
+                       \r
+                       // check for scientific notation\r
+                       if ( ch == 'e' || ch == 'E' )\r
+                       {\r
+                               input += "e"\r
+                               nextChar();\r
+                               // check for sign\r
+                               if ( ch == '+' || ch == '-' )\r
+                               {\r
+                                       input += ch;\r
+                                       nextChar();\r
+                               }\r
+                               \r
+                               // require at least one number for the exponent\r
+                               // in this case\r
+                               if ( !isDigit( ch ) )\r
+                               {\r
+                                       parseError( "Scientific notation number needs exponent value" );\r
+                               }\r
+                                                       \r
+                               // read in the exponent\r
+                               while ( isDigit( ch ) )\r
+                               {\r
+                                       input += ch;\r
+                                       nextChar();\r
+                               }\r
+                       }\r
+                       \r
+                       // convert the string to a number value\r
+                       var num:Number = Number( input );\r
+                       \r
+                       if ( isFinite( num ) && !isNaN( num ) ) {\r
+                               token.value = num;\r
+                               return token;\r
+                       } else {\r
+                               parseError( "Number " + num + " is not valid!" );\r
+                       }\r
+            return null;\r
+               }\r
+\r
+               /**\r
+                * Reads the next character in the input\r
+                * string and advances the character location.\r
+                *\r
+                * @return The next character in the input string, or\r
+                *              null if we've read past the end.\r
+                */\r
+               private function nextChar():String {\r
+                       return ch = jsonString.charAt( loc++ );\r
+               }\r
+               \r
+               /**\r
+                * Advances the character location past any\r
+                * sort of white space and comments\r
+                */\r
+               private function skipIgnored():void\r
+               {\r
+                       var originalLoc:int;\r
+                       \r
+                       // keep trying to skip whitespace and comments as long\r
+                       // as we keep advancing past the original location \r
+                       do\r
+                       {\r
+                               originalLoc = loc;\r
+                               skipWhite();\r
+                               skipComments();\r
+                       }\r
+                       while ( originalLoc != loc );\r
+               }\r
+               \r
+               /**\r
+                * Skips comments in the input string, either\r
+                * single-line or multi-line.  Advances the character\r
+                * to the first position after the end of the comment.\r
+                */\r
+               private function skipComments():void {\r
+                       if ( ch == '/' ) {\r
+                               // Advance past the first / to find out what type of comment\r
+                               nextChar();\r
+                               switch ( ch ) {\r
+                                       case '/': // single-line comment, read through end of line\r
+                                               \r
+                                               // Loop over the characters until we find\r
+                                               // a newline or until there's no more characters left\r
+                                               do {\r
+                                                       nextChar();\r
+                                               } while ( ch != '\n' && ch != '' )\r
+                                               \r
+                                               // move past the \n\r
+                                               nextChar();\r
+                                               \r
+                                               break;\r
+                                       \r
+                                       case '*': // multi-line comment, read until closing */\r
+\r
+                                               // move past the opening *\r
+                                               nextChar();\r
+                                               \r
+                                               // try to find a trailing */\r
+                                               while ( true ) {\r
+                                                       if ( ch == '*' ) {\r
+                                                               // check to see if we have a closing /\r
+                                                               nextChar();\r
+                                                               if ( ch == '/') {\r
+                                                                       // move past the end of the closing */\r
+                                                                       nextChar();\r
+                                                                       break;\r
+                                                               }\r
+                                                       } else {\r
+                                                               // move along, looking if the next character is a *\r
+                                                               nextChar();\r
+                                                       }\r
+                                                       \r
+                                                       // when we're here we've read past the end of \r
+                                                       // the string without finding a closing */, so error\r
+                                                       if ( ch == '' ) {\r
+                                                               parseError( "Multi-line comment not closed" );\r
+                                                       }\r
+                                               }\r
+\r
+                                               break;\r
+                                       \r
+                                       // Can't match a comment after a /, so it's a parsing error\r
+                                       default:\r
+                                               parseError( "Unexpected " + ch + " encountered (expecting '/' or '*' )" );\r
+                               }\r
+                       }\r
+                       \r
+               }\r
+               \r
+               \r
+               /**\r
+                * Skip any whitespace in the input string and advances\r
+                * the character to the first character after any possible\r
+                * whitespace.\r
+                */\r
+               private function skipWhite():void {\r
+                       \r
+                       // As long as there are spaces in the input \r
+                       // stream, advance the current location pointer\r
+                       // past them\r
+                       while ( isWhiteSpace( ch ) ) {\r
+                               nextChar();\r
+                       }\r
+                       \r
+               }\r
+               \r
+               /**\r
+                * Determines if a character is whitespace or not.\r
+                *\r
+                * @return True if the character passed in is a whitespace\r
+                *      character\r
+                */\r
+               private function isWhiteSpace( ch:String ):Boolean {\r
+                       return ( ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' );\r
+               }\r
+               \r
+               /**\r
+                * Determines if a character is a digit [0-9].\r
+                *\r
+                * @return True if the character passed in is a digit\r
+                */\r
+               private function isDigit( ch:String ):Boolean {\r
+                       return ( ch >= '0' && ch <= '9' );\r
+               }\r
+               \r
+               /**\r
+                * Determines if a character is a digit [0-9].\r
+                *\r
+                * @return True if the character passed in is a digit\r
+                */\r
+               private function isHexDigit( ch:String ):Boolean {\r
+                       // get the uppercase value of ch so we only have\r
+                       // to compare the value between 'A' and 'F'\r
+                       var uc:String = ch.toUpperCase();\r
+                       \r
+                       // a hex digit is a digit of A-F, inclusive ( using\r
+                       // our uppercase constraint )\r
+                       return ( isDigit( ch ) || ( uc >= 'A' && uc <= 'F' ) );\r
+               }\r
+       \r
+               /**\r
+                * Raises a parsing error with a specified message, tacking\r
+                * on the error location and the original string.\r
+                *\r
+                * @param message The message indicating why the error occurred\r
+                */\r
+               public function parseError( message:String ):void {\r
+                       throw new JSONParseError( message, loc, jsonString );\r
+               }\r
+       }\r
+       \r
+}\r