单源单路径代码集无关版本

术语单源单路径是指在一个应用程序中,只使用一条路径来同时处理单字节和多字节代码集。 单源单路径方法消除了用于全球化的全部 ifdef。 所有字符都以相同的方式处理,考虑它属于单字节代码集还是属于多字节代码集。

单源单路径是理想的,但会降低性能。 因此,并不推荐对所有的程序都采用此方法。 可能有些程序在全面全球化时并未遭受性能的降低;在这样的情况下,请使用单源单路径方法。

下面的 my_example 实用程序全面全球化版本通过单源单路径、代码集无关的编程,支持全部代码集:

/*
 * COMPONENT_NAME:
 *
 * FUNCTIONS: my_example
 *
 * The following code shows how to count the number of bytes and
 * the number of characters in a text file.
 *
 * This example is for illustration purposes only. Performance
 * improvements may still be possible.
 *
 */

#include        <stdio.h>
#include        <ctype.h>
#include        <locale.h>
#include        <stdlib.h>
#include        "my_example_msg.h"

#define MSGSTR(Num,Str) catgets(catd,MS_MY_EXAMPLE,Num,Str)

/*
 * NAME: my_example
 *
 * FUNCTION: Counts the number of characters in a file.
 *
 */  

main(argc,argv)
int argc;
char **argv;
{
    int     bytesread,   /* number of bytes read */
        bytesprocessed;
    int     leftover;

   int     i;
    int     mbcnt;           /* number of bytes in a character */
    int     f;               /* File descriptor */
    int mb_cur_max;
    int    bytect;           /* name changed from charct... */
    int    charct;           /* for real character count */
    char   *curp, *cure;     /* current and end pointers into
                               ** buffer */
    char         buf[BUFSIZ+1];

    nl_catd      catd;

    wchar_t    wc;

    /* Obtain the current locale */
    (void) setlocale(LC_ALL,"");

    /* after setting the locale, open the message catalog */
    catd = catopen(MF_MY_EXAMPLE,NL_CAT_LOCALE);

    /* Parse the arguments if any */

    /*
    ** Obtain  the maximum number of bytes in a character in the
    ** current locale.
    */
    mb_cur_max = MB_CUR_MAX;
    i = 1;

    /* Open the specified file and issue error messages if any */
    f = open(argv[i],0);
    if(f<0){
        fprintf(stderr,MSGSTR(CANTOPEN,              /*MSG*/
            "my_example: cannot open %s\n"), argv[i]);      /*MSG*/
            exit(2);
    }

   /* Initialize the variables for the count */
    bytect = 0;
    charct = 0;

    /* Start count of bytes and characters  */

    leftover = 0;

    for(;;) {
        bytesread = read(f,buf+leftover, BUFSIZ-leftover);
        /* issue any error messages here, if needed */
        if(bytesread <= 0)
             break;

        buf[leftover+bytesread] = '\0';
                /* Protect partial reads */
        bytect += bytesread;
        curp=buf;
        cure = buf + bytesread+leftover;
        leftover=0;      /* No more leftover */

        for(; curp<cure ;){
            /* Convert to wide character */
            mbcnt= mbtowc(&wc, curp, mb_cur_max);
            if(mbcnt <= 0){
                mbcnt = 1;
            }else if (cure - curp >=mb_cur_max){
                wc = *curp;
                mbcnt =1;
            }else{
                /* Needs more data */
                leftover= cure - curp;
                strcpy(buf, curp, leftover);
                break;
            }
            curp +=mbcnt;
            charct++;
        }
    }

        /* print number of chars and bytes */
    fprintf(stderr,MSGSTR(BYTECNT, "number of bytes:%d\n"),
            bytect);
    fprintf(stderr,MSGSTR(CHARCNT, "number of characters:%d\n"),
            charct);
    close(f);
    exit(0);
}