Пример #1
0
*/	REBSER *Copy_Sequence(REBSER *source)
/*
**		Copy any series that *isn't* an "array" (such as STRING!,
**		BINARY!, BITSET!, VECTOR!...).  Includes the terminator.
**
**		Use Copy_Array routines (which specify Shallow, Deep, etc.) for
**		greater detail needed when expressing intent for Rebol Arrays.
**
**		Note: No suitable name for "non-array-series" has been picked.
**		"Sequence" is used for now because Copy_Non_Array() doesn't
**		look good and lots of things aren't "Rebol Arrays" that aren't
**		series.  The main idea was just to get rid of the generic
**		Copy_Series() routine, which doesn't call any attention
**		to the importance of stating one's intentions specifically
**		about semantics when copying an array.
**
***********************************************************************/
{
	REBCNT len = source->tail + 1;
	REBSER *series = Make_Series(len, SERIES_WIDE(source), MKS_NONE);

	assert(!Is_Array_Series(source));

	memcpy(series->data, source->data, len * SERIES_WIDE(source));
	series->tail = source->tail;
	return series;
}
Пример #2
0
//
//  Dump_Series: C
//
void Dump_Series(REBSER *series, const char *memo)
{
    if (!series) return;
    Debug_Fmt(
        "%s Series %x \"%s\":"
            " wide: %2d"
            " size: %6d"
            " bias: %d"
            " tail: %d"
            " rest: %d"
            " flags: %x",
        memo,
        series,
        "-", // !label
        SER_WIDE(series),
        SER_TOTAL(series),
        SER_BIAS(series),
        SER_LEN(series),
        SER_REST(series),
        series->info.bits // flags + width
    );
    if (Is_Array_Series(series)) {
        Dump_Values(ARR_HEAD(AS_ARRAY(series)), SER_LEN(series));
    } else
        Dump_Bytes(
            SER_DATA_RAW(series),
            (SER_LEN(series) + 1) * SER_WIDE(series)
        );
}
Пример #3
0
//
//  Append_Series: C
// 
// Append value(s) onto the tail of a series.  The len is
// the number of units (bytes, REBVALS, etc.) of the data,
// and does not include the terminator (which will be added).
// The new tail position will be returned as the result.
// A terminator will be added to the end of the appended data.
//
void Append_Series(REBSER *s, const REBYTE *data, REBCNT len)
{
    REBCNT len_old = SER_LEN(s);
    REBYTE wide = SER_WIDE(s);

    assert(!Is_Array_Series(s));

    EXPAND_SERIES_TAIL(s, len);
    memcpy(SER_DATA_RAW(s) + (wide * len_old), data, wide * len);

    TERM_SERIES(s);
}
Пример #4
0
//
//  Trim_Tail: C
// 
// Used to trim off hanging spaces during FORM and MOLD.
//
void Trim_Tail(REBSER *src, REBYTE chr)
{
    REBOOL unicode = NOT(BYTE_SIZE(src));
    REBCNT tail;
    REBUNI c;

    assert(!Is_Array_Series(src));

    for (tail = SER_LEN(src); tail > 0; tail--) {
        c = unicode ? *UNI_AT(src, tail - 1) : *BIN_AT(src, tail - 1);
        if (c != chr) break;
    }
    SET_SERIES_LEN(src, tail);
    TERM_SEQUENCE(src);
}
Пример #5
0
/* set storage memory to external addr: raw_addr */
static void set_ext_storage (REBVAL *out, REBINT raw_size, REBUPT raw_addr)
{
	REBSER *data_ser = VAL_STRUCT_DATA_BIN(out);
	REBSER *ser = NULL;

	if (raw_size >= 0 && raw_size != cast(REBINT, VAL_STRUCT_LEN(out)))
		raise Error_0(RE_INVALID_DATA);

	ser = Make_Series(
		SERIES_LEN(data_ser) + 1, // include term.
		SERIES_WIDE(data_ser),
		Is_Array_Series(data_ser) ? (MKS_ARRAY | MKS_EXTERNAL) : MKS_EXTERNAL
	);

	ser->data = (REBYTE*)raw_addr;

	VAL_STRUCT_DATA_BIN(out) = ser;
	MANAGE_SERIES(ser);
}
Пример #6
0
*/	void Trim_Tail(REBSER *src, REBYTE chr)
/*
**		Used to trim off hanging spaces during FORM and MOLD.
**
***********************************************************************/
{
	REBOOL is_uni = !BYTE_SIZE(src);
	REBCNT tail;
	REBUNI c;

	assert(!Is_Array_Series(src));

	for (tail = SERIES_TAIL(src); tail > 0; tail--) {
		c = is_uni ? *UNI_SKIP(src, tail - 1) : *BIN_SKIP(src, tail - 1);
		if (c != chr) break;
	}
	SERIES_TAIL(src) = tail;
	TERM_SEQUENCE(src);
}
Пример #7
0
*/	void Assert_Series_Term_Core(REBSER *series)
/*
***********************************************************************/
{
	if (Is_Array_Series(series)) {
		// REB_END values may not be canonized to zero bytes, check type only
		if (!IS_END(BLK_SKIP(series, series->tail))) {
			Debug_Fmt("Unterminated blocklike series detected");
			Panic_Series(series);
		}
	}
	else {
		// Non-REBVAL-bearing series must have their terminal as all 0 bytes
		int n;
		for (n = 0; n < SERIES_WIDE(series); n++) {
			if (0 != series->data[series->tail * SERIES_WIDE(series) + n]) {
				Debug_Fmt("Non-zero byte in terminator of non-block series");
				Panic_Series(series);
			}
		}
	}
}
Пример #8
0
*/	REBSER *Copy_Sequence_At_Len(REBSER *source, REBCNT index, REBCNT len)
/*
**		Copy a subseries out of a series that is not an array.
**		Includes the terminator for it.
**
**		Use Copy_Array routines (which specify Shallow, Deep, etc.) for
**		greater detail needed when expressing intent for Rebol Arrays.
**
***********************************************************************/
{
	REBSER *series = Make_Series(len + 1, SERIES_WIDE(source), MKS_NONE);

	assert(!Is_Array_Series(source));

	memcpy(
		series->data,
		source->data + index * SERIES_WIDE(source),
		(len + 1) * SERIES_WIDE(source)
	);
	series->tail = len;
	return series;
}
Пример #9
0
*/  REBSER *Copy_Buffer(REBSER *buf, void *end)
/*
**		Copy a shared buffer. Set tail and termination.
**
***********************************************************************/
{
	REBSER *ser;
	REBCNT len;

	len = BYTE_SIZE(buf) ? ((REBYTE *)end) - BIN_HEAD(buf)
		: ((REBUNI *)end) - UNI_HEAD(buf);

	ser = Make_Series(
		len + 1,
		SERIES_WIDE(buf),
		Is_Array_Series(buf) ? MKS_ARRAY : MKS_NONE
	);

	memcpy(ser->data, buf->data, SERIES_WIDE(buf) * len);
	ser->tail = len;
	TERM_SERIES(ser);

	return ser;
}