讓我們假設有一段這樣的代碼:如何處理由字符的字符串字符的XS碼
my $str = 'some text';
my $result = my_subroutine($str);
和my_subroutine()
應該像Perl XS代碼來實現。例如,它可以返回(unicode)字符串的字節總和。
在XS碼,如何處理一個字符串的(a)炭由炭,作爲一般的方法,和(b)中逐字節,如果字符串是由ASCII碼的子集(一個內置-in函數將字符串的本機數據結構轉換爲char [])?
讓我們假設有一段這樣的代碼:如何處理由字符的字符串字符的XS碼
my $str = 'some text';
my $result = my_subroutine($str);
和my_subroutine()
應該像Perl XS代碼來實現。例如,它可以返回(unicode)字符串的字節總和。
在XS碼,如何處理一個字符串的(a)炭由炭,作爲一般的方法,和(b)中逐字節,如果字符串是由ASCII碼的子集(一個內置-in函數將字符串的本機數據結構轉換爲char [])?
在XS層,您將獲得字節或UTF-8字符串。在一般情況下,您的代碼可能會包含一個char *
以指向字符串中的下一個項目,隨着它的增加而遞增。對於一組有用的UTF-8支持功能在XS使用,從http://cpansearch.perl.org/src/PEVANS/Tickit-0.15/lib/Tickit/Utils.xs
int textwidth(str)
SV *str
INIT:
STRLEN len;
const char *s, *e;
CODE:
RETVAL = 0;
if(!SvUTF8(str)) {
str = sv_mortalcopy(str);
sv_utf8_upgrade(str);
}
s = SvPV_const(str, len);
e = s + len;
while(s < e) {
UV ord = utf8n_to_uvchr(s, e-s, &len, (UTF8_DISALLOW_SURROGATE
|UTF8_WARN_SURROGATE
|UTF8_DISALLOW_FE_FF
|UTF8_WARN_FE_FF
|UTF8_WARN_NONCHAR));
int width = wcwidth(ord);
if(width == -1)
XSRETURN_UNDEF;
s += len;
RETVAL += width;
}
OUTPUT:
RETVAL
簡言之讀取的perlapi
礦的一個例子的"Unicode Support"部,該函數迭代給定的字符串一次一個Unicode字符,累積寬度如wcwidth()
所示。
如果您期望字節:
STRLEN len;
char* buf = SvPVbyte(sv, len);
while (len--) {
char byte = *(buf++);
... do something with byte ...
}
如果您期望文本或任何非字節字符:
STRLEN len;
U8* buf = SvPVutf8(sv, len);
while (len) {
STRLEN ch_len;
UV ch = utf8n_to_uvchr(buf, len, &ch_len, 0);
buf += ch_len;
len -= ch_len;
... do something with ch ...
}
有用的筆記,謝謝。但我仍然希望至少有一個基本的子程序框架(不是特別針對你)。我會等一段時間,如果沒有更好的表現,我會接受這個答案。 – ArtM
好的。我會從我的代碼中挖出一些,併發布另一個答案,然後...... – LeoNerd