~cjwatson/meliae/py3-declare-support

« back to all changes in this revision

Viewing changes to meliae/_scanner_core.c

  • Committer: John Arbash Meinel
  • Date: 2020-02-03 04:37:50 UTC
  • mfrom: (213.1.1 py3-dump-unicode)
  • Revision ID: john@arbash-meinel.com-20200203043750-foyn45qmxsr4s229
Better Unicode handling on Python 3

Show diffs side-by-side

added added

removed removed

Lines of Context:
410
410
{
411
411
    // TODO: consider writing to a small memory buffer, before writing to disk
412
412
    Py_ssize_t uni_size;
 
413
    Py_ssize_t i;
 
414
    char out_buf[1024] = {0}, *ptr, *end;
 
415
#if PY_VERSION_HEX >= 0x03030000
 
416
    int uni_kind;
 
417
    void *uni_data;
 
418
    Py_UCS4 c;
 
419
#else
413
420
    Py_UNICODE *uni_buf, c;
414
 
    Py_ssize_t i;
415
 
    char out_buf[1024] = {0}, *ptr, *end;
 
421
#endif
416
422
 
 
423
#if PY_VERSION_HEX >= 0x03030000
 
424
    if (PyUnicode_READY(c_obj) == -1) {
 
425
        /* This function has no good way to signal errors.  For now, writing
 
426
         * JSON null will have to do.
 
427
         */
 
428
        info->write(info->data, "null", 4);
 
429
        PyErr_Clear();
 
430
        return;
 
431
    }
 
432
    uni_kind = PyUnicode_KIND(c_obj);
 
433
    uni_data = PyUnicode_DATA(c_obj);
 
434
    uni_size = PyUnicode_GET_LENGTH(c_obj);
 
435
#else
417
436
    uni_buf = PyUnicode_AS_UNICODE(c_obj);
418
437
    uni_size = PyUnicode_GET_SIZE(c_obj);
 
438
#endif
419
439
 
420
440
    // Never try to dump more than this many chars
421
441
    if (uni_size > 100) {
425
445
    end = out_buf + 1024;
426
446
    *ptr++ = '"';
427
447
    for (i = 0; i < uni_size; ++i) {
 
448
#if PY_VERSION_HEX >= 0x03030000
 
449
        c = PyUnicode_READ(uni_kind, uni_data, i);
 
450
#else
428
451
        c = uni_buf[i];
 
452
#endif
429
453
        if (c <= 0x1f || c > 0x7e) {
430
454
            if (c > 0xFFFF) {
431
455
                // Use surrogate pair.
535
559
        _write_static_to_info(info, ", \"value\": ");
536
560
        _dump_string(info, c_obj);
537
561
    } else if (PyUnicode_Check(c_obj)) {
538
 
        _write_to_ref_info(info, ", \"len\": " SSIZET_FMT, PyUnicode_GET_SIZE(c_obj));
 
562
        Py_ssize_t len;
 
563
#if PY_VERSION_HEX >= 0x03030000
 
564
        len = PyUnicode_GET_LENGTH(c_obj);
 
565
#else
 
566
        len = PyUnicode_GET_SIZE(c_obj);
 
567
#endif
 
568
        _write_to_ref_info(info, ", \"len\": " SSIZET_FMT, len);
539
569
        _write_static_to_info(info, ", \"value\": ");
540
570
        _dump_unicode(info, c_obj);
541
571
    } else if (PyBool_Check(c_obj)) {