📄 gbx_c_string.c
字号:
/*************************************************************************** gbx_c_string.c (c) 2000-2004 Beno顃 Minisini <gambas@users.sourceforge.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __GBX_C_STRING_C#include <wctype.h>#include <iconv.h>#include "gb_common.h"#include "gb_error.h"#include "gbx_string.h"#include "gbx_api.h"#include "gbx_exec.h"#include "gambas.h"#include "gbx_c_string.h"static const char *_str;static long _len;static long _pos;static long _clen;static int get_char_length(const char *s){ int n = 1; unsigned char c = *((unsigned char *)s); if (c & 0x80) { for (;;) { c <<= 1; if (!(c & 0x80)) break; n++; } } return n;}static void init_conv(char *str, long len){ _str = str; _len = len; _pos = 0; _clen = -1;}static long get_next_pos(void){ if (_pos >= _len) return 0; _pos += get_char_length(&_str[_pos]); return _pos;}BEGIN_METHOD(string_pos, GB_STRING str; GB_INTEGER index) int i; if (VARG(index) <= 0) { GB_ReturnInteger(0); return; } init_conv(STRING(str), LENGTH(str)); for (i = 1; i < VARG(index); i++) get_next_pos(); GB_ReturnInteger(_pos + 1); END_METHODstatic long get_length(void){ long len; long i; if (_clen >= 0) return _clen; len = 0; for (i = 0; i < _len; i++) { if ((_str[i] & 0xC0) != 0x80) len++; } _clen = len; return len; }BEGIN_METHOD(string_len, GB_STRING str) init_conv(STRING(str), LENGTH(str)); GB_ReturnInteger(get_length()); END_METHODBEGIN_METHOD(string_index, GB_STRING str; GB_INTEGER pos) int pos = VARG(pos); if (pos < 1) { GB_ReturnInteger(0); return; } if (pos > LENGTH(str)) pos = LENGTH(str); init_conv(STRING(str), pos); GB_ReturnInteger(get_length());END_METHODstatic void get_substring(long start, long len){ long i; long pos; if (len < 0) len += get_length(); if (len <= 0) { GB_ReturnNull(); return; } for (i = 0; i < start; i++) { if (get_next_pos() <= 0) { GB_ReturnNull(); return; } } pos = _pos; for (i = 0; i < len; i++) { if (get_next_pos() <= 0) break; } GB_ReturnNewString(_str + pos, _pos - pos);}BEGIN_METHOD(string_mid, GB_STRING str; GB_INTEGER start; GB_INTEGER len) long start = VARG(start); long len = VARGOPT(len, LENGTH(str)); if (start < 0) { GB_Error((char *)E_ARG); return; } init_conv(STRING(str), LENGTH(str)); get_substring(start - 1, len);END_METHODBEGIN_METHOD(string_left, GB_STRING str; GB_INTEGER len) long len = VARGOPT(len, 1); init_conv(STRING(str), LENGTH(str)); get_substring(0, len);END_METHODBEGIN_METHOD(string_right, GB_STRING str; GB_INTEGER len) long len = VARGOPT(len, 1); init_conv(STRING(str), LENGTH(str)); if (len < 0) get_substring((-len), LENGTH(str)); else get_substring(get_length() - len, len);END_METHODstatic void convert_string(char *str, long len, bool upper){ char *charset; char *temp = NULL; int i, l; wchar_t *wtemp; if (len > 0) { charset = EXEC_big_endian ? "UCS-4BE" : "UCS-4LE"; STRING_conv(&temp, str, len, "UTF-8", charset); l = STRING_length(temp) / sizeof(wchar_t); wtemp = (wchar_t *)temp; if (upper) { for (i = 0; i < l; i++) wtemp[i] = towupper(wtemp[i]); } else { for (i = 0; i < l; i++) wtemp[i] = towlower(wtemp[i]); } STRING_conv(&temp, temp, l * sizeof(wchar_t), charset, "UTF-8"); } GB_ReturnString(temp);}BEGIN_METHOD(string_lower, GB_STRING str) convert_string(STRING(str), LENGTH(str), FALSE);END_METHODBEGIN_METHOD(string_upper, GB_STRING str) convert_string(STRING(str), LENGTH(str), TRUE);END_METHODPUBLIC GB_DESC NATIVE_String[] ={ GB_DECLARE("String", 0), GB_VIRTUAL_CLASS(), GB_STATIC_METHOD("Len", "i", string_len, "(String)s"), GB_STATIC_METHOD("Mid", "s", string_mid, "(String)s(Start)i[(Length)i]"), GB_STATIC_METHOD("Mid$", "s", string_mid, "(String)s(Start)i[(Length)i]"), GB_STATIC_METHOD("Left", "s", string_left, "(String)s[(Length)i]"), GB_STATIC_METHOD("Left$", "s", string_left, "(String)s[(Length)i]"), GB_STATIC_METHOD("Right", "s", string_right, "(String)s[(Length)i]"), GB_STATIC_METHOD("Right$", "s", string_right, "(String)s[(Length)i]"), GB_STATIC_METHOD("Upper", "s", string_upper, "(String)s"), GB_STATIC_METHOD("Upper$", "s", string_upper, "(String)s"), GB_STATIC_METHOD("UCase", "s", string_upper, "(String)s"), GB_STATIC_METHOD("UCase$", "s", string_upper, "(String)s"), GB_STATIC_METHOD("Lower", "s", string_lower, "(String)s"), GB_STATIC_METHOD("Lower$", "s", string_lower, "(String)s"), GB_STATIC_METHOD("LCase", "s", string_lower, "(String)s"), GB_STATIC_METHOD("LCase$", "s", string_lower, "(String)s"), /*GB_STATIC_METHOD("Comp", "i", string_comp, "(String)s(String2)s[(Mode)i]"),*/ GB_STATIC_METHOD("Pos", "i", string_pos, "(String)s(Index)i"), GB_STATIC_METHOD("Index", "i", string_index, "(String)s(Pos)i"), /*GB_STATIC_METHOD("Chr", "s", string_chr, "(Unicode)i"), GB_STATIC_METHOD("Chr$", "s", string_chr, "(Unicode)i"), GB_STATIC_METHOD("Code", "i", string_code, "(String)s[(Pos)i]"),*/ GB_END_DECLARE};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -