// // 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; }
// // 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; }
// // 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; }