]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.10/Lib/json/decoder.py
AppPkg/Applications/Python/Python-2.7.10: Initial Checkin part 4/5.
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Lib / json / decoder.py
diff --git a/AppPkg/Applications/Python/Python-2.7.10/Lib/json/decoder.py b/AppPkg/Applications/Python/Python-2.7.10/Lib/json/decoder.py
new file mode 100644 (file)
index 0000000..f2a4829
--- /dev/null
@@ -0,0 +1,385 @@
+"""Implementation of JSONDecoder\r
+"""\r
+import re\r
+import sys\r
+import struct\r
+\r
+from json import scanner\r
+try:\r
+    from _json import scanstring as c_scanstring\r
+except ImportError:\r
+    c_scanstring = None\r
+\r
+__all__ = ['JSONDecoder']\r
+\r
+FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL\r
+\r
+def _floatconstants():\r
+    _BYTES = '7FF80000000000007FF0000000000000'.decode('hex')\r
+    if sys.byteorder != 'big':\r
+        _BYTES = _BYTES[:8][::-1] + _BYTES[8:][::-1]\r
+    nan, inf = struct.unpack('dd', _BYTES)\r
+    return nan, inf, -inf\r
+\r
+NaN, PosInf, NegInf = _floatconstants()\r
+\r
+\r
+def linecol(doc, pos):\r
+    lineno = doc.count('\n', 0, pos) + 1\r
+    if lineno == 1:\r
+        colno = pos + 1\r
+    else:\r
+        colno = pos - doc.rindex('\n', 0, pos)\r
+    return lineno, colno\r
+\r
+\r
+def errmsg(msg, doc, pos, end=None):\r
+    # Note that this function is called from _json\r
+    lineno, colno = linecol(doc, pos)\r
+    if end is None:\r
+        fmt = '{0}: line {1} column {2} (char {3})'\r
+        return fmt.format(msg, lineno, colno, pos)\r
+        #fmt = '%s: line %d column %d (char %d)'\r
+        #return fmt % (msg, lineno, colno, pos)\r
+    endlineno, endcolno = linecol(doc, end)\r
+    fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'\r
+    return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)\r
+    #fmt = '%s: line %d column %d - line %d column %d (char %d - %d)'\r
+    #return fmt % (msg, lineno, colno, endlineno, endcolno, pos, end)\r
+\r
+\r
+_CONSTANTS = {\r
+    '-Infinity': NegInf,\r
+    'Infinity': PosInf,\r
+    'NaN': NaN,\r
+}\r
+\r
+STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS)\r
+BACKSLASH = {\r
+    '"': u'"', '\\': u'\\', '/': u'/',\r
+    'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t',\r
+}\r
+\r
+DEFAULT_ENCODING = "utf-8"\r
+\r
+def _decode_uXXXX(s, pos):\r
+    esc = s[pos + 1:pos + 5]\r
+    if len(esc) == 4 and esc[1] not in 'xX':\r
+        try:\r
+            return int(esc, 16)\r
+        except ValueError:\r
+            pass\r
+    msg = "Invalid \\uXXXX escape"\r
+    raise ValueError(errmsg(msg, s, pos))\r
+\r
+def py_scanstring(s, end, encoding=None, strict=True,\r
+        _b=BACKSLASH, _m=STRINGCHUNK.match):\r
+    """Scan the string s for a JSON string. End is the index of the\r
+    character in s after the quote that started the JSON string.\r
+    Unescapes all valid JSON string escape sequences and raises ValueError\r
+    on attempt to decode an invalid string. If strict is False then literal\r
+    control characters are allowed in the string.\r
+\r
+    Returns a tuple of the decoded string and the index of the character in s\r
+    after the end quote."""\r
+    if encoding is None:\r
+        encoding = DEFAULT_ENCODING\r
+    chunks = []\r
+    _append = chunks.append\r
+    begin = end - 1\r
+    while 1:\r
+        chunk = _m(s, end)\r
+        if chunk is None:\r
+            raise ValueError(\r
+                errmsg("Unterminated string starting at", s, begin))\r
+        end = chunk.end()\r
+        content, terminator = chunk.groups()\r
+        # Content is contains zero or more unescaped string characters\r
+        if content:\r
+            if not isinstance(content, unicode):\r
+                content = unicode(content, encoding)\r
+            _append(content)\r
+        # Terminator is the end of string, a literal control character,\r
+        # or a backslash denoting that an escape sequence follows\r
+        if terminator == '"':\r
+            break\r
+        elif terminator != '\\':\r
+            if strict:\r
+                #msg = "Invalid control character %r at" % (terminator,)\r
+                msg = "Invalid control character {0!r} at".format(terminator)\r
+                raise ValueError(errmsg(msg, s, end))\r
+            else:\r
+                _append(terminator)\r
+                continue\r
+        try:\r
+            esc = s[end]\r
+        except IndexError:\r
+            raise ValueError(\r
+                errmsg("Unterminated string starting at", s, begin))\r
+        # If not a unicode escape sequence, must be in the lookup table\r
+        if esc != 'u':\r
+            try:\r
+                char = _b[esc]\r
+            except KeyError:\r
+                msg = "Invalid \\escape: " + repr(esc)\r
+                raise ValueError(errmsg(msg, s, end))\r
+            end += 1\r
+        else:\r
+            # Unicode escape sequence\r
+            uni = _decode_uXXXX(s, end)\r
+            end += 5\r
+            # Check for surrogate pair on UCS-4 systems\r
+            if sys.maxunicode > 65535 and \\r
+               0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\\u':\r
+                uni2 = _decode_uXXXX(s, end + 1)\r
+                if 0xdc00 <= uni2 <= 0xdfff:\r
+                    uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))\r
+                    end += 6\r
+            char = unichr(uni)\r
+        # Append the unescaped character\r
+        _append(char)\r
+    return u''.join(chunks), end\r
+\r
+\r
+# Use speedup if available\r
+scanstring = c_scanstring or py_scanstring\r
+\r
+WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)\r
+WHITESPACE_STR = ' \t\n\r'\r
+\r
+def JSONObject(s_and_end, encoding, strict, scan_once, object_hook,\r
+               object_pairs_hook, _w=WHITESPACE.match, _ws=WHITESPACE_STR):\r
+    s, end = s_and_end\r
+    pairs = []\r
+    pairs_append = pairs.append\r
+    # Use a slice to prevent IndexError from being raised, the following\r
+    # check will raise a more specific ValueError if the string is empty\r
+    nextchar = s[end:end + 1]\r
+    # Normally we expect nextchar == '"'\r
+    if nextchar != '"':\r
+        if nextchar in _ws:\r
+            end = _w(s, end).end()\r
+            nextchar = s[end:end + 1]\r
+        # Trivial empty object\r
+        if nextchar == '}':\r
+            if object_pairs_hook is not None:\r
+                result = object_pairs_hook(pairs)\r
+                return result, end + 1\r
+            pairs = {}\r
+            if object_hook is not None:\r
+                pairs = object_hook(pairs)\r
+            return pairs, end + 1\r
+        elif nextchar != '"':\r
+            raise ValueError(errmsg(\r
+                "Expecting property name enclosed in double quotes", s, end))\r
+    end += 1\r
+    while True:\r
+        key, end = scanstring(s, end, encoding, strict)\r
+\r
+        # To skip some function call overhead we optimize the fast paths where\r
+        # the JSON key separator is ": " or just ":".\r
+        if s[end:end + 1] != ':':\r
+            end = _w(s, end).end()\r
+            if s[end:end + 1] != ':':\r
+                raise ValueError(errmsg("Expecting ':' delimiter", s, end))\r
+        end += 1\r
+\r
+        try:\r
+            if s[end] in _ws:\r
+                end += 1\r
+                if s[end] in _ws:\r
+                    end = _w(s, end + 1).end()\r
+        except IndexError:\r
+            pass\r
+\r
+        try:\r
+            value, end = scan_once(s, end)\r
+        except StopIteration:\r
+            raise ValueError(errmsg("Expecting object", s, end))\r
+        pairs_append((key, value))\r
+\r
+        try:\r
+            nextchar = s[end]\r
+            if nextchar in _ws:\r
+                end = _w(s, end + 1).end()\r
+                nextchar = s[end]\r
+        except IndexError:\r
+            nextchar = ''\r
+        end += 1\r
+\r
+        if nextchar == '}':\r
+            break\r
+        elif nextchar != ',':\r
+            raise ValueError(errmsg("Expecting ',' delimiter", s, end - 1))\r
+\r
+        try:\r
+            nextchar = s[end]\r
+            if nextchar in _ws:\r
+                end += 1\r
+                nextchar = s[end]\r
+                if nextchar in _ws:\r
+                    end = _w(s, end + 1).end()\r
+                    nextchar = s[end]\r
+        except IndexError:\r
+            nextchar = ''\r
+\r
+        end += 1\r
+        if nextchar != '"':\r
+            raise ValueError(errmsg(\r
+                "Expecting property name enclosed in double quotes", s, end - 1))\r
+    if object_pairs_hook is not None:\r
+        result = object_pairs_hook(pairs)\r
+        return result, end\r
+    pairs = dict(pairs)\r
+    if object_hook is not None:\r
+        pairs = object_hook(pairs)\r
+    return pairs, end\r
+\r
+def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):\r
+    s, end = s_and_end\r
+    values = []\r
+    nextchar = s[end:end + 1]\r
+    if nextchar in _ws:\r
+        end = _w(s, end + 1).end()\r
+        nextchar = s[end:end + 1]\r
+    # Look-ahead for trivial empty array\r
+    if nextchar == ']':\r
+        return values, end + 1\r
+    _append = values.append\r
+    while True:\r
+        try:\r
+            value, end = scan_once(s, end)\r
+        except StopIteration:\r
+            raise ValueError(errmsg("Expecting object", s, end))\r
+        _append(value)\r
+        nextchar = s[end:end + 1]\r
+        if nextchar in _ws:\r
+            end = _w(s, end + 1).end()\r
+            nextchar = s[end:end + 1]\r
+        end += 1\r
+        if nextchar == ']':\r
+            break\r
+        elif nextchar != ',':\r
+            raise ValueError(errmsg("Expecting ',' delimiter", s, end))\r
+        try:\r
+            if s[end] in _ws:\r
+                end += 1\r
+                if s[end] in _ws:\r
+                    end = _w(s, end + 1).end()\r
+        except IndexError:\r
+            pass\r
+\r
+    return values, end\r
+\r
+class JSONDecoder(object):\r
+    """Simple JSON <http://json.org> decoder\r
+\r
+    Performs the following translations in decoding by default:\r
+\r
+    +---------------+-------------------+\r
+    | JSON          | Python            |\r
+    +===============+===================+\r
+    | object        | dict              |\r
+    +---------------+-------------------+\r
+    | array         | list              |\r
+    +---------------+-------------------+\r
+    | string        | unicode           |\r
+    +---------------+-------------------+\r
+    | number (int)  | int, long         |\r
+    +---------------+-------------------+\r
+    | number (real) | float             |\r
+    +---------------+-------------------+\r
+    | true          | True              |\r
+    +---------------+-------------------+\r
+    | false         | False             |\r
+    +---------------+-------------------+\r
+    | null          | None              |\r
+    +---------------+-------------------+\r
+\r
+    It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as\r
+    their corresponding ``float`` values, which is outside the JSON spec.\r
+\r
+    """\r
+\r
+    def __init__(self, encoding=None, object_hook=None, parse_float=None,\r
+            parse_int=None, parse_constant=None, strict=True,\r
+            object_pairs_hook=None):\r
+        """``encoding`` determines the encoding used to interpret any ``str``\r
+        objects decoded by this instance (utf-8 by default).  It has no\r
+        effect when decoding ``unicode`` objects.\r
+\r
+        Note that currently only encodings that are a superset of ASCII work,\r
+        strings of other encodings should be passed in as ``unicode``.\r
+\r
+        ``object_hook``, if specified, will be called with the result\r
+        of every JSON object decoded and its return value will be used in\r
+        place of the given ``dict``.  This can be used to provide custom\r
+        deserializations (e.g. to support JSON-RPC class hinting).\r
+\r
+        ``object_pairs_hook``, if specified will be called with the result of\r
+        every JSON object decoded with an ordered list of pairs.  The return\r
+        value of ``object_pairs_hook`` will be used instead of the ``dict``.\r
+        This feature can be used to implement custom decoders that rely on the\r
+        order that the key and value pairs are decoded (for example,\r
+        collections.OrderedDict will remember the order of insertion). If\r
+        ``object_hook`` is also defined, the ``object_pairs_hook`` takes\r
+        priority.\r
+\r
+        ``parse_float``, if specified, will be called with the string\r
+        of every JSON float to be decoded. By default this is equivalent to\r
+        float(num_str). This can be used to use another datatype or parser\r
+        for JSON floats (e.g. decimal.Decimal).\r
+\r
+        ``parse_int``, if specified, will be called with the string\r
+        of every JSON int to be decoded. By default this is equivalent to\r
+        int(num_str). This can be used to use another datatype or parser\r
+        for JSON integers (e.g. float).\r
+\r
+        ``parse_constant``, if specified, will be called with one of the\r
+        following strings: -Infinity, Infinity, NaN.\r
+        This can be used to raise an exception if invalid JSON numbers\r
+        are encountered.\r
+\r
+        If ``strict`` is false (true is the default), then control\r
+        characters will be allowed inside strings.  Control characters in\r
+        this context are those with character codes in the 0-31 range,\r
+        including ``'\\t'`` (tab), ``'\\n'``, ``'\\r'`` and ``'\\0'``.\r
+\r
+        """\r
+        self.encoding = encoding\r
+        self.object_hook = object_hook\r
+        self.object_pairs_hook = object_pairs_hook\r
+        self.parse_float = parse_float or float\r
+        self.parse_int = parse_int or int\r
+        self.parse_constant = parse_constant or _CONSTANTS.__getitem__\r
+        self.strict = strict\r
+        self.parse_object = JSONObject\r
+        self.parse_array = JSONArray\r
+        self.parse_string = scanstring\r
+        self.scan_once = scanner.make_scanner(self)\r
+\r
+    def decode(self, s, _w=WHITESPACE.match):\r
+        """Return the Python representation of ``s`` (a ``str`` or ``unicode``\r
+        instance containing a JSON document)\r
+\r
+        """\r
+        obj, end = self.raw_decode(s, idx=_w(s, 0).end())\r
+        end = _w(s, end).end()\r
+        if end != len(s):\r
+            raise ValueError(errmsg("Extra data", s, end, len(s)))\r
+        return obj\r
+\r
+    def raw_decode(self, s, idx=0):\r
+        """Decode a JSON document from ``s`` (a ``str`` or ``unicode``\r
+        beginning with a JSON document) and return a 2-tuple of the Python\r
+        representation and the index in ``s`` where the document ended.\r
+\r
+        This can be used to decode a JSON document from a string that may\r
+        have extraneous data at the end.\r
+\r
+        """\r
+        try:\r
+            obj, end = self.scan_once(s, idx)\r
+        except StopIteration:\r
+            raise ValueError("No JSON object could be decoded")\r
+        return obj, end\r