static void swap_chars(REBVAL *val1, REBVAL *val2) { REBUNI c1; REBUNI c2; REBSER *s1 = VAL_SERIES(val1); REBSER *s2 = VAL_SERIES(val2); c1 = GET_ANY_CHAR(s1, VAL_INDEX(val1)); c2 = GET_ANY_CHAR(s2, VAL_INDEX(val2)); if (BYTE_SIZE(s1) && c2 > 0xff) Widen_String(s1); SET_ANY_CHAR(s1, VAL_INDEX(val1), c2); if (BYTE_SIZE(s2) && c1 > 0xff) Widen_String(s2); SET_ANY_CHAR(s2, VAL_INDEX(val2), c1); }
*/ REBINT PD_String(REBPVS *pvs) /* ***********************************************************************/ { REBVAL *data = pvs->value; REBVAL *val = pvs->setval; REBINT n = 0; REBCNT i; REBINT c; REBSER *ser = VAL_SERIES(data); if (IS_INTEGER(pvs->select)) { n = Int32(pvs->select) + VAL_INDEX(data) - 1; } else return PE_BAD_SELECT; if (val == 0) { if (n < 0 || (REBCNT)n >= SERIES_TAIL(ser)) return PE_NONE; if (IS_BINARY(data)) { SET_INTEGER(pvs->store, *BIN_SKIP(ser, n)); } else { SET_CHAR(pvs->store, GET_ANY_CHAR(ser, n)); } return PE_USE; } if (n < 0 || (REBCNT)n >= SERIES_TAIL(ser)) return PE_BAD_RANGE; if (IS_CHAR(val)) { c = VAL_CHAR(val); if (c > MAX_CHAR) return PE_BAD_SET; } else if (IS_INTEGER(val)) { c = Int32(val); if (c > MAX_CHAR || c < 0) return PE_BAD_SET; if (IS_BINARY(data)) { // special case for binary if (c > 0xff) Trap_Range(val); BIN_HEAD(ser)[n] = (REBYTE)c; return PE_OK; } } else if (ANY_BINSTR(val)) { i = VAL_INDEX(val); if (i >= VAL_TAIL(val)) return PE_BAD_SET; c = GET_ANY_CHAR(VAL_SERIES(val), i); } else return PE_BAD_SELECT; TRAP_PROTECT(ser); if (BYTE_SIZE(ser) && c > 0xff) Widen_String(ser); SET_ANY_CHAR(ser, n, c); return PE_OK; }
*/ void Insert_Char(REBSER *dst, REBCNT index, REBCNT chr) /* ** Insert a Char (byte or unicode) into a string. ** ***********************************************************************/ { if (index > dst->tail) index = dst->tail; if (chr > 0xFF && BYTE_SIZE(dst)) Widen_String(dst, TRUE); Expand_Series(dst, index, 1); SET_ANY_CHAR(dst, index, chr); }
*/ void Insert_String(REBSER *dst, REBCNT idx, const REBSER *src, REBCNT pos, REBCNT len, REBFLG no_expand) /* ** Insert a non-encoded string into a series at given index. ** Source and/or destination can be 1 or 2 bytes wide. ** If destination is not wide enough, it will be widened. ** ***********************************************************************/ { REBUNI *up; REBYTE *bp; REBCNT n; if (idx > dst->tail) idx = dst->tail; if (!no_expand) Expand_Series(dst, idx, len); // tail changed too // Src and dst have same width (8 or 16): if (SERIES_WIDE(dst) == SERIES_WIDE(src)) { cp_same: if (BYTE_SIZE(dst)) memcpy(BIN_SKIP(dst, idx), BIN_SKIP(src, pos), len); else memcpy(UNI_SKIP(dst, idx), UNI_SKIP(src, pos), sizeof(REBUNI) * len); return; } // Src is 8 and dst is 16: if (!BYTE_SIZE(dst)) { bp = BIN_SKIP(src, pos); up = UNI_SKIP(dst, idx); for (n = 0; n < len; n++) up[n] = (REBUNI)bp[n]; return; } // Src is 16 and dst is 8: bp = BIN_SKIP(dst, idx); up = UNI_SKIP(src, pos); for (n = 0; n < len; n++) { if (up[n] > 0xFF) { //Debug_Num("##Widen-series because char value is:", up[n]); // Expand dst and restart: idx += n; pos += n; len -= n; Widen_String(dst, TRUE); goto cp_same; } bp[n] = (REBYTE)up[n]; } }