コード例 #1
0
ファイル: p-file.c プロジェクト: 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));
	}
}
コード例 #2
0
ファイル: u-compress.c プロジェクト: 51weekend/r3
*/  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;
}
コード例 #3
0
ファイル: a-lib.c プロジェクト: kjanz1899/ren-c
//
//  RL_Do_Binary: C
// 
// Evaluate an encoded binary script such as compressed text.
// 
// Returns:
//     The datatype of the result or zero if error in the encoding.
// Arguments:
//     bin - by default, a REBOL compressed UTF-8 (or ASCII) script.
//     length - the length of the data.
//     flags - special flags (set to zero at this time).
//     key - encoding, encryption, or signature key.
//     result - value returned from evaluation.
// Notes:
//     As of A104, only compressed scripts are supported, however,
//     rebin, cloaked, signed, and encrypted formats will be supported.
//
RL_API int RL_Do_Binary(
    int *exit_status,
    const REBYTE *bin,
    REBINT length,
    REBCNT flags,
    REBCNT key,
    RXIARG *out
) {
    REBSER *text;
#ifdef DUMP_INIT_SCRIPT
    int f;
#endif
    int maybe_rxt; // could be REBRXT, or negative number for error :-/

    text = Decompress(bin, length, -1, FALSE, FALSE);
    if (!text) return 0;
    Append_Codepoint_Raw(text, 0);

#ifdef DUMP_INIT_SCRIPT
    f = _open("host-boot.r", _O_CREAT | _O_RDWR, _S_IREAD | _S_IWRITE );
    _write(f, BIN_HEAD(text), LEN_BYTES(BIN_HEAD(text)));
    _close(f);
#endif

    PUSH_GUARD_SERIES(text);
    maybe_rxt = RL_Do_String(exit_status, BIN_HEAD(text), flags, out);
    DROP_GUARD_SERIES(text);

    Free_Series(text);
    return maybe_rxt;
}
コード例 #4
0
ファイル: s-find.c プロジェクト: BrianHawley/rebol
*/	REBCNT Find_Byte_Str(REBSER *series, REBCNT index, REBYTE *b2, REBCNT l2, REBFLG uncase, REBFLG match)
/*
**		Find a byte string within a byte string. Optimized for speed.
**
**		Returns starting position or NOT_FOUND.
**
**		Uncase: compare is case-insensitive.
**		Match: compare to first position only.
**
**		NOTE: Series tail must be > index.
**
***********************************************************************/
{
	REBYTE *b1;
	REBYTE *e1;
	REBCNT l1;
	REBYTE c;
	REBCNT n;

	// The pattern empty or is longer than the target:
	if (l2 == 0 || (l2 + index) > SERIES_TAIL(series)) return NOT_FOUND;

	b1 = BIN_SKIP(series, index);
	l1 = SERIES_TAIL(series) - index;

	e1 = b1 + (match ? 1 : l1 - (l2 - 1));

	c = *b2; // first char

	if (!uncase) {

		while (b1 != e1) {
			if (*b1 == c) { // matched first char
				for (n = 1; n < l2; n++) {
					if (b1[n] != b2[n]) break;
				}
				if (n == l2) return (b1 - BIN_HEAD(series));
			}
			b1++;
		}

	} else {

		c = (REBYTE)LO_CASE(c); // OK! (never > 255)

		while (b1 != e1) {
			if (LO_CASE(*b1) == c) { // matched first char
				for (n = 1; n < l2; n++) {
					if (LO_CASE(b1[n]) != LO_CASE(b2[n])) break;
				}
				if (n == l2) return (b1 - BIN_HEAD(series));
			}
			b1++;
		}

	}

	return NOT_FOUND;
}
コード例 #5
0
ファイル: s-ops.c プロジェクト: rhencke/rebol
//
//  Temp_Byte_Chars_May_Fail: C
// 
// NOTE: This function returns a temporary result, and uses an internal
// buffer.  Do not use it recursively.  Also, it will Trap on errors.
// 
// Prequalifies a string before using it with a function that
// expects it to be 8-bits.  It would be used for instance to convert
// a string that is potentially REBUNI-wide into a form that can be used
// with a Scan_XXX routine, that is expecting ASCII or UTF-8 source.
// (Many TO-XXX conversions from STRING re-use that scanner logic.)
// 
// Returns a temporary string and sets the length field.
// 
// If `allow_utf8`, the constructed result is converted to UTF8.
// 
// Checks or converts it:
// 
//     1. it is byte string (not unicode)
//     2. if unicode, copy and return as temp byte string
//     3. it's actual content (less space, newlines) <= max len
//     4. it does not contain other values ("123 456")
//     5. it's not empty or only whitespace
//
REBYTE *Temp_Byte_Chars_May_Fail(
    const REBVAL *val,
    REBINT max_len,
    REBCNT *length,
    REBOOL allow_utf8
) {
    REBCNT tail = VAL_LEN_HEAD(val);
    REBCNT index = VAL_INDEX(val);
    REBCNT len;
    REBUNI c;
    REBYTE *bp;
    REBSER *src = VAL_SERIES(val);

    if (index > tail) fail (Error(RE_PAST_END));

    Resize_Series(BYTE_BUF, max_len+1);
    bp = BIN_HEAD(BYTE_BUF);

    // Skip leading whitespace:
    for (; index < tail; index++) {
        c = GET_ANY_CHAR(src, index);
        if (!IS_SPACE(c)) break;
    }

    // Copy chars that are valid:
    for (; index < tail; index++) {
        c = GET_ANY_CHAR(src, index);
        if (c >= 0x80) {
            if (!allow_utf8) fail (Error(RE_INVALID_CHARS));

            len = Encode_UTF8_Char(bp, c);
            max_len -= len;
            bp += len;
        }
        else if (!IS_SPACE(c)) {
            *bp++ = (REBYTE)c;
            max_len--;
        }
        else break;
        if (max_len < 0)
            fail (Error(RE_TOO_LONG));
    }

    // Rest better be just spaces:
    for (; index < tail; index++) {
        c = GET_ANY_CHAR(src, index);
        if (!IS_SPACE(c)) fail (Error(RE_INVALID_CHARS));
    }

    *bp = '\0';

    len = bp - BIN_HEAD(BYTE_BUF);
    if (len == 0) fail (Error(RE_TOO_SHORT));

    if (length) *length = len;

    return BIN_HEAD(BYTE_BUF);
}
コード例 #6
0
ファイル: u-compress.c プロジェクト: mbk/ren-c
*/  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;
}
コード例 #7
0
ファイル: s-ops.c プロジェクト: rhencke/rebol
//
//  Enline_Bytes: C
//
void Enline_Bytes(REBSER *ser, REBCNT idx, REBCNT len)
{
    REBCNT cnt = 0;
    REBYTE *bp;
    REBYTE c = 0;
    REBCNT tail;

    // Calculate the size difference by counting the number of LF's
    // that have no CR's in front of them.
    bp = BIN_AT(ser, idx);
    for (; len > 0; len--) {
        if (*bp == LF && c != CR) cnt++;
        c = *bp++;
    }
    if (cnt == 0) return;

    // Extend series:
    len = SER_LEN(ser); // before expansion
    EXPAND_SERIES_TAIL(ser, cnt);
    tail = SER_LEN(ser); // after expansion
    bp = BIN_HEAD(ser); // expand may change it

    // Add missing CRs:
    while (cnt > 0) {
        bp[tail--] = bp[len]; // Copy src to dst.
        if (bp[len] == LF && (len == 0 || bp[len - 1] != CR)) {
            bp[tail--] = CR;
            cnt--;
        }
        len--;
    }
}
コード例 #8
0
ファイル: s-make.c プロジェクト: asampal/ren-c
*/	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;
}
コード例 #9
0
ファイル: t-bitset.c プロジェクト: kealist/ren-c
*/	REBFLG Check_Bit(REBSER *bset, REBCNT c, REBFLG uncased)
/*
**		Check bit indicated. Returns TRUE if set.
**		If uncased is TRUE, try to match either upper or lower case.
**
***********************************************************************/
{
	REBCNT i, n = c;
	REBCNT tail = SERIES_TAIL(bset);
	REBFLG flag = 0;

	if (uncased) {
		if (n >= UNICODE_CASES) uncased = FALSE; // no need to check
		else n = LO_CASE(c);
	}

	// Check lowercase char:
retry:
	i = n >> 3;
	if (i < tail)
		flag = (0 != (BIN_HEAD(bset)[i] & (1 << (7 - ((n) & 7)))));

	// Check uppercase if needed:
	if (uncased && !flag) {
		n = UP_CASE(c);
		uncased = FALSE;
		goto retry;
	}

	return (BITS_NOT(bset)) ? !flag : flag;
}
コード例 #10
0
ファイル: t-bitset.c プロジェクト: kjanz1899/ren-c
//
//  Check_Bit: C
// 
// Check bit indicated. Returns TRUE if set.
// If uncased is TRUE, try to match either upper or lower case.
//
REBOOL Check_Bit(REBSER *bset, REBCNT c, REBOOL uncased)
{
    REBCNT i, n = c;
    REBCNT tail = SER_LEN(bset);
    REBOOL flag = FALSE;

    if (uncased) {
        if (n >= UNICODE_CASES) uncased = FALSE; // no need to check
        else n = LO_CASE(c);
    }

    // Check lowercase char:
retry:
    i = n >> 3;
    if (i < tail)
        flag = LOGICAL(BIN_HEAD(bset)[i] & (1 << (7 - ((n) & 7))));

    // Check uppercase if needed:
    if (uncased && !flag) {
        n = UP_CASE(c);
        uncased = FALSE;
        goto retry;
    }

    return BITS_NOT(bset) ? NOT(flag) : flag;
}
コード例 #11
0
ファイル: p-file.c プロジェクト: mbk/ren-c
*/	static void Write_File_Port(REBREQ *file, REBVAL *data, REBCNT len, REBCNT args)
/*
***********************************************************************/
{
	REBSER *ser;

	if (IS_BLOCK(data)) {
		// Form the values of the block
		// !! Could be made more efficient if we broke the FORM
		// into 32K chunks for writing.
		REB_MOLD mo;
		CLEARS(&mo);
		Reset_Mold(&mo);
		if (args & AM_WRITE_LINES) {
			mo.opts = 1 << MOPT_LINES;
		}
		Mold_Value(&mo, data, 0);
		Set_String(data, mo.series); // fall into next section
		len = SERIES_TAIL(mo.series);
	}

	// Auto convert string to UTF-8
	if (IS_STRING(data)) {
		ser = Encode_UTF8_Value(data, len, ENCF_OS_CRLF);
		file->common.data = ser? BIN_HEAD(ser) : VAL_BIN_DATA(data); // No encoding may be needed
		len = SERIES_TAIL(ser);
	}
	else {
		file->common.data = VAL_BIN_DATA(data);
	}
	file->length = len;
	OS_DO_DEVICE(file, RDC_WRITE);
}
コード例 #12
0
ファイル: f-enbase.c プロジェクト: rgchris/ren-c
//
//  Decode_Base2: C
//
static REBSER *Decode_Base2(const REBYTE **src, REBCNT len, REBYTE delim)
{
    REBYTE *bp;
    const REBYTE *cp;
    REBCNT count = 0;
    REBCNT accum = 0;
    REBYTE lex;
    REBSER *ser;

    ser = Make_Binary(len >> 3);
    bp = BIN_HEAD(ser);
    cp = *src;

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

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

        lex = Lex_Map[*cp];

        if (lex >= LEX_NUMBER) {

            if (*cp == '0') accum *= 2;
            else if (*cp == '1') accum = (accum * 2) + 1;
            else goto err;

            if (count++ >= 7) {
                *bp++ = cast(REBYTE, accum);
                count = 0;
                accum = 0;
            }
        }
        else if (!*cp || lex > LEX_DELIMIT_RETURN) goto err;
    }
    if (count) goto err; // improper modulus

    *bp = 0;
    SET_SERIES_LEN(ser, bp - BIN_HEAD(ser));
    ASSERT_SERIES_TERM(ser);
    return ser;

