[z3-checkins] r27148 - z3/jsonserver/branch/merge

reebalazs at codespeak.net reebalazs at codespeak.net
Fri May 12 19:04:20 CEST 2006


Author: reebalazs
Date: Fri May 12 19:04:19 2006
New Revision: 27148

Removed:
   z3/jsonserver/branch/merge/minjson.py
Modified:
   z3/jsonserver/branch/merge/configure.zcml
Log:
Use new minjson

Modified: z3/jsonserver/branch/merge/configure.zcml
==============================================================================
--- z3/jsonserver/branch/merge/configure.zcml	(original)
+++ z3/jsonserver/branch/merge/configure.zcml	Fri May 12 19:04:19 2006
@@ -5,6 +5,8 @@
            i18n_domain="zope"
            >
 
+  <include package=".minjson" />
+
   <publisher
     name="JSONRPC"
     factory=".requestpublicationfactory.JSONRPCFactory"

Deleted: /z3/jsonserver/branch/merge/minjson.py
==============================================================================
--- /z3/jsonserver/branch/merge/minjson.py	Fri May 12 19:04:19 2006
+++ (empty file)
@@ -1,436 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2005 Jim Washington and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-# minjson.py
-# reads minimal javascript objects.
-# str's objects and fixes the text to write javascript.
-
-#UNICODE USAGE:  Minjson tries hard to accommodate naive usage in a 
-#"Do what I mean" manner.  Real applications should handle unicode separately.
-# The "right" way to use minjson in an application is to provide minjson a 
-# python unicode string for reading and accept a unicode output from minjson's
-# writing.  That way, the assumptions for unicode are yours and not minjson's.
-
-# That said, the minjson code has some (optional) unicode handling that you 
-# may look at as a model for the unicode handling your application may need.
-
-# Thanks to Patrick Logan for starting the json-py project and making so many
-# good test cases.
-
-# Additional thanks to Balazs Ree for replacing the writing module.
-
-# Jim Washington 30 Dec 2005.
-
-# 2005-12-30 writing now traverses the object tree instead of relying on 
-#            str() or unicode()
-# 2005-10-10 on reading, looks for \\uxxxx and replaces with u'\uxxxx'
-# 2005-10-09 now tries hard to make all strings unicode when reading.
-# 2005-10-07 got rid of eval() completely, makes object as found by the
-#            tokenizer.
-# 2005-09-06 imported parsing constants from tokenize; they changed a bit from
-#            python2.3 to 2.4
-# 2005-08-22 replaced the read sanity code
-# 2005-08-21 Search for exploits on eval() yielded more default bad operators.
-# 2005-08-18 Added optional code from Koen van de Sande to escape
-#            outgoing unicode chars above 128
-
-
-from re import compile, sub, search, DOTALL
-from token import ENDMARKER, NAME, NUMBER, STRING, OP, ERRORTOKEN
-from tokenize import tokenize, TokenError, NL
-
-#Usually, utf-8 will work, set this to utf-16 if you dare.
-emergencyEncoding = 'utf-8'
-
-class ReadException(Exception):
-    pass
-
-class WriteException(Exception):
-    pass
-
-#################################
-#      read JSON object         #
-#################################
-
-slashstarcomment = compile(r'/\*.*?\*/',DOTALL)
-doubleslashcomment = compile(r'//.*\n')
-
-unichrRE = compile(r"\\u[0-9a-fA-F]{4,4}")
-
-def unichrReplace(match):
-    return unichr(int(match.group()[2:],16))
-
-escapeStrs = (('\\','\\\\'),('\n',r'\n'),('\b',r'\b'),
-    ('\f',r'\f'),('\t',r'\t'),('\r',r'\r'), ('"',r'\"')
-    )
-
-class DictToken:
-    __slots__=[]
-    pass
-class ListToken:
-    __slots__=[]
-    pass
-class ColonToken:
-    __slots__=[]
-    pass
-class CommaToken:
-    __slots__=[]
-    pass
-
-class JSONReader(object):
-    """raise SyntaxError if it is not JSON, and make the object available"""
-    def __init__(self,data):
-        self.stop = False
-        #make an iterator of data so that next() works in tokenize.
-        self._data = iter([data])
-        self.lastOp = None
-        self.objects = []
-        self.tokenize()
-
-    def tokenize(self):
-        try:
-            tokenize(self._data.next,self.readTokens)
-        except TokenError:
-            raise SyntaxError
-
-    def resolveList(self):
-        #check for empty list
-        if isinstance(self.objects[-1],ListToken):
-            self.objects[-1] = []
-            return
-        theList = []
-        commaCount = 0
-        try:
-            item = self.objects.pop()
-        except IndexError:
-            raise SyntaxError
-        while not isinstance(item,ListToken):
-            if isinstance(item,CommaToken):
-                commaCount += 1
-            else:
-                theList.append(item)
-            try:
-                item = self.objects.pop()
-            except IndexError:
-                raise SyntaxError
-        if not commaCount == (len(theList) -1):
-            raise SyntaxError
-        theList.reverse()
-        item = theList
-        self.objects.append(item)
-
-    def resolveDict(self):
-        theList = []
-        #check for empty dict
-        if isinstance(self.objects[-1], DictToken):
-            self.objects[-1] = {}
-            return
-        #not empty; must have at least three values
-        try:
-            #value (we're going backwards!)
-            value = self.objects.pop()
-        except IndexError:
-            raise SyntaxError
-        try:
-            #colon
-            colon = self.objects.pop()
-            if not isinstance(colon, ColonToken):
-                raise SyntaxError
-        except IndexError:
-            raise SyntaxError
-        try:
-            #key
-            key = self.objects.pop()
-            if not isinstance(key,basestring):
-                raise SyntaxError
-        except IndexError:
-
-            raise SyntaxError
-        #salt the while
-        comma = value
-        while not isinstance(comma,DictToken):
-            # store the value
-            theList.append((key,value))
-            #do it again...
-            try:
-                #might be a comma
-                comma = self.objects.pop()
-            except IndexError:
-                raise SyntaxError
-            if isinstance(comma,CommaToken):
-                #if it's a comma, get the values
-                try:
-                    value = self.objects.pop()
-                except IndexError:
-                    #print self.objects
-                    raise SyntaxError
-                try:
-                    colon = self.objects.pop()
-                    if not isinstance(colon, ColonToken):
-                        raise SyntaxError
-                except IndexError:
-                    raise SyntaxError
-                try:
-                    key = self.objects.pop()
-                    if not isinstance(key,basestring):
-                        raise SyntaxError
-                except IndexError:
-                    raise SyntaxError
-        theDict = {}
-        for k in theList:
-            theDict[k[0]] = k[1]
-        self.objects.append(theDict)
-
-    def readTokens(self,type, token, (srow, scol), (erow, ecol), line):
-        # UPPERCASE consts from tokens.py or tokenize.py
-        if type == OP:
-            if token not in "[{}],:-":
-                raise SyntaxError
-            else:
-                self.lastOp = token
-            if token == '[':
-                self.objects.append(ListToken())
-            elif token == '{':
-                self.objects.append(DictToken())
-            elif token == ']':
-                self.resolveList()
-            elif token == '}':
-                self.resolveDict()
-            elif token == ':':
-                self.objects.append(ColonToken())
-            elif token == ',':
-                self.objects.append(CommaToken())
-        elif type == STRING:
-            tok = token[1:-1]
-            for k in escapeStrs:
-                if k[1] in tok:
-                    tok = tok.replace(k[1],k[0])
-            self.objects.append(tok)
-        elif type == NUMBER:
-            if self.lastOp == '-':
-                factor = -1
-            else:
-                factor = 1
-            try:
-                self.objects.append(factor * int(token))
-            except ValueError:
-                self.objects.append(factor * float(token))
-        elif type == NAME:
-            try:
-                self.objects.append({'true':True,
-                    'false':False,'null':None}[token])
-            except KeyError:
-                raise SyntaxError
-        elif type == ENDMARKER:
-            pass
-        elif type == NL:
-            pass
-        elif type == ERRORTOKEN:
-            if ecol == len(line):
-                #it's a char at the end of the line.  (mostly) harmless.
-                pass
-            else:
-                raise SyntaxError
-        else:
-            raise SyntaxError
-    def output(self):
-        try:
-            assert len(self.objects) == 1
-        except AssertionError:
-            raise SyntaxError
-        return self.objects[0]
-
-def safeRead(aString, encoding=None):
-    """read the js, first sanitizing a bit and removing any c-style comments
-    If the input is a unicode string, great.  That's preferred.  If the input 
-    is a byte string, strings in the object will be produced as unicode anyway.
-    """
-    # get rid of trailing null. Konqueror appends this.
-    CHR0 = chr(0)
-    while aString.endswith(CHR0):
-        aString = aString[:-1]
-    # strip leading and trailing whitespace
-    aString = aString.strip()
-    # zap /* ... */ comments
-    aString = slashstarcomment.sub('',aString)
-    # zap // comments
-    aString = doubleslashcomment.sub('',aString)
-    # detect and handle \\u unicode characters. Note: This has the side effect
-    # of converting the entire string to unicode. This is probably OK.
-    unicodechars = unichrRE.search(aString)
-    if unicodechars:
-        aString = unichrRE.sub(unichrReplace, aString)
-    #if it's already unicode, we won't try to decode it
-    if isinstance(aString, unicode):
-        s = aString
-    else:
-        if encoding:
-            # note: no "try" here.  the encoding provided must work for the
-            # incoming byte string.  UnicodeDecode error will be raised
-            # in that case.  Often, it will be best not to provide the encoding
-            # and allow the default
-            s = unicode(aString, encoding)
-            #print "decoded %s from %s" % (s,encoding)
-        else:
-            # let's try to decode to unicode in system default encoding
-            try:
-                s = unicode(aString)
-                #import sys
-                #print "decoded %s from %s" % (s,sys.getdefaultencoding())
-            except UnicodeDecodeError:
-                # last choice: handle as emergencyEncoding
-                enc = emergencyEncoding
-                s = unicode(aString, enc)
-                #print "%s decoded from %s" % (s, enc)
-    # parse and get the object.
-    try:
-        data = JSONReader(s).output()
-    except SyntaxError:
-        raise ReadException, 'Unacceptable JSON expression: %s' % aString
-    return data
-
-read = safeRead
-
-#################################
-#   write object as JSON        #
-#################################
-
-import re, codecs
-from cStringIO import StringIO
-
-### Codec error handler
-
-def jsonreplace_handler(exc):
-    '''Error handler for json
-
-    If encoding fails, \\uxxxx must be emitted. This
-    is similar to the "backshashreplace" handler, only
-    that we never emit \\xnn since this is not legal
-    according to the JSON syntax specs.
-    '''
-    if isinstance(exc, UnicodeEncodeError):
-        part = exc.object[exc.start]
-        # repr(part) will convert u'\unnnn' to u'u\\nnnn'
-        return u'\\u%04x' % ord(part), exc.start+1
-    else:
-        raise exc
-
-# register the error handler
-codecs.register_error('jsonreplace', jsonreplace_handler)
-
-### Writer
-
-def write(input, encoding='utf-8', outputEncoding=None):
-    writer = JsonWriter(input_encoding=encoding, output_encoding=outputEncoding)
-    writer.write(input)
-    return writer.getvalue()
-
-re_strmangle = re.compile('"|\b|\f|\n|\r|\t|\\\\')
-
-def func_strmangle(match):
-    return {
-        '"': '\\"',
-        '\b': '\\b',
-        '\f': '\\f',
-        '\n': '\\n',
-        '\r': '\\r',
-        '\t': '\\t',
-        '\\': '\\\\',
-        }[match.group(0)]
-
-def strmangle(text):
-    return re_strmangle.sub(func_strmangle, text)
-
-class JsonStream(object):
-
-    def __init__(self):
-        self.buf = []
-
-    def write(self, text):
-        self.buf.append(text)
-
-    def getvalue(self):
-        return ''.join(self.buf)
-
-class JsonWriter(object):
-
-    def __init__(self, stream=None, input_encoding='utf-8', output_encoding=None):
-        '''
-        - stream is optional, if specified must also give output_encoding
-        - The input strings can be unicode or in input_encoding
-        - output_encoding is optional, if omitted, result will be unicode
-        '''
-        if stream is not None:
-            if output_encoding is None:
-                raise WriteException, 'If a stream is given, output encoding must also be provided'
-        else:
-            stream = JsonStream()
-        self.stream = stream
-        self.input_encoding = input_encoding
-        self.output_encoding = output_encoding
-
-    def write(self, obj):
-        if isinstance(obj, (list, tuple)):
-            self.stream.write('[')
-            first = True
-            for elem in obj:
-                if first:
-                    first = False
-                else:
-                    self.stream.write(',')
-                self.write(elem)
-            self.stream.write(']'),
-        elif isinstance(obj, dict):
-            self.stream.write('{')
-            first = True
-            for key, value in obj.iteritems():
-                if first:
-                    first = False
-                else:
-                    self.stream.write(',')
-                self.write(key)
-                self.stream.write(':')
-                self.write(value)
-            self.stream.write('}')
-        elif obj is True:
-            self.stream.write('true')
-        elif obj is False:
-            self.stream.write('false')
-        elif obj is None:
-            self.stream.write('null')
-        elif not isinstance(obj, basestring):
-            # if we are not baseobj, convert to it
-            try:
-                obj = str(obj)
-            except Exception, exc:
-                raise WriteException, 'Cannot write object (%s: %s)' % (exc.__class__, exc)
-            self.stream.write(obj)
-        else:
-            # convert to unicode first
-            if not isinstance(obj, unicode):
-                try:
-                    obj = unicode(obj, self.input_encoding)
-                except (UnicodeDecodeError, UnicodeTranslateError):
-                    obj = unicode(obj, 'utf-8', 'replace')
-            # do the mangling
-            obj = strmangle(obj)
-            # make the encoding
-            if self.output_encoding is not None:
-                obj = obj.encode(self.output_encoding, 'jsonreplace')
-            self.stream.write('"')
-            self.stream.write(obj)
-            self.stream.write('"')
-
-    def getvalue(self):
-        return self.stream.getvalue()


More information about the z3-checkins mailing list