Ignore:
Timestamp:
12/29/08 23:02:04 (5 years ago)
Author:
xi
Message:

Handle the encoding of input and output streams in a uniform way.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pyyaml/trunk/ext/_yaml.pyx

    r331 r333  
    250250    cdef object current_event 
    251251    cdef object anchors 
     252    cdef object stream_cache 
     253    cdef int stream_cache_len 
     254    cdef int stream_cache_pos 
     255    cdef int unicode_source 
    252256 
    253257    def __init__(self, stream): 
     
    261265        except AttributeError: 
    262266            is_readable = 0 
     267        self.unicode_source = 0 
    263268        if is_readable: 
    264269            self.stream = stream 
     
    267272            except AttributeError: 
    268273                self.stream_name = '<file>' 
     274            self.stream_cache = None 
     275            self.stream_cache_len = 0 
     276            self.stream_cache_pos = 0 
    269277            yaml_parser_set_input(&self.parser, input_handler, <void *>self) 
    270278        else: 
     
    272280                stream = PyUnicode_AsUTF8String(stream) 
    273281                self.stream_name = '<unicode string>' 
     282                self.unicode_source = 1 
    274283            else: 
    275                 self.stream_name = '<string>' 
     284                self.stream_name = '<byte string>' 
    276285            if PyString_CheckExact(stream) == 0: 
    277286                raise TypeError("a string or stream input is required") 
     
    364373            encoding = None 
    365374            if token.data.stream_start.encoding == YAML_UTF8_ENCODING: 
    366                 encoding = u"utf-8" 
     375                if self.unicode_source == 0: 
     376                    encoding = u"utf-8" 
    367377            elif token.data.stream_start.encoding == YAML_UTF16LE_ENCODING: 
    368378                encoding = u"utf-16-le" 
     
    516526            encoding = None 
    517527            if event.data.stream_start.encoding == YAML_UTF8_ENCODING: 
    518                 encoding = "utf-8" 
     528                if self.unicode_source == 0: 
     529                    encoding = "utf-8" 
    519530            elif event.data.stream_start.encoding == YAML_UTF16LE_ENCODING: 
    520531                encoding = "utf-16-le" 
     
    878889    cdef CParser parser 
    879890    parser = <CParser>data 
    880     value = parser.stream.read(size) 
    881     if PyUnicode_CheckExact(value) != 0: 
    882         value = PyUnicode_AsUTF8String(value) 
    883     if PyString_CheckExact(value) == 0: 
    884         raise TypeError("a string value is expected") 
    885     if PyString_GET_SIZE(value) > size: 
    886         raise ValueError("a string value it too long") 
    887     memcpy(buffer, PyString_AS_STRING(value), PyString_GET_SIZE(value)) 
    888     read[0] = PyString_GET_SIZE(value) 
     891    if parser.stream_cache is None: 
     892        value = parser.stream.read(size) 
     893        if PyUnicode_CheckExact(value) != 0: 
     894            value = PyUnicode_AsUTF8String(value) 
     895            parser.unicode_source = 1 
     896        if PyString_CheckExact(value) == 0: 
     897            raise TypeError("a string value is expected") 
     898        parser.stream_cache = value 
     899        parser.stream_cache_pos = 0 
     900        parser.stream_cache_len = PyString_GET_SIZE(value) 
     901    if (parser.stream_cache_len - parser.stream_cache_pos) < size: 
     902        size = parser.stream_cache_len - parser.stream_cache_pos 
     903    if size > 0: 
     904        memcpy(buffer, PyString_AS_STRING(parser.stream_cache) 
     905                            + parser.stream_cache_pos, size) 
     906    read[0] = size 
     907    parser.stream_cache_pos += size 
     908    if parser.stream_cache_pos == parser.stream_cache_len: 
     909        parser.stream_cache = None 
    889910    return 1 
    890911 
     
    895916    cdef object stream 
    896917 
    897     cdef yaml_encoding_t use_encoding 
    898918    cdef int document_start_implicit 
    899919    cdef int document_end_implicit 
     
    905925    cdef int last_alias_id 
    906926    cdef int closed 
    907     cdef int decode_output 
     927    cdef int dump_unicode 
     928    cdef object use_encoding 
    908929 
    909930    def __init__(self, stream, canonical=None, indent=None, width=None, 
     
    913934            raise MemoryError 
    914935        self.stream = stream 
    915         self.decode_output = 1 
     936        self.dump_unicode = 0 
    916937        try: 
    917             stream.encoding 
     938            if stream.encoding: 
     939                self.dump_unicode = 1 
    918940        except AttributeError: 
    919             self.decode_output = 0 
     941            pass 
     942        self.use_encoding = encoding 
    920943        yaml_emitter_set_output(&self.emitter, output_handler, <void *>self)     
    921         if canonical is not None: 
     944        if canonical: 
    922945            yaml_emitter_set_canonical(&self.emitter, 1) 
    923946        if indent is not None: 
     
    925948        if width is not None: 
    926949            yaml_emitter_set_width(&self.emitter, width) 
    927         if allow_unicode is not None: 
     950        if allow_unicode: 
    928951            yaml_emitter_set_unicode(&self.emitter, 1) 
    929952        if line_break is not None: 
     
    934957            elif line_break == '\r\n': 
    935958                yaml_emitter_set_break(&self.emitter, YAML_CRLN_BREAK) 
    936         if encoding == 'utf-16-le': 
    937             self.use_encoding = YAML_UTF16LE_ENCODING 
    938         elif encoding == 'utf-16-be': 
    939             self.use_encoding = YAML_UTF16BE_ENCODING 
    940         else: 
    941             self.use_encoding = YAML_UTF8_ENCODING 
    942959        self.document_start_implicit = 1 
    943960        if explicit_start: 
     
    9871004            elif event_object.encoding == 'utf-16-be': 
    9881005                encoding = YAML_UTF16BE_ENCODING 
     1006            if event_object.encoding is None: 
     1007                self.dump_unicode = 1 
     1008            if self.dump_unicode == 1: 
     1009                encoding = YAML_UTF8_ENCODING 
    9891010            yaml_stream_start_event_initialize(event, encoding) 
    9901011        elif event_class is StreamEndEvent: 
     
    11511172    def open(self): 
    11521173        cdef yaml_event_t event 
     1174        cdef yaml_encoding_t encoding 
    11531175        if self.closed == -1: 
    1154             yaml_stream_start_event_initialize(&event, self.use_encoding) 
     1176            if self.use_encoding == 'utf-16-le': 
     1177                encoding = YAML_UTF16LE_ENCODING 
     1178            elif self.use_encoding == 'utf-16-be': 
     1179                encoding = YAML_UTF16BE_ENCODING 
     1180            else: 
     1181                encoding = YAML_UTF8_ENCODING 
     1182            if self.use_encoding is None: 
     1183                self.dump_unicode = 1 
     1184            if self.dump_unicode == 1: 
     1185                encoding = YAML_UTF8_ENCODING 
     1186            yaml_stream_start_event_initialize(&event, encoding) 
    11551187            if yaml_emitter_emit(&self.emitter, &event) == 0: 
    11561188                error = self._emitter_error() 
     
    13741406    cdef CEmitter emitter 
    13751407    emitter = <CEmitter>data 
    1376     if emitter.decode_output == 0: 
     1408    if emitter.dump_unicode == 0: 
    13771409        value = PyString_FromStringAndSize(buffer, size) 
    13781410    else: 
Note: See TracChangeset for help on using the changeset viewer.