err:
    Free_Series(ser);
    *src = cp;
    return 0;
}
コード例 #13
0
ファイル: t-string.c プロジェクト: RamchandraApte/rebol
*/	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;
}
コード例 #14
0
ファイル: u-compress.c プロジェクト: 51weekend/r3
*/  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;
}
コード例 #15
0
ファイル: f-enbase.c プロジェクト: rgchris/ren-c
//
//  Decode_Base16: C
//
static REBSER *Decode_Base16(const REBYTE **src, REBCNT len, REBYTE delim)
{
    REBYTE *bp;
    const REBYTE *cp;
    REBCNT count = 0;
    REBCNT accum = 0;
    REBYTE lex;
    REBINT val;
    REBSER *ser;

    ser = Make_Binary(len / 2);
    bp = BIN_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++ = cast(REBYTE, accum);
        }
        else if (!*cp || lex > LEX_DELIMIT_RETURN) goto err;
    }
    if (count & 1) goto err; // improper modulus

    *bp = 0;
    SET_SERIES_LEN(ser, bp - BIN_HEAD(ser));
    ASSERT_SERIES_TERM(ser);
    return ser;

err:
    Free_Series(ser);
    *src = cp;
    return 0;
}
コード例 #16
0
ファイル: s-ops.c プロジェクト: hostilefork/rebol
//
//  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;
}
コード例 #17
0
ファイル: s-ops.c プロジェクト: asampal/ren-c
*/  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;
}
コード例 #18
0
ファイル: s-unicode.c プロジェクト: Oldes/r3
*/  int Encode_UTF8_Line(REBSER *dst, REBSER *src, REBCNT idx)
/*
**		Encode a unicode source buffer into a binary line of UTF8.
**		Include the LF terminator in the result.
**		Return the length of the line buffer.
**
***********************************************************************/
{
	REBUNI *up = UNI_HEAD(src);
	REBCNT len  = SERIES_TAIL(src);
	REBCNT tail;
	REBUNI c;
	REBINT n;
	REBYTE buf[8];

	tail = RESET_TAIL(dst);

	while (idx < len) {
		if ((c = up[idx]) < 0x80) {
			EXPAND_SERIES_TAIL(dst, 1);
			BIN_HEAD(dst)[tail++] = (REBYTE)c;
		}
		else {
			n = Encode_UTF8_Char(buf, c);
			EXPAND_SERIES_TAIL(dst, n);
			memcpy(BIN_SKIP(dst, tail), buf, n);
			tail += n;
		}
		idx++;
		if (c == LF) break;
	}

	BIN_HEAD(dst)[tail] = 0;
	SERIES_TAIL(dst) = tail;
	return idx;
}
コード例 #19
0
ファイル: t-string.c プロジェクト: RamchandraApte/rebol
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;
}
コード例 #20
0
ファイル: s-ops.c プロジェクト: rhencke/rebol
//
//  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;
}
コード例 #21
0
ファイル: s-ops.c プロジェクト: asampal/ren-c
*/	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;
}
コード例 #22
0
ファイル: u-parse.c プロジェクト: Tectorum/rebol
*/	REBSER *Parse_Lines(REBSER *src)
/*
**		Convert a string buffer to a block of strings.
**		Note that the string must already be converted
**		to REBOL LF format (no CRs).
**
***********************************************************************/
{
	REBSER	*blk;
	REBUNI c;
	REBCNT i;
	REBCNT s;
	REBVAL *val;
	REBOOL uni = !BYTE_SIZE(src);
	REBYTE *bp = BIN_HEAD(src);
	REBUNI *up = UNI_HEAD(src);

	blk = BUF_EMIT;
	RESET_SERIES(blk);

	// Scan string, looking for LF and CR terminators:
	for (i = s = 0; i < SERIES_TAIL(src); i++) {
		c = uni ? up[i] : bp[i];
		if (c == LF || c == CR) {
			val = Append_Value(blk);
			Set_String(val, Copy_String(src, s, i - s));
			VAL_SET_LINE(val);
			// Skip CRLF if found:
			if (c == CR && LF == uni ? up[i] : bp[i]) i++; 
			s = i;
		}
	}

	// Partial line (no linefeed):
	if (s + 1 != i) {
		val = Append_Value(blk);
		Set_String(val, Copy_String(src, s, i - s));
		VAL_SET_LINE(val);
	}

	return Copy_Block(blk, 0);
}
コード例 #23
0
ファイル: u-compress.c プロジェクト: mbk/ren-c
*/  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;
}
コード例 #24
0
ファイル: f-enbase.c プロジェクト: rgchris/ren-c
//
//  Decode_Base64: C
//
static REBSER *Decode_Base64(const REBYTE **src, REBCNT len, REBYTE delim)
{
    REBYTE *bp;
    const REBYTE *cp;
    REBCNT flip = 0;
    REBCNT 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 = BIN_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++ = cast(REBYTE, accum >> 16);
                    *bp++ = cast(REBYTE, accum >> 8);
                    *bp++ = cast(REBYTE, accum);
                    accum = 0;
                    flip = 0;
                }
            } else {
コード例 #25
0
ファイル: d-print.c プロジェクト: mbk/ren-c
*/	void Debug_Series(const REBSER *ser)
/*
***********************************************************************/
{
	REBINT disabled = GC_Disabled;
	GC_Disabled = 1;

	// This routine is also a little catalog of the outlying series
	// types in terms of sizing, just to know what they are.

	if (BYTE_SIZE(ser))
		Debug_Str(s_cast(BIN_HEAD(ser)));
	else if (IS_BLOCK_SERIES(ser)) {
		REBVAL value;
		// May not actually be a REB_BLOCK, but we put it in a value
		// container for now saying it is so we can output it.  Because
		// it may be a frame or otherwise, we use a raw VAL_SET
		VAL_SET(&value, REB_BLOCK);
		VAL_SERIES(&value) = m_cast(REBSER *, ser); // not actually modifying
		VAL_INDEX(&value) = 0;
		Debug_Fmt("%r", &value);
	} else if (SERIES_WIDE(ser) == sizeof(REBUNI))
コード例 #26
0
ファイル: s-unicode.c プロジェクト: Oldes/r3
*/	REBSER *Encode_UTF8_String(void *src, REBCNT len, REBFLG uni, 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 = BUF_FORM; // a shared buffer
	REBCNT size;
	REBYTE *cp;
	REBFLG ccr = GET_FLAG(opts, ENC_OPT_CRLF);

	if (uni) {
		REBUNI *up = (REBUNI*)src;

		size = Length_As_UTF8(up, len, TRUE, (REBOOL)ccr);
		cp = Reset_Buffer(ser, size + (GET_FLAG(opts, ENC_OPT_BOM) ? 3 : 0));
        UNUSED(cp);
		Encode_UTF8(Reset_Buffer(ser, size), size, up, &len, TRUE, ccr);
	}
	else {
		REBYTE *bp = (REBYTE*)src;

		if (Is_Not_ASCII(bp, len)) {
			size = Length_As_UTF8((REBUNI*)bp, len, FALSE, (REBOOL)ccr);
			cp = Reset_Buffer(ser, size + (GET_FLAG(opts, ENC_OPT_BOM) ? 3 : 0));
			Encode_UTF8(cp, size, bp, &len, FALSE, ccr);
		}
		else if (GET_FLAG(opts, ENC_OPT_NO_COPY)) return 0;
		else return Copy_Bytes(bp, len);
	}

	SERIES_TAIL(ser) = len;
	STR_TERM(ser);

	return Copy_Bytes(BIN_HEAD(ser), len);
}
コード例 #27
0
ファイル: d-print.c プロジェクト: kealist/ren-c
*/	void Debug_Series(const REBSER *ser)
/*
***********************************************************************/
{
	REBINT disabled = GC_Disabled;
	GC_Disabled = 1;

	// This routine is also a little catalog of the outlying series
	// types in terms of sizing, just to know what they are.

	if (BYTE_SIZE(ser))
		Debug_Str(s_cast(BIN_HEAD(ser)));
	else if (Is_Array_Series(ser)) {
		REBVAL value;
		// May not actually be a REB_BLOCK, but we put it in a value
		// container for now saying it is so we can output it.  It may be
		// a frame and we may not want to Manage_Series here, so we use a
		// raw VAL_SET instead of Val_Init_Block
		VAL_SET(&value, REB_BLOCK);
		VAL_SERIES(&value) = m_cast(REBSER *, ser); // not actually modifying
		VAL_INDEX(&value) = 0;
		Debug_Fmt("%r", &value);
	} else if (SERIES_WIDE(ser) == sizeof(REBUNI))
コード例 #28
0
ファイル: t-string.c プロジェクト: rgchris/ren-c
static REBSER *Make_Binary_BE64(const REBVAL *arg)
{
    REBSER *ser = Make_Binary(9);
    REBI64 n;
    REBINT count;
    REBYTE *bp = BIN_HEAD(ser);

    if (IS_INTEGER(arg)) {
        n = VAL_INT64(arg);
    }
    else {
        assert(IS_DECIMAL(arg));
        n = VAL_DECIMAL_BITS(arg);
    }

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

    return ser;
}
コード例 #29
0
ファイル: m-series.c プロジェクト: kealist/ren-c
*/  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;
}
コード例 #30
0
ファイル: t-string.c プロジェクト: RamchandraApte/rebol
static REBSER *make_binary(REBVAL *arg, REBOOL make)
{
	REBSER *ser;

	// MAKE BINARY! 123
	switch (VAL_TYPE(arg)) {
	case REB_INTEGER:
	case REB_DECIMAL:
		if (make) ser = Make_Binary(Int32s(arg, 0));
		else ser = Make_Binary_BE64(arg);
		break;

	// MAKE/TO BINARY! BINARY!
	case REB_BINARY:
		ser = Copy_Bytes(VAL_BIN_DATA(arg), VAL_LEN(arg));
		break;

	// MAKE/TO BINARY! <any-string>
	case REB_STRING:
	case REB_FILE:
	case REB_EMAIL:
	case REB_URL:
	case REB_TAG:
//	case REB_ISSUE:
		ser = Encode_UTF8_Value(arg, VAL_LEN(arg), 0);
		break;

	case REB_BLOCK:
		ser = Join_Binary(arg);
		break;

	// MAKE/TO BINARY! <tuple!>
	case REB_TUPLE:
		ser = Copy_Bytes(VAL_TUPLE(arg), VAL_TUPLE_LEN(arg));
		break;

	// MAKE/TO BINARY! <char!>
	case REB_CHAR:
		ser = Make_Binary(6);
		ser->tail = Encode_UTF8_Char(BIN_HEAD(ser), VAL_CHAR(arg));
		break;

	// MAKE/TO BINARY! <bitset!>
	case REB_BITSET:
		ser = Copy_Bytes(VAL_BIN(arg), VAL_TAIL(arg));
		break;

	// MAKE/TO BINARY! <image!>
	case REB_IMAGE:
	  	ser = Make_Image_Binary(arg);
		break;

	case REB_MONEY:
		ser = Make_Binary(12);
		ser->tail = 12;
		deci_to_binary(ser->data, VAL_DECI(arg));
		ser->data[12] = 0;
		break;

	default:
		ser = 0;
	}

	return ser;
}