单源单路径代码集无关版本
术语单源单路径是指在一个应用程序中,只使用一条路径来同时处理单字节和多字节代码集。 单源单路径方法消除了用于全球化的全部 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);
}