*/ REBINT Compare_String_Vals(REBVAL *v1, REBVAL *v2, REBOOL uncase) /* ** Compare two string values. Either can be byte or unicode wide. ** ** Uncase: compare is case-insensitive. ** ** Used for: general string comparions (various places) ** ***********************************************************************/ { REBCNT l1 = VAL_LEN(v1); REBCNT l2 = VAL_LEN(v2); REBCNT len = MIN(l1, l2); REBINT n; if (IS_BINARY(v1) || IS_BINARY(v2)) uncase = FALSE; if (VAL_BYTE_SIZE(v1)) { // v1 is 8 if (VAL_BYTE_SIZE(v2)) n = Compare_Bytes(VAL_BIN_DATA(v1), VAL_BIN_DATA(v2), len, uncase); else n = -Compare_Uni_Byte(VAL_UNI_DATA(v2), VAL_BIN_DATA(v1), len, uncase); } else { // v1 is 16 if (VAL_BYTE_SIZE(v2)) n = Compare_Uni_Byte(VAL_UNI_DATA(v1), VAL_BIN_DATA(v2), len, uncase); else n = Compare_Uni_Str(VAL_UNI_DATA(v1), VAL_UNI_DATA(v2), len, uncase); } if (n != 0) return n; return l1 - l2; }
static void reverse_string(REBVAL *value, REBCNT len) { REBCNT n; REBCNT m; REBUNI c; if (VAL_BYTE_SIZE(value)) { REBYTE *bp = VAL_BIN_DATA(value); for (n = 0, m = len-1; n < len / 2; n++, m--) { c = bp[n]; bp[n] = bp[m]; bp[m] = (REBYTE)c; } } else { REBUNI *up = VAL_UNI_DATA(value); for (n = 0, m = len-1; n < len / 2; n++, m--) { c = up[n]; up[n] = up[m]; up[m] = c; } } }
static int Check_Char_Range(REBVAL *val, REBINT limit) { REBCNT len; if (IS_CHAR(val)) { if (VAL_CHAR(val) > limit) return R_FALSE; return R_TRUE; } if (IS_INTEGER(val)) { if (VAL_INT64(val) > limit) return R_FALSE; return R_TRUE; } len = VAL_LEN(val); if (VAL_BYTE_SIZE(val)) { REBYTE *bp = VAL_BIN_DATA(val); if (limit == 0xff) return R_TRUE; // by definition for (; len > 0; len--, bp++) if (*bp > limit) return R_FALSE; } else { REBUNI *up = VAL_UNI_DATA(val); for (; len > 0; len--, up++) if (*up > limit) return R_FALSE; } return R_TRUE; }
*/ static void replace_with(REBSER *ser, REBCNT index, REBCNT tail, REBVAL *with) /* ** Replace whitespace chars that match WITH string. ** ** Resulting string is always smaller than it was to start. ** ***********************************************************************/ { #define MAX_WITH 32 REBCNT wlen; REBUNI with_chars[MAX_WITH]; // chars to be trimmed REBUNI *up = with_chars; REBYTE *bp; REBCNT n; REBUNI uc; // Setup WITH array from arg or the default: n = 0; if (IS_NONE(with)) { bp = "\n \r\t"; wlen = n = 4; } else if (IS_CHAR(with)) { wlen = 1; *up++ = VAL_CHAR(with); } else if (IS_INTEGER(with)) { wlen = 1; *up++ = Int32s(with, 0); } else if (ANY_BINSTR(with)) { n = VAL_LEN(with); if (n >= MAX_WITH) n = MAX_WITH-1; wlen = n; if (VAL_BYTE_SIZE(with)) { bp = VAL_BIN_DATA(with); } else { memcpy(up, VAL_UNI_DATA(with), n * sizeof(REBUNI)); n = 0; } } for (; n > 0; n--) *up++ = (REBUNI)*bp++; // Remove all occurances of chars found in WITH string: for (n = index; index < tail; index++) { uc = GET_ANY_CHAR(ser, index); if (!find_in_uni(with_chars, wlen, uc)) { SET_ANY_CHAR(ser, n, uc); n++; } } SET_ANY_CHAR(ser, n, 0); SERIES_TAIL(ser) = n; }
*/ REBSER *Encode_UTF8_Value(REBVAL *arg, REBCNT len, REBFLG opts) /* ** Do all the details to encode a string as UTF8. ** No_copy means do not make a copy. ** Result can be a shared buffer! ** ***********************************************************************/ { REBSER * ser; if (VAL_BYTE_SIZE(arg)) { ser = Encode_UTF8_String(VAL_BIN_DATA(arg), len, FALSE, opts); } else { ser = Encode_UTF8_String(VAL_UNI_DATA(arg), len, TRUE, opts); } return ser; }