static String* S_unescape(QueryParser *self, String *orig, CharBuf *buf) { StringIterator *iter = Str_Top(orig); int32_t code_point; UNUSED_VAR(self); CB_Set_Size(buf, 0); CB_Grow(buf, Str_Get_Size(orig) + 4); while (STRITER_DONE != (code_point = StrIter_Next(iter))) { if (code_point == '\\') { int32_t next_code_point = StrIter_Next(iter); if (next_code_point == ':' || next_code_point == '"' || next_code_point == '\\' ) { CB_Cat_Char(buf, next_code_point); } else { CB_Cat_Char(buf, code_point); if (next_code_point != STRITER_DONE) { CB_Cat_Char(buf, next_code_point); } } } else { CB_Cat_Char(buf, code_point); } } DECREF(iter); return CB_To_String(buf); }
Hash* Hash_deserialize(Hash *self, InStream *instream) { uint32_t size = InStream_Read_C32(instream); uint32_t num_charbufs = InStream_Read_C32(instream); uint32_t num_other = size - num_charbufs; CharBuf *key = num_charbufs ? CB_new(0) : NULL; Hash_init(self, size); // Read key-value pairs with CharBuf keys. while (num_charbufs--) { uint32_t len = InStream_Read_C32(instream); char *key_buf = CB_Grow(key, len); InStream_Read_Bytes(instream, key_buf, len); key_buf[len] = '\0'; CB_Set_Size(key, len); Hash_Store(self, (Obj*)key, THAW(instream)); } DECREF(key); // Read remaining key/value pairs. while (num_other--) { Obj *k = THAW(instream); Hash_Store(self, k, THAW(instream)); DECREF(k); } return self; }
Obj* TextSortCache_value(TextSortCache *self, int32_t ord, Obj *blank) { if (ord == self->null_ord) { return NULL; } InStream_Seek(self->ix_in, ord * sizeof(int64_t)); int64_t offset = InStream_Read_I64(self->ix_in); if (offset == NULL_SENTINEL) { return NULL; } else { uint32_t next_ord = ord + 1; int64_t next_offset; while (1) { InStream_Seek(self->ix_in, next_ord * sizeof(int64_t)); next_offset = InStream_Read_I64(self->ix_in); if (next_offset != NULL_SENTINEL) { break; } next_ord++; } // Read character data into CharBuf. CERTIFY(blank, CHARBUF); int64_t len = next_offset - offset; char *ptr = CB_Grow((CharBuf*)blank, (size_t)len); InStream_Seek(self->dat_in, offset); InStream_Read_Bytes(self->dat_in, ptr, (size_t)len); ptr[len] = '\0'; CB_Set_Size((CharBuf*)blank, (size_t)len); } return blank; }
void TextTermStepper_read_key_frame(TextTermStepper *self, InStream *instream) { const uint32_t text_len = InStream_Read_C32(instream); CharBuf *value; char *ptr; // Allocate space. if (self->value == NULL) { self->value = (Obj*)CB_new(text_len); } value = (CharBuf*)self->value; ptr = CB_Grow(value, text_len); // Set the value text. InStream_Read_Bytes(instream, ptr, text_len); CB_Set_Size(value, text_len); if (!StrHelp_utf8_valid(ptr, text_len)) { THROW(ERR, "Invalid UTF-8 sequence in '%o' at byte %i64", InStream_Get_Filename(instream), InStream_Tell(instream) - text_len); } // Null-terminate. ptr[text_len] = '\0'; }
void TextTermStepper_Read_Delta_IMP(TextTermStepper *self, InStream *instream) { TextTermStepperIVARS *const ivars = TextTermStepper_IVARS(self); const uint32_t text_overlap = InStream_Read_C32(instream); const uint32_t finish_chars_len = InStream_Read_C32(instream); const uint32_t total_text_len = text_overlap + finish_chars_len; // Allocate space. CharBuf *charbuf = (CharBuf*)ivars->value; char *ptr = CB_Grow(charbuf, total_text_len); // Set the value text. InStream_Read_Bytes(instream, ptr + text_overlap, finish_chars_len); CB_Set_Size(charbuf, total_text_len); if (!StrHelp_utf8_valid(ptr, total_text_len)) { THROW(ERR, "Invalid UTF-8 sequence in '%o' at byte %i64", InStream_Get_Filename(instream), InStream_Tell(instream) - finish_chars_len); } // Null-terminate. ptr[total_text_len] = '\0'; // Invalidate string. DECREF(ivars->string); ivars->string = NULL; }
static String* S_encode_entities(String *text, CharBuf *buf) { StringIterator *iter = Str_Top(text); size_t space = 0; const int MAX_ENTITY_BYTES = 9; // &#dddddd; // Scan first so that we only allocate once. int32_t code_point; while (STRITER_DONE != (code_point = StrIter_Next(iter))) { if (code_point > 127 || (!isgraph(code_point) && !isspace(code_point)) || code_point == '<' || code_point == '>' || code_point == '&' || code_point == '"' ) { space += MAX_ENTITY_BYTES; } else { space += 1; } } CB_Grow(buf, space); CB_Set_Size(buf, 0); DECREF(iter); iter = Str_Top(text); while (STRITER_DONE != (code_point = StrIter_Next(iter))) { if (code_point > 127 || (!isgraph(code_point) && !isspace(code_point)) ) { CB_catf(buf, "&#%u32;", code_point); } else if (code_point == '<') { CB_Cat_Trusted_Utf8(buf, "<", 4); } else if (code_point == '>') { CB_Cat_Trusted_Utf8(buf, ">", 4); } else if (code_point == '&') { CB_Cat_Trusted_Utf8(buf, "&", 5); } else if (code_point == '"') { CB_Cat_Trusted_Utf8(buf, """, 6); } else { CB_Cat_Char(buf, code_point); } } DECREF(iter); return CB_To_String(buf); }
static void S_vcat_mess(CharBuf *message, const char *file, int line, const char *func, const char *pattern, va_list args) { size_t guess_len = strlen(file) + func ? strlen(func) : 0 + strlen(pattern) + 30; CB_Grow(message, guess_len); CB_VCatF(message, pattern, args); if (func != NULL) CB_catf(message, " at %s:%i32 %s ", file, (i32_t)line, func); else CB_catf(message, " at %s:%i32", file, (i32_t)line); }
void StrHelp_add_indent(CharBuf *charbuf, size_t amount) { u32_t num_margins = 1; size_t new_size; char *limit = CBEND(charbuf); char *source = charbuf->ptr; char *dest; /* Add a margin for every newline. */ for ( ; source < limit; source++) { if (*source == '\n') num_margins++; } /* Make space for margins. */ new_size = CB_Get_Size(charbuf) + (num_margins * amount); CB_Grow(charbuf, new_size); source = CBEND(charbuf); CB_Set_Size(charbuf, new_size); dest = CBEND(charbuf); *dest-- = '\0'; source--; while (source >= charbuf->ptr) { if (*source == '\n') { int i = amount; while (i--) { *dest-- = ' '; } } *dest-- = *source--; } while (dest >= charbuf->ptr) { *dest-- = ' '; } }
static void S_grow(CharBuf *self, size_t size) { if (size >= self->cap) { CB_Grow(self, size); } }