// // 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--; } }
// // Cloak: C // // Simple data scrambler. Quality depends on the key length. // Result is made in place (data string). // // The key (kp) is passed as a REBVAL or REBYTE (when klen is !0). // REBOOL Cloak(REBOOL decode, REBYTE *cp, REBCNT dlen, REBYTE *kp, REBCNT klen, REBOOL as_is) { REBCNT i, n; REBYTE src[20]; REBYTE dst[20]; if (dlen == 0) return TRUE; // Decode KEY as VALUE field (binary, string, or integer) if (klen == 0) { REBVAL *val = (REBVAL*)kp; REBSER *ser; switch (VAL_TYPE(val)) { case REB_BINARY: kp = VAL_BIN_AT(val); klen = VAL_LEN_AT(val); break; case REB_STRING: ser = Temp_Bin_Str_Managed(val, &i, &klen); kp = BIN_AT(ser, i); break; case REB_INTEGER: INT_TO_STR(VAL_INT64(val), dst); klen = LEN_BYTES(dst); as_is = FALSE; break; } if (klen == 0) return FALSE; } if (!as_is) { for (i = 0; i < 20; i++) src[i] = kp[i % klen]; SHA1(src, 20, dst); klen = 20; kp = dst; } if (decode) for (i = dlen-1; i > 0; i--) cp[i] ^= cp[i-1] ^ kp[i % klen]; // Change starting byte based all other bytes. n = 0xa5; for (i = 1; i < dlen; i++) n += cp[i]; cp[0] ^= (REBYTE)n; if (!decode) for (i = 1; i < dlen; i++) cp[i] ^= cp[i-1] ^ kp[i % klen]; return TRUE; }
// // 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); }
// // Trim_Tail: C // // Used to trim off hanging spaces during FORM and MOLD. // void Trim_Tail(REB_MOLD *mo, REBYTE ascii) { assert(ascii < 0x80); // more work needed for multi-byte characters REBCNT len = STR_LEN(mo->series); REBSIZ size = STR_SIZE(mo->series); for (; size > 0; --size, --len) { REBYTE b = *BIN_AT(SER(mo->series), size - 1); if (b != ascii) break; } TERM_STR_LEN_SIZE(mo->series, len, size); }
// // RL_Get_String: C // // Obtain a pointer into a string (bytes or unicode). // // Returns: // The length and type of string. When len > 0, string is unicode. // When len < 0, string is bytes. // Arguments: // series - string series pointer // index - index from beginning (zero-based) // str - pointer to first character // Notes: // If the len is less than zero, then the string is optimized to // codepoints (chars) 255 or less for ASCII and LATIN-1 charsets. // Strings are allowed to move in memory. Therefore, you will want // to make a copy of the string if needed. // RL_API int RL_Get_String(REBSER *series, u32 index, void **str) { // ret: len or -len int len; if (index >= SER_LEN(series)) len = 0; else len = SER_LEN(series) - index; if (BYTE_SIZE(series)) { *str = BIN_AT(series, index); len = -len; } else { *str = UNI_AT(series, index); } return len; }