Ejemplo n.º 1
0
Archivo: p-file.c Proyecto: mbk/ren-c
*/	static void Read_File_Port(REBVAL *out, REBSER *port, REBREQ *file, REBVAL *path, REBCNT args, REBCNT len)
/*
**		Read from a file port.
**
***********************************************************************/
{
	REBSER *ser;

	// Allocate read result buffer:
	ser = Make_Binary(len);
	Set_Series(REB_BINARY, out, ser); //??? what if already set?

	// Do the read, check for errors:
	file->common.data = BIN_HEAD(ser);
	file->length = len;
	if (OS_DO_DEVICE(file, RDC_READ) < 0)
		Trap_Port(RE_READ_ERROR, port, file->error);
	SERIES_TAIL(ser) = file->actual;
	STR_TERM(ser);

	// Convert to string or block of strings.
	// NOTE: This code is incorrect for files read in chunks!!!
	if (args & (AM_READ_STRING | AM_READ_LINES)) {
		REBSER *nser = Decode_UTF_String(BIN_HEAD(ser), file->actual, -1);
		if (nser == NULL) {
			Trap(RE_BAD_DECODE);
		}
		Set_String(out, nser);
		if (args & AM_READ_LINES) Set_Block(out, Split_Lines(out));
	}
}
Ejemplo n.º 2
0
*/	void Init_Words(REBFLG only)
/*
**		Only flags BIND_Table creation only (for threads).
**
***********************************************************************/
{
	REBCNT n = Get_Hash_Prime(WORD_TABLE_SIZE * 4); // extra to reduce rehashing

	if (!only) {
		// Create the hash for locating words quickly:
		// Note that the TAIL is never changed for this series.
		PG_Word_Table.hashes = Make_Series(n+1, sizeof(REBCNT), FALSE);
		KEEP_SERIES(PG_Word_Table.hashes, "word hashes"); // pointer array
		Clear_Series(PG_Word_Table.hashes);
		PG_Word_Table.hashes->tail = n;

		// The word (symbol) table itself:
		PG_Word_Table.series = Make_Block(WORD_TABLE_SIZE);
		SET_NONE(BLK_HEAD(PG_Word_Table.series)); // Put a NONE at head.
		KEEP_SERIES(PG_Word_Table.series, "word table"); // words are never GC'd
		BARE_SERIES(PG_Word_Table.series); // don't bother to GC scan it
		PG_Word_Table.series->tail = 1;  // prevent the zero case

		// A normal char array to hold symbol names:
		PG_Word_Names = Make_Binary(6 * WORD_TABLE_SIZE); // average word size
		KEEP_SERIES(PG_Word_Names, "word names");
	}

	// The bind table. Used to cache context indexes for given symbols.
	Bind_Table = Make_Series(SERIES_REST(PG_Word_Table.series), 4, FALSE);
	KEEP_SERIES(Bind_Table, "bind table"); // numeric table
	CLEAR_SERIES(Bind_Table);
	Bind_Table->tail = PG_Word_Table.series->tail;
}
Ejemplo n.º 3
0
*/	void *Use_Port_State(REBSER *port, REBCNT device, REBCNT size)
/*
**		Use private state area in a port. Create if necessary.
**		The size is that of a binary structure used by
**		the port for storing internal information.
**
***********************************************************************/
{
	REBVAL *state = BLK_SKIP(port, STD_PORT_STATE);

	// If state is not a binary structure, create it:
	if (!IS_BINARY(state)) {
		REBSER *data = Make_Binary(size);
		REBREQ *req = (REBREQ*)STR_HEAD(data);
		req->clen = size;
		CLEAR(STR_HEAD(data), size);
		//data->tail = size; // makes it easier for ACCEPT to clone the port
		SET_FLAG(req->flags, RRF_ALLOC); // not on stack
		req->port = port;
		req->device = device;
		Val_Init_Binary(state, data);
	}

	return (void *)VAL_BIN(state);
}
Ejemplo n.º 4
0
*/ RL_API void *RL_Make_String(u32 size, int unicode)
/*
**	Allocate a new string or binary series.
**
**	Returns:
**		A pointer to a string or binary series.
**	Arguments:
**		size - the length of the string. The system will add one extra
**			for a null terminator (not strictly required, but good for C.)
**		unicode - set FALSE for ASCII/Latin1 strings, set TRUE for Unicode.
**	Notes:
**		Strings can be REBYTE or REBCHR sized (depends on R3 config.)
**		Strings are allocated with REBOL's internal memory manager.
**		Internal structures may change, so NO assumptions should be made!
**		Strings are automatically garbage collected if there are
**		no references to them from REBOL code (C code does nothing.)
**		However, you can lock strings to prevent deallocation. (?? default)
**
***********************************************************************/
{
	REBSER *result = unicode ? Make_Unicode(size) : Make_Binary(size);

	// !!! Assume client does not have Free_Series() or MANAGE_SERIES()
	// APIs, so the series we give back must be managed.  But how can
	// we be sure they get what usage they needed before the GC happens?
	MANAGE_SERIES(result);
	return result;
}
Ejemplo n.º 5
0
*/  REBSER *Decompress(REBSER *input, REBCNT index, REBINT len, REBCNT limit, REBFLG use_crc)
/*
**      Decompress a binary (only).
**
***********************************************************************/
{
	REBCNT size;
	REBSER *output;
	REBINT err;

	if (len < 0 || (index + len > BIN_LEN(input))) len = BIN_LEN(input) - index;

	// Get the size from the end and make the output buffer that size.
	if (len <= 4) Trap0(RE_PAST_END); // !!! better msg needed
	size = Bytes_To_Long(BIN_SKIP(input, len) - 4);

	if (limit && size > limit) Trap_Num(RE_SIZE_LIMIT, size); 

	output = Make_Binary(size + 20); // (Why 20 extra? -CS)

	//DISABLE_GC;
	err = Z_uncompress(BIN_HEAD(output), (uLongf*)&size, BIN_HEAD(input) + index, len, use_crc);
	if (err) {
		if (PG_Boot_Phase < 2) return 0;
		if (err == Z_MEM_ERROR) Trap0(RE_NO_MEMORY);
		SET_INTEGER(DS_RETURN, err);
		Trap1(RE_BAD_PRESS, DS_RETURN); //!!!provide error string descriptions
	}
	SET_STR_END(output, size);
	SERIES_TAIL(output) = size;
	//ENABLE_GC;
	return output;
}
Ejemplo n.º 6
0
// Used for file loading during very early development.
static REBSER *Read_All_File(char *fname)
{
	REBREQ file;
	REBSER *ser = 0;

	CLEAR(&file, sizeof(file));

	file.clen = sizeof(file);
	file.device = RDI_FILE;
	file.file.path = fname;

	SET_FLAG(file.modes, RFM_READ);

	OS_DO_DEVICE(&file, RDC_OPEN);

	if (file.error) return 0;

	ser = Make_Binary((REBCNT)(file.file.size));

	file.data = BIN_DATA(ser);
	file.length = (REBCNT)(file.file.size);

	OS_DO_DEVICE(&file, RDC_READ);

	if (file.error) {
		ser = 0;
	}
	else {
		ser->tail = file.actual;
		STR_TERM(ser);
	}

	OS_DO_DEVICE(&file, RDC_CLOSE);
	return ser;
}
Ejemplo n.º 7
0
*/	REBSER *Copy_Wide_Str(void *src, REBINT len)
/*
**		Create a REBOL string series from a wide char string.
**		Minimize to bytes if possible
*/
{
    REBSER *dst;
    REBUNI *str = (REBUNI*)src;
    if (Is_Wide(str, len)) {
        REBUNI *up;
        dst = Make_Unicode(len);
        SERIES_TAIL(dst) = len;
        up = UNI_HEAD(dst);
        while (len-- > 0) *up++ = *str++;
        *up = 0;
    }
    else {
        REBYTE *bp;
        dst = Make_Binary(len);
        SERIES_TAIL(dst) = len;
        bp = BIN_HEAD(dst);
        while (len-- > 0) *bp++ = (REBYTE)*str++;
        *bp = 0;
    }
    return dst;
}
Ejemplo n.º 8
0
static REBSER *make_string(REBVAL *arg, REBOOL make)
{
	REBSER *ser = 0;

	// MAKE <type> 123
	if (make && (IS_INTEGER(arg) || IS_DECIMAL(arg))) {
		ser = Make_Binary(Int32s(arg, 0));
	}
	// MAKE/TO <type> <binary!>
	else if (IS_BINARY(arg)) {
		REBYTE *bp = VAL_BIN_DATA(arg);
		REBCNT len = VAL_LEN(arg);
		switch (What_UTF(bp, len)) {
		case 0:
			break;
		case 8: // UTF-8 encoded
			bp  += 3;
			len -= 3;
			break;
		default:
			Trap0(RE_BAD_DECODE);
		}
		ser = Decode_UTF_String(bp, len, 8); // UTF-8
	}
	// MAKE/TO <type> <any-string>
	else if (ANY_BINSTR(arg)) {
		ser = Copy_String(VAL_SERIES(arg), VAL_INDEX(arg), VAL_LEN(arg));
	}
	// MAKE/TO <type> <any-word>
	else if (ANY_WORD(arg)) {
		ser = Copy_Mold_Value(arg, TRUE);
		//ser = Append_UTF8(0, Get_Word_Name(arg), -1);
	}
	// MAKE/TO <type> #"A"
	else if (IS_CHAR(arg)) {
		ser = (VAL_CHAR(arg) > 0xff) ? Make_Unicode(2) : Make_Binary(2);
		Append_Byte(ser, VAL_CHAR(arg));
	}
	// MAKE/TO <type> <any-value>
//	else if (IS_NONE(arg)) {
//		ser = Make_Binary(0);
//	}
	else
		ser = Copy_Form_Value(arg, 1<<MOPT_TIGHT);

	return ser;
}
Ejemplo n.º 9
0
//
//  MAKE_String: C
//
void MAKE_String(REBVAL *out, enum Reb_Kind kind, const REBVAL *def) {
    REBSER *ser; // goto would cross initialization

    if (IS_INTEGER(def)) {
        //
        // !!! R3-Alpha tolerated decimal, e.g. `make string! 3.14`, which
        // is semantically nebulous (round up, down?) and generally bad.
        //
        ser = Make_Binary(Int32s(def, 0));
        Val_Init_Series(out, kind, ser);
        return;
    }
    else if (IS_BLOCK(def)) {
        //
        // The construction syntax for making strings or binaries that are
        // preloaded with an offset into the data is #[binary [#{0001} 2]].
        // In R3-Alpha make definitions didn't have to be a single value
        // (they are for compatibility between construction syntax and MAKE
        // in Ren-C).  So the positional syntax was #[binary! #{0001} 2]...
        // while #[binary [#{0001} 2]] would join the pieces together in order
        // to produce #{000102}.  That behavior is not available in Ren-C.

        if (VAL_ARRAY_LEN_AT(def) != 2)
            goto bad_make;

        RELVAL *any_binstr = VAL_ARRAY_AT(def);
        if (!ANY_BINSTR(any_binstr))
            goto bad_make;
        if (IS_BINARY(any_binstr) != LOGICAL(kind == REB_BINARY))
            goto bad_make;

        RELVAL *index = VAL_ARRAY_AT(def) + 1;
        if (!IS_INTEGER(index))
            goto bad_make;

        REBINT i = Int32(index) - 1 + VAL_INDEX(any_binstr);
        if (i < 0 || i > cast(REBINT, VAL_LEN_AT(any_binstr)))
            goto bad_make;

        Val_Init_Series_Index(out, kind, VAL_SERIES(any_binstr), i);
        return;
    }

    if (kind == REB_BINARY)
        ser = make_binary(def, TRUE);
    else
        ser = MAKE_TO_String_Common(def);

    if (!ser)
        goto bad_make;

    Val_Init_Series_Index(out, kind, ser, 0);
    return;

bad_make:
    fail (Error_Bad_Make(kind, def));
}
Ejemplo n.º 10
0
//
//  RL_Make_String: C
// 
// Allocate a new string or binary series.
// 
// Returns:
//     A pointer to a string or binary series.
// Arguments:
//     size - the length of the string. The system will add one extra
//         for a null terminator (not strictly required, but good for C.)
//     unicode - set FALSE for ASCII/Latin1 strings, set TRUE for Unicode.
// Notes:
//     Strings can be REBYTE or REBCHR sized (depends on R3 config.)
//     Strings are allocated with REBOL's internal memory manager.
//     Internal structures may change, so NO assumptions should be made!
//     Strings are automatically garbage collected if there are
//     no references to them from REBOL code (C code does nothing.)
//     However, you can lock strings to prevent deallocation. (?? default)
//
RL_API REBSER *RL_Make_String(u32 size, REBOOL unicode)
{
    REBSER *result = unicode ? Make_Unicode(size) : Make_Binary(size);

    // !!! Assume client does not have Free_Series() or MANAGE_SERIES()
    // APIs, so the series we give back must be managed.  But how can
    // we be sure they get what usage they needed before the GC happens?
    MANAGE_SERIES(result);
    return result;
}
Ejemplo n.º 11
0
//
//  Make_Bitset: C
// 
// Return a bitset series (binary.
// 
// len: the # of bits in the bitset.
//
REBSER *Make_Bitset(REBCNT len)
{
    REBSER *ser;

    len = (len + 7) / 8;
    ser = Make_Binary(len);
    Clear_Series(ser);
    SET_SERIES_LEN(ser, len);
    BITS_NOT(ser) = FALSE;

    return ser;
}
Ejemplo n.º 12
0
//
//  Complement_Binary: C
//
// Only valid for BINARY data.
//
REBSER *Complement_Binary(REBVAL *value)
{
    const REBYTE *bp = VAL_BIN_AT(value);
    REBCNT len = VAL_LEN_AT(value);

    REBSER *bin = Make_Binary(len);
    TERM_SEQUENCE_LEN(bin, len);

    REBYTE *dp = BIN_HEAD(bin);
    for (; len > 0; len--, ++bp, ++dp)
        *dp = ~(*bp);

    return bin;
}
Ejemplo n.º 13
0
Archivo: s-unicode.c Proyecto: Oldes/r3
*/	REBSER *Decode_UTF_String(REBYTE *bp, REBCNT len, REBINT utf, REBFLG ccr)
/*
**		Do all the details to decode a string.
**		Input is a byte series. Len is len of input.
**		The utf is 0, 8, +/-16, +/-32.
**		A special -1 means use the BOM.
**
***********************************************************************/
{
	REBSER *ser = BUF_UTF8; // buffer is Unicode width
	REBSER *dst;
	REBINT size;

	//REBFLG ccr = FALSE; // in original R3-alpha if was TRUE
	//@@ https://github.com/rebol/rebol-issues/issues/2336

	if (utf == -1) {
		utf = What_UTF(bp, len);
		if (utf) {
			if (utf == 8) bp += 3, len -= 3;
			else if (utf == -16 || utf == 16) bp += 2, len -= 2;
			else if (utf == -32 || utf == 32) bp += 4, len -= 4;
		}
	}

	if (utf == 0 || utf == 8) {
		size = Decode_UTF8((REBUNI*)Reset_Buffer(ser, len), bp, len, ccr);
	} 
	else if (utf == -16 || utf == 16) {
		size = Decode_UTF16((REBUNI*)Reset_Buffer(ser, len/2 + 1), bp, len, utf < 0, ccr);
	}
	else if (utf == -32 || utf == 32) {
		size = Decode_UTF32((REBUNI*)Reset_Buffer(ser, len/4 + 1), bp, len, utf < 0, ccr);
	}
    else {
        return NULL;
    }

	if (size < 0) {
		size = -size;
		dst = Make_Binary(size);
		Append_Uni_Bytes(dst, UNI_HEAD(ser), size);
	}
	else {
		dst = Make_Unicode(size);
		Append_Uni_Uni(dst, UNI_HEAD(ser), size);
	}

	return dst;
}
Ejemplo n.º 14
0
*/  REBSER *Compress(REBSER *input, REBINT index, REBINT len, REBFLG use_crc)
/*
**      Compress a binary (only).
**		data
**		/part
**		length
**		/crc32
**
**      Note: If the file length is "small", it can't overrun on
**      compression too much so we use our magic numbers; otherwise,
**      we'll just be safe by a percentage of the file size.  This may
**      be a bit much, though.
**
***********************************************************************/
{
    // NOTE: The use_crc flag is not present in Zlib 1.2.8
    // Instead, compress's fifth paramter is the compression level
    // It can be a value from 1 to 9, or Z_DEFAULT_COMPRESSION if you
    // want it to pick what the library author considers the "worth it"
    // tradeoff of time to generally suggest.

    uLongf size;
    REBSER *output;
    REBINT err;
    REBYTE out_size[sizeof(REBCNT)];

    if (len < 0) Trap_DEAD_END(RE_PAST_END); // !!! better msg needed
    size = len + (len > STERLINGS_MAGIC_NUMBER ? len / 10 + 12 : STERLINGS_MAGIC_FIX);
    output = Make_Binary(size);

    //DISABLE_GC;	// !!! why??
    // dest, dest-len, src, src-len, level
    err = z_compress2(BIN_HEAD(output), &size, BIN_HEAD(input) + index, len, Z_DEFAULT_COMPRESSION);
    if (err) {
        REBVAL arg;
        if (err == Z_MEM_ERROR) Trap_DEAD_END(RE_NO_MEMORY);
        SET_INTEGER(&arg, err);
        Trap1_DEAD_END(RE_BAD_PRESS, &arg); //!!!provide error string descriptions
    }
    SET_STR_END(output, size);
    SERIES_TAIL(output) = size;
    REBCNT_To_Bytes(out_size, (REBCNT)len); // Tag the size to the end.
    Append_Series(output, (REBYTE*)out_size, sizeof(REBCNT));
    if (SERIES_AVAIL(output) > 1024) // Is there wasted space?
        output = Copy_Series(output); // Trim it down if too big. !!! Revisit this based on mem alloc alg.
    //ENABLE_GC;

    return output;
}
Ejemplo n.º 15
0
*/  REBSER *Xandor_Binary(REBCNT action, REBVAL *value, REBVAL *arg)
/*
**		Only valid for BINARY data.
**
***********************************************************************/
{
		REBSER *series;
		REBYTE *p0 = VAL_BIN_DATA(value);
		REBYTE *p1 = VAL_BIN_DATA(arg);
		REBYTE *p2;
		REBCNT i;
		REBCNT mt, t1, t0, t2;

		t0 = VAL_LEN(value);
		t1 = VAL_LEN(arg);

		mt = MIN(t0, t1); // smaller array size
		// For AND - result is size of shortest input:
//		if (action == A_AND || (action == 0 && t1 >= t0))
//			t2 = mt;
//		else
		t2 = MAX(t0, t1);

		series = Make_Binary(t2);
		SERIES_TAIL(series) = t2;
		p2 = BIN_HEAD(series);

		switch (action) {
		case A_AND:
			for (i = 0; i < mt; i++) *p2++ = *p0++ & *p1++;
			CLEAR(p2, t2 - mt);
			return series;
		case A_OR:
			for (i = 0; i < mt; i++) *p2++ = *p0++ | *p1++;
			break;
		case A_XOR:
			for (i = 0; i < mt; i++) *p2++ = *p0++ ^ *p1++;
			break;
		default:
			// special bit set case EXCLUDE:
			for (i = 0; i < mt; i++) *p2++ = *p0++ & ~*p1++;
			if (t0 > t1) memcpy(p2, p0, t0 - t1); // residual from first only
			return series;
		}

		// Copy the residual:
		memcpy(p2, ((t0 > t1) ? p0 : p1), t2 - mt);
		return series;
}
Ejemplo n.º 16
0
static REBSER *Make_Binary_BE64(REBVAL *arg)
{
	REBSER *ser = Make_Binary(9);
	REBI64 n = VAL_INT64(arg);
	REBINT count;
	REBYTE *bp = BIN_HEAD(ser);

	for (count = 7; count >= 0; count--) {
		bp[count] = (REBYTE)(n & 0xff);
		n >>= 8;
	}
	bp[8] = 0;
	ser->tail = 8;

	return ser;
}
Ejemplo n.º 17
0
*/	static void Scan_Error(REBCNT errnum, SCAN_STATE *ss, REBCNT tkn, REBYTE *arg, REBCNT size, REBVAL *relax)
/*
**		Scanner error handler
**
***********************************************************************/
{
	ERROR_OBJ *error;
	REBSER *errs;
	REBYTE *name;
	REBYTE *cp;
	REBYTE *bp;
	REBSER *ser;
	REBCNT len = 0;

	ss->errors++;

	if (PG_Boot_Strs)
		name = BOOT_STR(RS_SCAN,tkn);
	else
		name = (REBYTE*)"boot";

	cp = ss->head_line;
    while (IS_LEX_SPACE(*cp)) cp++;	// skip indentation
	bp = cp;
	while (NOT_NEWLINE(*cp)) cp++, len++;

	//DISABLE_GC;
	errs = Make_Error(errnum, 0, 0, 0);
	error = (ERROR_OBJ *)FRM_VALUES(errs);
	ser = Make_Binary(len + 16);
	Append_Bytes(ser, "(line ");
	Append_Int(ser, ss->line_count);
	Append_Bytes(ser, ") ");
	Append_Series(ser, (REBYTE*)bp, len);
	Set_String(&error->nearest, ser);
	Set_String(&error->arg1, Copy_Bytes(name, -1));
	Set_String(&error->arg2, Copy_Bytes(arg, size));

	if (relax) {
		SET_ERROR(relax, errnum, errs);
		//ENABLE_GC;
		return;
	}

	Throw_Error(errs);	// ENABLE_GC implied
}
Ejemplo n.º 18
0
Archivo: d-print.c Proyecto: mbk/ren-c
*/	void Enable_Backtrace(REBFLG on)
/*
***********************************************************************/
{
	if (on) {
		if (Trace_Limit == 0) {
			Trace_Limit = 100000;
			Trace_Buffer = Make_Binary(Trace_Limit);
			KEEP_SERIES(Trace_Buffer, "trace-buffer"); // !!! use better way
		}
	}
	else {
		if (Trace_Limit) Free_Series(Trace_Buffer);
		Trace_Limit = 0;
		Trace_Buffer = 0;
	}
}
Ejemplo n.º 19
0
//
//  Complement_Binary: C
// 
// Only valid for BINARY data.
//
REBSER *Complement_Binary(REBVAL *value)
{
        REBSER *series;
        REBYTE *str = VAL_BIN_AT(value);
        REBINT len = VAL_LEN_AT(value);
        REBYTE *out;

        series = Make_Binary(len);
        SET_SERIES_LEN(series, len);
        out = BIN_HEAD(series);
        for (; len > 0; len--) {
            *out++ = ~(*str);
            ++str;
        }

        return series;
}
Ejemplo n.º 20
0
*/	REBSER *Make_Bitset(REBCNT len)
/*
**		Return a bitset series (binary.
**
**		len: the # of bits in the bitset.
**
***********************************************************************/
{
	REBSER *ser;

	len = (len + 7) / 8;
	ser = Make_Binary(len);
	Clear_Series(ser);
	SERIES_TAIL(ser) = len;
	BITS_NOT(ser) = 0;

	return ser;
}
Ejemplo n.º 21
0
*/	REBSER *Copy_Bytes(const REBYTE *src, REBINT len)
/*
**		Create a string series from the given bytes.
**		Source is always latin-1 valid. Result is always 8bit.
**
***********************************************************************/
{
    REBSER *dst;

    if (len < 0) len = LEN_BYTES(src);

    dst = Make_Binary(len);
    memcpy(STR_DATA(dst), src, len);
    SERIES_TAIL(dst) = len;
    STR_TERM(dst);

    return dst;
}
Ejemplo n.º 22
0
*/	REBSER *Complement_Binary(REBVAL *value)
/*
**		Only valid for BINARY data.
**
***********************************************************************/
{
		REBSER *series;
		REBYTE *str = VAL_BIN_DATA(value);
		REBINT len = VAL_LEN(value);
		REBYTE *out;

		series = Make_Binary(len);
		SERIES_TAIL(series) = len;
		out = BIN_HEAD(series);
		for (; len > 0; len--)
			*out++ = ~ *str++;

		return series;
}
Ejemplo n.º 23
0
*/  REBSER *Compress(REBSER *input, REBINT index, REBINT len, REBFLG use_crc)
/*
**      Compress a binary (only).
**		data
**		/part
**		length
**		/crc32
**
**      Note: If the file length is "small", it can't overrun on
**      compression too much so we use our magic numbers; otherwise,
**      we'll just be safe by a percentage of the file size.  This may
**      be a bit much, though.
**
***********************************************************************/
{
	REBCNT size;
	REBSER *output;
	REBINT err;
	REBYTE out_size[4];

	if (len < 0) Trap0(RE_PAST_END); // !!! better msg needed
	size = len + (len > STERLINGS_MAGIC_NUMBER ? len / 10 + 12 : STERLINGS_MAGIC_FIX);
	output = Make_Binary(size);

	//DISABLE_GC;	// !!! why??
	// dest, dest-len, src, src-len, level
	err = Z_compress2(BIN_HEAD(output), (uLongf*)&size, BIN_HEAD(input) + index, len, use_crc);
	if (err) {
		if (err == Z_MEM_ERROR) Trap0(RE_NO_MEMORY);
		SET_INTEGER(DS_RETURN, err);
		Trap1(RE_BAD_PRESS, DS_RETURN); //!!!provide error string descriptions
	}
	SET_STR_END(output, size);
	SERIES_TAIL(output) = size;
	Long_To_Bytes(out_size, (REBCNT)len); // Tag the size to the end.
	Append_Series(output, (REBYTE*)out_size, 4);
	if (SERIES_AVAIL(output) > 1024) // Is there wasted space?
		output = Copy_Series(output); // Trim it down if too big. !!! Revisit this based on mem alloc alg.
	//ENABLE_GC;

	return output;
}
Ejemplo n.º 24
0
Archivo: f-enbase.c Proyecto: mbk/ren-c
*/	static REBSER *Decode_Base64(const REBYTE **src, REBCNT len, REBYTE delim)
/*
***********************************************************************/
{
	REBYTE *bp;
	const REBYTE *cp;
	REBCNT flip = 0;
	REBINT accum = 0;
	REBYTE lex;
	REBSER *ser;

	// Allocate buffer large enough to hold result:
	// Accounts for e bytes decoding into 3 bytes.
	ser = Make_Binary(((len + 3) * 3) / 4);
	bp = STR_HEAD(ser);
	cp = *src;

	for (; len > 0; cp++, len--) {

		// Check for terminating delimiter (optional):
		if (delim && *cp == delim) break;

		// Check for char out of range:
		if (*cp > 127) {
			if (*cp == 0xA0) continue;  // hard space
			goto err;
		}

		lex = Debase64[*cp];

		if (lex < BIN_SPACE) {

			if (*cp != '=')	{
				accum = (accum << 6) + lex;
				if (flip++ == 3) {
					*bp++ = (REBYTE)(accum >> 16);
					*bp++ = (REBYTE)(accum >> 8);
					*bp++ = (REBYTE)(accum);
					accum = 0;
					flip = 0;
				}
			} else {
Ejemplo n.º 25
0
Archivo: f-enbase.c Proyecto: mbk/ren-c
*/	static REBSER *Decode_Base16(const REBYTE **src, REBCNT len, REBYTE delim)
/*
***********************************************************************/
{
	REBYTE *bp;
	const REBYTE *cp;
	REBCNT count = 0;
	REBINT accum = 0;
	REBYTE lex;
	REBINT val;
	REBSER *ser;

	ser = Make_Binary(len / 2);
	bp = STR_HEAD(ser);
	cp = *src;

	for (; len > 0; cp++, len--) {

		if (delim && *cp == delim) break;

		lex = Lex_Map[*cp];

		if (lex > LEX_WORD) {
			val = lex & LEX_VALUE; // char num encoded into lex
			if (!val && lex < LEX_NUMBER) goto err;  // invalid char (word but no val)
			accum = (accum << 4) + val;
			if (count++ & 1) *bp++ = (REBYTE)accum;
		}
		else if (!*cp || lex > LEX_DELIMIT_RETURN) goto err;
	}
	if (count & 1) goto err; // improper modulus

	*bp = 0;
	ser->tail = bp - STR_HEAD(ser);
	return ser;

err:
	Free_Series(ser);
	*src = cp;
	return 0;
}
Ejemplo n.º 26
0
RL_API void *RL_Make_String(u32 size, int unicode)
/*
**	Allocate a new string or binary series.
**
**	Returns:
**		A pointer to a string or binary series.
**	Arguments:
**		size - the length of the string. The system will add one extra
**			for a null terminator (not strictly required, but good for C.)
**		unicode - set FALSE for ASCII/Latin1 strings, set TRUE for Unicode.
**	Notes:
**		Strings can be REBYTE or REBCHR sized (depends on R3 config.)
**		Strings are allocated with REBOL's internal memory manager.
**		Internal structures may change, so NO assumptions should be made!
**		Strings are automatically garbage collected if there are
**		no references to them from REBOL code (C code does nothing.)
**		However, you can lock strings to prevent deallocation. (?? default)
*/
{
	return unicode ? Make_Unicode(size) : Make_Binary(size);
}
Ejemplo n.º 27
0
*/  REBSER *Decompress(const REBYTE *data, REBCNT len, REBCNT limit, REBFLG use_crc)
/*
**      Decompress a binary (only).
**
**		Rebol's compress/decompress functions store an extra length
**		at the tail of the data, to double-check the zlib result
**
***********************************************************************/
{
    // NOTE: The use_crc flag is not present in Zlib 1.2.8
    // There is no fifth parameter to uncompress matching the fifth to compress

    uLongf size;
    REBSER *output;
    REBINT err;

    // Get the size from the end and make the output buffer that size.
    if (len <= 4) Trap_DEAD_END(RE_PAST_END); // !!! better msg needed
    size = Bytes_To_REBCNT(data + len - sizeof(REBCNT));

    // NOTE: You can hit this if you 'make prep' without doing a full rebuild
    // (If you 'make clean' and build again and this goes away, it was that)
    if (limit && size > limit) Trap_Num(RE_SIZE_LIMIT, size);

    output = Make_Binary(size);

    //DISABLE_GC;
    err = z_uncompress(BIN_HEAD(output), &size, data, len);
    if (err) {
        REBVAL arg;
        if (PG_Boot_Phase < 2) return 0;
        if (err == Z_MEM_ERROR) Trap_DEAD_END(RE_NO_MEMORY);
        SET_INTEGER(&arg, err);
        Trap1_DEAD_END(RE_BAD_PRESS, &arg); //!!!provide error string descriptions
    }
    SET_STR_END(output, size);
    SERIES_TAIL(output) = size;
    //ENABLE_GC;
    return output;
}
Ejemplo n.º 28
0
*/  REBSER *Prep_String(REBSER *series, REBYTE **str, REBCNT len)
/*
**		Helper function for the string related Mold functions below.
**		Creates or expands the series and provides the location to
**		copy text into.
**
***********************************************************************/
{
	REBCNT tail;

	if (!series) {
		series = Make_Binary(len);
		series->tail = len;
		*str = STR_HEAD(series);
	}
	else {
		tail = SERIES_TAIL(series);
		EXPAND_SERIES_TAIL(series, len);
		*str = STR_SKIP(series, tail);
	}
	return series;
}
Ejemplo n.º 29
0
static REBSER *MAKE_TO_String_Common(const REBVAL *arg)
{
    REBSER *ser = 0;

    // MAKE/TO <type> <binary!>
    if (IS_BINARY(arg)) {
        REBYTE *bp = VAL_BIN_AT(arg);
        REBCNT len = VAL_LEN_AT(arg);
        switch (What_UTF(bp, len)) {
        case 0:
            break;
        case 8: // UTF-8 encoded
            bp  += 3;
            len -= 3;
            break;
        default:
            fail (Error(RE_BAD_UTF8));
        }
        ser = Decode_UTF_String(bp, len, 8); // UTF-8
    }
    // MAKE/TO <type> <any-string>
    else if (ANY_BINSTR(arg)) {
        ser = Copy_String_Slimming(VAL_SERIES(arg), VAL_INDEX(arg), VAL_LEN_AT(arg));
    }
    // MAKE/TO <type> <any-word>
    else if (ANY_WORD(arg)) {
        ser = Copy_Mold_Value(arg, 0 /* opts... MOPT_0? */);
    }
    // MAKE/TO <type> #"A"
    else if (IS_CHAR(arg)) {
        ser = (VAL_CHAR(arg) > 0xff) ? Make_Unicode(2) : Make_Binary(2);
        Append_Codepoint_Raw(ser, VAL_CHAR(arg));
    }
    else
        ser = Copy_Form_Value(arg, 1 << MOPT_TIGHT);

    return ser;
}
Ejemplo n.º 30
0
xx*/  void Dump_Block(REBVAL *blk, REBINT len)
/*
**		Dump a block's contents for debugging purposes.
**
***********************************************************************/
{
	REBSER *series;
	//REBVAL *blk = BLK_HEAD(block);

	//Print("BLOCK: %x Tail: %d Size: %d", block, block->tail, block->rest);
	// change to a make string!!!  no need to append to a series, this is a debug function
	series = Make_Binary(100);
	Append_Bytes(series, "[\n");
	while (NOT_END(blk) && len-- > 0) {
		Append_Byte(series, '\t');
		Dump_Value(blk, series);
		Append_Byte(series, '\n');
		blk++;
	}
	Append_Byte(series, ']');
	*STR_TAIL(series) = 0;
	Debug_Str(STR_HEAD(series));
}