コード例 #1
0
ファイル: pg_chardetect.c プロジェクト: aweber/pg_chardetect
Datum
convert_to_UTF8(PG_FUNCTION_ARGS)
{
    // things we need to deal with constructing our composite type
    TupleDesc   tupdesc;
    Datum       values[3];
    bool        nulls[3];
    HeapTuple   tuple;

    // for char_set_detect function returns
    text    *encoding = NULL;
    text    *lang = NULL;
    int32_t confidence = 0;

    UErrorCode status = U_ZERO_ERROR;

    // output buffer for conversion to Unicode
    UChar* uBuf = NULL;
    int32_t uBuf_len = 0;

    // output of this function
    text *text_out;
    bool converted = false;
    bool dropped_bytes = false;
    bool dropped_bytes_toU = false;
    bool dropped_bytes_fromU = false;

    // temporary buffer for converted string
    char* converted_buf = NULL;

    // input args
    const text  *buffer = PG_GETARG_TEXT_P(0);
    const bool  force   = PG_GETARG_BOOL(1);

    // C string of text* buffer
    const char* cbuffer = NULL;
    int cbuffer_len = 0;

    // Convert output values into a PostgreSQL composite type.
    if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
        ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
              errmsg("function returning record called in context "
                     "that cannot accept type record.\n")));

    // BlessTupleDesc for Datums
    BlessTupleDesc(tupdesc);

    // return if string to convert is NULL
    if (NULL == buffer)
    {
        // return input string,
        // converted to true,
        // dropped_bytes to false
        text_out = (text *) buffer;
        converted = true;
        dropped_bytes = false;
    }
    else
    {
        // extract string from text* to C string
        cbuffer = text_to_cstring(buffer);
        cbuffer_len = strlen(cbuffer);

        // bail on zero-length strings
        // return if cbuffer has zero length or contains a blank space
        if ((0 == cbuffer_len) || (0 == strcmp("", cbuffer)))
        {
            text_out = (text *) buffer;
            converted = true;
            dropped_bytes = false;
        }
        else
        {
            // UTF8 output can be up to 6 bytes per input byte
            // palloc0 allocates and zeros bytes in array
            int32_t converted_buf_len = cbuffer_len * 6 * sizeof(char);
            converted_buf = (char *) palloc0(converted_buf_len);
            // int32_t converted_len = 0;

            // detect encoding with ICU
            status = detect_ICU(buffer, &encoding, &lang, &confidence);

            ereport(DEBUG1,
                (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
                 errmsg("ICU detection status: %d\n", status)));

            ereport(DEBUG1,
                (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
                 errmsg("Detected encoding: %s, language: %s, confidence: %d\n",
                 text_to_cstring(encoding),
                 text_to_cstring(lang),
                         confidence)));

            // return without attempting a conversion if UTF8 is detected
            if (
                (0 == strcmp("UTF-8", text_to_cstring(encoding))) ||
                (0 == strcmp("utf-8", text_to_cstring(encoding))) ||
                (0 == strcmp("UTF8", text_to_cstring(encoding)))  ||
                (0 == strcmp("utf8", text_to_cstring(encoding)))
               )
            {
                ereport(DEBUG1,
                    (errcode(ERRCODE_SUCCESSFUL_COMPLETION),
                     errmsg("ICU detected %s.  No conversion necessary.\n", text_to_cstring(encoding))));

                text_out = (text *) buffer;
                converted = true;
                dropped_bytes = false;
            }
            else
            {
                // ICU uses UTF16 internally, so need to convert to Unicode first
                // then convert to UTF8

                if (U_SUCCESS(status))
                    status = convert_to_unicode(buffer, (const text*) encoding, &uBuf, (int32_t*) &uBuf_len, force, &dropped_bytes_toU);

                if (U_SUCCESS(status))
                    status = convert_to_utf8((const UChar*) uBuf, uBuf_len, &converted_buf, (int32_t*) &converted_buf_len, force, &dropped_bytes_fromU);

                if (U_SUCCESS(status))
                {
                    text_out = cstring_to_text(converted_buf);
                    converted = true;
                    dropped_bytes = (dropped_bytes_toU || dropped_bytes_fromU);
                }
                else
                {
                    ereport(WARNING,
                        (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
                            errmsg("ICU conversion failed - returning original input")));

                    text_out = (text *) buffer;
                    converted = false;
                    dropped_bytes = false;
                }
            } // already UTF8
        } // zero-length string
    }  // return if buffer is NULL

    values[0] = PointerGetDatum(text_out);
    values[1] = BoolGetDatum(converted);
    values[2] = BoolGetDatum(dropped_bytes);

    // check if pointers are still NULL; if so Datum is NULL and
    // confidence is meaningless (also NULL)
    (text_out  == NULL || ! VARSIZE_ANY_EXHDR(text_out)) ? (nulls[0] = true) : (nulls[0] = false);
    // converted will never be NULL
    nulls[1] = false;
    nulls[2] = false;

    // build tuple from datum array
    tuple = heap_form_tuple(tupdesc, values, nulls);

    // cleanup
    if (NULL != encoding)
        pfree((void *) encoding);

    if (NULL != lang)
        pfree((void *) lang);

    if (NULL != cbuffer)
        pfree((void *) cbuffer);

    if (NULL != converted_buf)
        pfree((void *) converted_buf);

    PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
}
コード例 #2
0
ファイル: sendmail.c プロジェクト: AlexSteel/wine
/**************************************************************************
 *  MAPISendMail	(MAPI32.211)
 *
 * Send a mail.
 *
 * PARAMS
 *  session  [I] Handle to a MAPI session.
 *  uiparam  [I] Parent window handle.
 *  message  [I] Pointer to a MAPIMessage structure.
 *  flags    [I] Flags.
 *  reserved [I] Reserved, pass 0.
 *
 * RETURNS
 *  Success: SUCCESS_SUCCESS
 *  Failure: MAPI_E_FAILURE
 *
 */
ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam,
    lpMapiMessage message, FLAGS flags, ULONG reserved )
{
    WCHAR msg_title[READ_BUF_SIZE], error_msg[READ_BUF_SIZE];

    /* Check to see if we have a Simple MAPI provider loaded */
    if (mapiFunctions.MAPISendMail)
        return mapiFunctions.MAPISendMail(session, uiparam, message, flags, reserved);

    /* Check if we have an Extended MAPI provider - if so, use our wrapper */
    if (MAPIInitialize(NULL) == S_OK)
    {
        MapiMessageW messageW;
        ULONG ret;

        ZeroMemory(&messageW, sizeof(MapiMessageW));

        /* Convert the entries we need to Unicode */
        messageW.lpszSubject = convert_to_unicode(message->lpszSubject);
        messageW.lpszNoteText = convert_to_unicode(message->lpszNoteText);
        messageW.nFileCount = message->nFileCount;

        if (message->nFileCount && message->lpFiles)
        {
            lpMapiFileDescW filesW;
            unsigned int i;

            filesW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MapiFileDescW) * message->nFileCount);

            for (i = 0; i < message->nFileCount; i++)
            {
                filesW[i].lpszPathName = convert_to_unicode(message->lpFiles[i].lpszPathName);
                filesW[i].lpszFileName = convert_to_unicode(message->lpFiles[i].lpszFileName);
            }

            messageW.lpFiles = filesW;
        }

        ret = sendmail_extended_mapi(session, uiparam, &messageW, flags);

        /* Now free everything we allocated */
        if (message->nFileCount && message->lpFiles)
        {
            unsigned int i;

            for (i = 0; i < message->nFileCount; i++)
            {
                HeapFree(GetProcessHeap(), 0, messageW.lpFiles[i].lpszPathName);
                HeapFree(GetProcessHeap(), 0, messageW.lpFiles[i].lpszFileName);
            }

            HeapFree(GetProcessHeap(), 0, messageW.lpFiles);
        }

        HeapFree(GetProcessHeap(), 0, messageW.lpszSubject);
        HeapFree(GetProcessHeap(), 0, messageW.lpszNoteText);

        return ret;
    }

    /* Display an error message since we apparently have no mail clients */
    LoadStringW(hInstMAPI32, IDS_NO_MAPI_CLIENT, error_msg, sizeof(error_msg) / sizeof(WCHAR));
    LoadStringW(hInstMAPI32, IDS_SEND_MAIL, msg_title, sizeof(msg_title) / sizeof(WCHAR));

    MessageBoxW((HWND) uiparam, error_msg, msg_title, MB_ICONEXCLAMATION);

    return MAPI_E_NOT_SUPPORTED;
}