String* Str_Trim_IMP(String *self) { StringIterator *top = STACK_ITER(self, 0); StrIter_Skip_Whitespace(top); StringIterator *tail = NULL; if (top->byte_offset < self->size) { tail = STACK_ITER(self, self->size); StrIter_Skip_Whitespace_Back(tail); } return StrIter_crop((StringIterator*)top, (StringIterator*)tail); }
int32_t Str_Code_Point_From_IMP(String *self, size_t tick) { if (tick == 0) { return STR_OOB; } StringIterator *iter = STACK_ITER(self, self->size); StrIter_Recede(iter, tick - 1); return StrIter_Prev(iter); }
int64_t Str_BaseX_To_I64_IMP(String *self, uint32_t base) { StringIterator *iter = STACK_ITER(self, 0); int64_t retval = 0; bool is_negative = false; int32_t code_point = StrIter_Next(iter); // Advance past minus sign. if (code_point == '-') { code_point = StrIter_Next(iter); is_negative = true; } // Accumulate. while (code_point != STR_OOB) { if (code_point <= 127 && isalnum(code_point)) { int32_t addend = isdigit(code_point) ? code_point - '0' : tolower(code_point) - 'a' + 10; if (addend >= (int32_t)base) { break; } retval *= base; retval += addend; } else { break; } code_point = StrIter_Next(iter); } // Apply minus sign. if (is_negative) { retval = 0 - retval; } return retval; }
String* Str_SubString_IMP(String *self, size_t offset, size_t len) { StringIterator *iter = STACK_ITER(self, 0); StrIter_Advance(iter, offset); size_t start_offset = iter->byte_offset; StrIter_Advance(iter, len); size_t size = iter->byte_offset - start_offset; return S_new_substring(self, start_offset, size); }
size_t Str_Hash_Sum_IMP(String *self) { size_t hashvalue = 5381; StringIterator *iter = STACK_ITER(self, 0); const StrIter_Next_t next = METHOD_PTR(STRINGITERATOR, CFISH_StrIter_Next); int32_t code_point; while (STR_OOB != (code_point = next(iter))) { hashvalue = ((hashvalue << 5) + hashvalue) ^ (size_t)code_point; } return hashvalue; }
/* * Pop an elem off the stack and deallocate its memory. Returns the integer * offset into the history list of the popped frame. Returns RSH_ERR if there * is an error (empty stack). */ int rsh_stack_pop(struct rsh_history_stack *stack){ int frame_data; struct rsh_history_frame *frame; if ( ! stack->top ) return RSH_ERR; frame = stack->top; frame_data = stack->top->text; STACK_ITER(stack->top); free(frame); return frame_data; }
/* * Clean a stack up. */ void rsh_stack_clean(struct rsh_history_stack *stack){ struct rsh_history_frame *frame; struct rsh_history_frame *tmp; if ( ! stack->top ) return; frame = stack->top; while ( frame != NULL){ tmp = frame; STACK_ITER(frame); free(tmp); } stack->top = NULL; return; }
int32_t Str_Code_Point_At_IMP(String *self, size_t tick) { StringIterator *iter = STACK_ITER(self, 0); StrIter_Advance(iter, tick); return StrIter_Next(iter); }
size_t Str_Length_IMP(String *self) { StringIterator *iter = STACK_ITER(self, 0); return StrIter_Advance(iter, SIZE_MAX); }
String* Str_Trim_Tail_IMP(String *self) { StringIterator *tail = STACK_ITER(self, self->size); StrIter_Skip_Whitespace_Back(tail); return StrIter_crop(NULL, (StringIterator*)tail); }
String* Str_Trim_Top_IMP(String *self) { StringIterator *top = STACK_ITER(self, 0); StrIter_Skip_Whitespace(top); return StrIter_crop((StringIterator*)top, NULL); }