Exemple #1
0
//
//  Val_Init_Series_Index_Core: C
// 
// Common function.
//
void Val_Init_Series_Index_Core(
    REBVAL *value,
    enum Reb_Kind type,
    REBSER *series,
    REBCNT index
) {
    assert(series);
    ENSURE_SERIES_MANAGED(series);

    if (type != REB_IMAGE && type != REB_VECTOR) {
        // Code in various places seemed to have different opinions of
        // whether a BINARY needed to be zero terminated.  It doesn't
        // make a lot of sense to zero terminate a binary unless it
        // simplifies the code assumptions somehow--it's in the class
        // "ANY_BINSTR()" so that suggests perhaps it has a bit more
        // obligation to conform.  Also, the original Make_Binary comment
        // from the open source release read:
        //
        //     Make a binary string series. For byte, C, and UTF8 strings.
        //     Add 1 extra for terminator.
        //
        // Until that is consciously overturned, check the REB_BINARY too

        ASSERT_SERIES_TERM(series); // doesn't apply to image/vector
    }

    VAL_RESET_HEADER(value, type);
    INIT_VAL_SERIES(value, series);
    VAL_INDEX(value) = index;
}
Exemple #2
0
//
//  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;
}
Exemple #3
0
//
//  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;
}