mirror of
https://github.com/clockworkpi/Menu.git
synced 2026-03-22 20:02:41 +01:00
first commit
This commit is contained in:
208
60_Utils/02_Bean/beans/std/strings.bean
Executable file
208
60_Utils/02_Bean/beans/std/strings.bean
Executable file
@@ -0,0 +1,208 @@
|
||||
|
||||
class std+, strings {
|
||||
|
||||
private import rt::c;
|
||||
|
||||
struct strings {
|
||||
mem dmem;
|
||||
offsets vector<uint32>;
|
||||
index size_t;
|
||||
}
|
||||
|
||||
func constructor() {
|
||||
constructor(this);
|
||||
this.mem.page = 0x2000;
|
||||
this.index = -1;
|
||||
}
|
||||
|
||||
func destructor() {
|
||||
destructor(this);
|
||||
}
|
||||
|
||||
func clear(free_mem bool = false) {
|
||||
if free_mem {
|
||||
this.mem->free();
|
||||
else
|
||||
this.mem.used = 0;
|
||||
}
|
||||
this.offsets->clear(free_mem);
|
||||
this.index = -1;
|
||||
}
|
||||
|
||||
func add(str. char, len size_t = 0) .char {
|
||||
var used size_t = this.mem.used;
|
||||
this.offsets->push_back(used);
|
||||
if !len;
|
||||
len = strlen(str);
|
||||
if len;
|
||||
this.mem->write(str, len);
|
||||
.this.mem->alloc_t<char>() = 0;
|
||||
return this.mem.ptr + used;
|
||||
}
|
||||
|
||||
func load_file(file_name. char, trim bool = true, ignore_blank bool = true) int {
|
||||
var stream void = fopen(file_name, "rb");
|
||||
if stream == null;
|
||||
return -1;
|
||||
defer fclose(stream);
|
||||
if fgetc(stream) ~= 0xef or
|
||||
fgetc(stream) ~= 0xbb or
|
||||
fgetc(stream) ~= 0xbf {
|
||||
if fseek(stream, 0, SEEK_SET) < 0;
|
||||
return -1;
|
||||
}
|
||||
var count size_t = this.offsets->count();
|
||||
var buf(0x2000) char;
|
||||
for ;; {
|
||||
if fgets(&buf, 0x2000, stream) == null;
|
||||
break;
|
||||
var line. char = &buf;
|
||||
var len size_t = strlen(line);
|
||||
if len and line[len - 1] == 10 {
|
||||
if len > 1 and line[len - 2] == 13 {
|
||||
len -= 2;
|
||||
else
|
||||
len -= 1;
|
||||
}
|
||||
line[len] = 0;
|
||||
}
|
||||
if trim {
|
||||
while isspace(.line);
|
||||
line += 1, len--;
|
||||
while len {
|
||||
if !isspace(line[len - 1]);
|
||||
break;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
if !len and ignore_blank;
|
||||
continue;
|
||||
this->add(line, len);
|
||||
}
|
||||
return this.offsets->count() - count;
|
||||
}
|
||||
|
||||
func split(str. char, del. char) uint {
|
||||
func = 1;
|
||||
var len size_t = strlen(del);
|
||||
var tmp. char;
|
||||
while (tmp = strstr(str, del)) ~= null;
|
||||
this->add(str, tmp - str), str = tmp + len, func++;
|
||||
this->add(str);
|
||||
}
|
||||
|
||||
inline count() size_t {
|
||||
return this.offsets->count();
|
||||
}
|
||||
|
||||
inline empty() bool {
|
||||
return this.offsets->count() == 0;
|
||||
}
|
||||
|
||||
inline item(index size_t) .char {
|
||||
return this.mem.ptr + .this.offsets->at(index);
|
||||
}
|
||||
|
||||
func next_item(loop bool = false) .char {
|
||||
var count size_t = this->count();
|
||||
if !count;
|
||||
return null;
|
||||
var index size_t = this.index;
|
||||
if index < count {
|
||||
func = this->item(index), this.index++;
|
||||
else
|
||||
this.index = 0;
|
||||
if index == -1 or loop {
|
||||
func = this->next_item();
|
||||
else
|
||||
func = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func prev_item() .char {
|
||||
var index size_t = this.index;
|
||||
if index == -1;
|
||||
return null;
|
||||
var count size_t = this->count();
|
||||
if !count;
|
||||
return null;
|
||||
if index and index < count {
|
||||
return this->item(index - 1);
|
||||
else
|
||||
return this->item(count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
func rollback() {
|
||||
var count size_t = this->count();
|
||||
if count {
|
||||
if this.index ~= -1 {
|
||||
if this.index and this.index < count {
|
||||
this.index--;
|
||||
else
|
||||
this.index = count - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
this.index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
func first_item() .char {
|
||||
if !this->count();
|
||||
return null;
|
||||
return this->item(0);
|
||||
}
|
||||
|
||||
func last_item() .char {
|
||||
var count size_t = this->count();
|
||||
if !count;
|
||||
return null;
|
||||
return this->item(count - 1);
|
||||
}
|
||||
|
||||
func rnd_item() .char {
|
||||
var count size_t = this->count();
|
||||
if !count;
|
||||
return null;
|
||||
return this->item(random<size_t>(count));
|
||||
}
|
||||
|
||||
func join(str. string, del. char = null) .char {
|
||||
forvar index size_t = 0, count size_t = this->count(); index < count; index++ {
|
||||
str->append(this->item(index));
|
||||
if del ~= null;
|
||||
str->append(del);
|
||||
}
|
||||
return str->ptr();
|
||||
}
|
||||
|
||||
func exists(str. char, index. size_t = null) bool {
|
||||
forvar i size_t = 0, c size_t = this->count(); i < c; i++ {
|
||||
if !strcmp(this->item(i), str) {
|
||||
if index ~= null;
|
||||
.index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
func existsi(str. char, index. size_t = null) bool {
|
||||
forvar i size_t = 0, c size_t = this->count(); i < c; i++ {
|
||||
if !strcasecmp(this->item(i), str) {
|
||||
if index ~= null;
|
||||
.index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// fixme
|
||||
inline remove(index size_t) bool {
|
||||
return this.offsets->erase(index);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user