示例#1
0
/*
 *   Get the Unicode character code of the first character of a string 
 */
void CVmBifT3Test::get_charcode(VMG_ uint argc)
{
    const char *str;

    /* one argument required */
    check_argc(vmg_ argc, 1);

    /* get the object ID as an integer */
    str = pop_str_val(vmg0_);

    /* 
     *   if the string is empty, return nil; otherwise, return the Unicode
     *   character code of the first character 
     */
    if (vmb_get_len(str) == 0)
    {
        /* empty string - return nil */
        retval_nil(vmg0_);
    }
    else
    {
        /* 
         *   get the character code of the first character and return it
         *   as an integer 
         */
        retval_int(vmg_ (int)utf8_ptr::s_getch(str + VMB_LEN));
    }
}
示例#2
0
/*
 *   displayText(str) - display a text string.
 */
void CVmBifSample::display_text(VMG_ uint argc)
{
    const char *strp;
    size_t len;

    /*
     *   Check to make sure we have the right number of arguments.  'argc'
     *   tells us how many arguments we received from the T3 program.
     */
    check_argc(vmg_ argc, 1);

    /*
     *   Get the first argument, which is the string to display.
     *
     *   This will give us a pointer to a string in internal format, which
     *   has a two-byte length prefix.  So, once we have the string, we must
     *   get the length from the string pointer, and then skip the length
     *   prefix to get to the real text of the string.
     *
     *   Arguments from the T3 program to a native function always appear on
     *   the VM stack, which we can access using the pop_xxx_val() functions.
     *   The arguments appear on the stack in order such that the first
     *   pop_xxx_val() gives us the first argument, the second pop_xxx_val()
     *   gives us the second argument, and so on.  The pop_xxx_val()
     *   functions REMOVE an argument from the stack - once it's removed, we
     *   can get to the next one.  We MUST remove EXACTLY the number of
     *   arguments that we receive before we return.
     */
    strp = pop_str_val(vmg0_);
    len = vmb_get_len(strp);
    strp += VMB_LEN;

    /*
     *   Okay, we have our string, but it's in UTF-8 format, which is an
     *   encoding format for Unicode.  We don't want to display Unicode; we
     *   want to display the local character set.  How do we do this?
     *   Fortunately, T3 provides a handy character mapping subsystem that
     *   will let us convert the string fairly automatically.  The VM also
     *   gives us a pre-loaded mapper for this specific kind of conversion,
     *   in the object G_cmap_to_ui.  G_cmap_to_ui will map characters from
     *   UTF-8 to the local User Interface character set.
     *
     *   To avoid the need to allocate a gigantic string buffer to convert
     *   the characters, the mapper lets us map in chunks of any size.  So,
     *   we'll simply map and display chunks until we run out of string.
     */
    while (len != 0)
    {
        char buf[128];
        size_t cur_out;
        size_t cur_in;

        /*
         *   Map as much as we can into our buffer.  This will set cur_out to
         *   the number of bytes in the local character set (the output of
         *   the conversion), and will set cur_in to the number of bytes we
         *   used from the Unicode string (the input).
         */
        cur_out = G_cmap_to_ui->map_utf8(buf, sizeof(buf),
                                         strp, len, &cur_in);

        /*
         *   Show the local characters.
         *
         *   "%.*s" is just like "%s", but the ".*" tells printf to show
         *   exactly the number of characters in the int argument before the
         *   string, instead of showing everything until it finds a null byte
         *   in the string.  This is important because map_utf8 does NOT
         *   null-terminate the result.
         */
        printf("%.*s", (int)cur_out, buf);

        /*
         *   skip the characters of input we just translated, so that on the
         *   next iteration of this loop we'll translate the next bunch of
         *   characters
         */
        strp += cur_in;
        len -= cur_in;
    }
}