static _Nt_array_ptr process_string()

in parson.c [697:756]


static _Nt_array_ptr<char> process_string(_Nt_array_ptr<const char> input : count(len), size_t len) {
    _Nt_array_ptr<const char> input_ptr : bounds(input, input + len) = input;
    size_t initial_size = (len + 1) * sizeof(char);
    size_t final_size = 0;
    _Nt_array_ptr<char> output : count(initial_size) = NULL;
    output = parson_string_malloc(initial_size);
    _Nt_array_ptr<char> output_ptr : bounds(output, output + initial_size) = NULL;
    if (output == NULL) {
        goto error;
    }
    output_ptr = output;
    while ((*input_ptr != '\0') && (size_t)(input_ptr - input) < len) {
        if (*input_ptr == '\\') {
            input_ptr++;
            switch (*input_ptr) {
                case '\"': *output_ptr = '\"'; break;
                case '\\': *output_ptr = '\\'; break;
                case '/':  *output_ptr = '/';  break;
                case 'b':  *output_ptr = '\b'; break;
                case 'f':  *output_ptr = '\f'; break;
                case 'n':  *output_ptr = '\n'; break;
                case 'r':  *output_ptr = '\r'; break;
                case 't':  *output_ptr = '\t'; break;
                case 'u': /*HACK for C3*/
                    _Unchecked {
                        const char *input_tmp = (const char *) input_ptr;
                        char *output_tmp = (char *) output_ptr;
                        if (parse_utf16(&input_tmp, &output_tmp) == JSONFailure) {
                            goto error;
                        }
                        input_ptr = _Assume_bounds_cast<_Nt_array_ptr<const char>>(input_tmp, bounds(input, input + len));
                        output_ptr = _Assume_bounds_cast<_Nt_array_ptr<char>>(output_tmp, bounds(output, output + initial_size));
                        break;
                    }
                default:
                    goto error;
            }
        } else if ((unsigned char)*input_ptr < 0x20) {
            goto error; /* 0x00-0x19 are invalid characters for json string (http://www.ietf.org/rfc/rfc4627.txt) */
        } else {
            *output_ptr = *input_ptr;
        }
        output_ptr++;
        input_ptr++;
    }
    *output_ptr = '\0';
    /* resize to new length */
    final_size = (size_t)(output_ptr-output) + 1;
    /* todo: don't resize if final_size == initial_size */
    _Nt_array_ptr<char> resized_output : count(final_size) = parson_string_malloc(final_size);
    if (resized_output == NULL) {
        goto error;
    }
    memcpy<char>(resized_output, _Dynamic_bounds_cast<_Nt_array_ptr<char>>(output, count(final_size)), final_size);
    parson_free(char, output);
    return resized_output;
error:
    parson_free(char, output);
    return NULL;
}