Пример #1
0
/* Convert a string from the current locale's character set to UTF-8.
 * Unfortunately, "current locale" can mean a few different things on
 * Windows -- we use the default ANSI code page, which does the right
 * thing for command-line arguments (like "-sPDFPassword=foo") and
 * for strings typed as input to gswin32.exe.  It doesn't work for
 * strings typed as input to gswin32c.exe, which are normally in the
 * default OEM code page instead.
 * <string> .locale_to_utf8 <string> */
static int
zlocale_to_utf8(i_ctx_t *i_ctx_p)
{
#define LOCALE_TO_UTF8_BUFFER_SIZE 1024
    os_ptr op = osp;
    char *input;
    WCHAR wide_buffer[LOCALE_TO_UTF8_BUFFER_SIZE];
    char utf8_buffer[LOCALE_TO_UTF8_BUFFER_SIZE];
    int success;
    int code;

    check_read_type(*op, t_string);
    input = ref_to_string(op, imemory, "locale_to_utf8 input");
    if (input == 0)
        return_error(gs_error_VMerror);

    success = MultiByteToWideChar(CP_ACP, 0, input, -1,
        wide_buffer, LOCALE_TO_UTF8_BUFFER_SIZE);
    ifree_string((byte *)input, r_size(op) + 1, "locale_to_utf8 input");
    if (success == 0)
        return_error(gs_error_ioerror);

    success = WideCharToMultiByte(CP_UTF8, 0, wide_buffer, -1,
        utf8_buffer, LOCALE_TO_UTF8_BUFFER_SIZE, NULL, NULL);
    if (success == 0)
        return_error(gs_error_ioerror);

    code = string_to_ref(utf8_buffer, op, iimemory, "locale_to_utf8 output");
    if (code < 0)
        return code;

    return 0;
#undef LOCALE_TO_UTF8_BUFFER_SIZE
}
Пример #2
0
/* <int> .oserrorstring false */
static int
zoserrorstring(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    const char *str;
    int code;
    uint len;
    byte ch;

    check_type(*op, t_integer);
    str = gp_strerror((int)op->value.intval);
    if (str == 0 || (len = strlen(str)) == 0) {
        make_false(op);
        return 0;
    }
    check_ostack(1);
    code = string_to_ref(str, op, iimemory, ".oserrorstring");
    if (code < 0)
        return code;
    /* Strip trailing end-of-line characters. */
    while ((len = r_size(op)) != 0 &&
           ((ch = op->value.bytes[--len]) == '\r' || ch == '\n')
        )
        r_dec_size(op, 1);
    push(1);
    make_true(op);
    return 0;
}
Пример #3
0
/* Convert a string from the current locale's character set to UTF-8.
 * <string> .locale_to_utf8 <string> */
static int
zlocale_to_utf8(i_ctx_t *i_ctx_p)
{
    os_ptr op = osp;
    char *input;
    char *output;
    int code;

    check_read_type(*op, t_string);
    input = ref_to_string(op, imemory, "locale_to_utf8 input");
    if (input == 0)
        return_error(gs_error_VMerror);

    output = stringprep_locale_to_utf8(input);
    ifree_string((byte *)input, r_size(op) + 1, "locale_to_utf8 input");
    if (output == 0) {
        /* This function is intended to be used on strings whose
         * character set is unknown, so it's not an error if the
         * input contains invalid characters.  Just return the input
         * string unchanged.
         *
         * Sadly, EINVAL from stringprep_locale_to_utf8 can mean
         * either an invalid character set conversion (which we care
         * about), or an incomplete input string (which we don't).
         * For now, we ignore EINVAL; the right solution is probably
         * to not use stringprep_locale_to_utf8, and just call iconv
         * by hand. */
        if (errno == EILSEQ || errno == EINVAL)
            return 0;

        /* Other errors (like ENFILE) are real errors, which we
         * want to return to the user. */
        return_error(gs_error_ioerror);
    }

    code = string_to_ref(output, op, iimemory, "locale_to_utf8 output");
    free(output);
    if (code < 0)
        return code;

    return 0;
}