move escape

This commit is contained in:
blueloveTH 2024-06-11 12:25:04 +08:00
parent 3e64b3b742
commit f0ec979815
5 changed files with 69 additions and 43 deletions

View File

@ -35,6 +35,9 @@ pkpy_Str pkpy_Str__substr(const pkpy_Str* self, int start);
pkpy_Str pkpy_Str__substr2(const pkpy_Str* self, int start, int size); pkpy_Str pkpy_Str__substr2(const pkpy_Str* self, int start, int size);
pkpy_Str pkpy_Str__lower(const pkpy_Str* self); pkpy_Str pkpy_Str__lower(const pkpy_Str* self);
pkpy_Str pkpy_Str__upper(const pkpy_Str* self); pkpy_Str pkpy_Str__upper(const pkpy_Str* self);
pkpy_Str pkpy_Str__escape(const pkpy_Str* self, char quote);
// pkpy_Str pkpy_Str__strip(const pkpy_Str* self, bool left, bool right);
// pkpy_Str pkpy_Str__strip2(const pkpy_Str* self, bool left, bool right, const pkpy_Str* chars);
pkpy_Str pkpy_Str__replace(const pkpy_Str* self, char old, char new_); pkpy_Str pkpy_Str__replace(const pkpy_Str* self, char old, char new_);
pkpy_Str pkpy_Str__replace2(const pkpy_Str* self, const pkpy_Str* old, const pkpy_Str* new_); pkpy_Str pkpy_Str__replace2(const pkpy_Str* self, const pkpy_Str* old, const pkpy_Str* new_);
pkpy_Str pkpy_Str__u8_getitem(const pkpy_Str* self, int i); pkpy_Str pkpy_Str__u8_getitem(const pkpy_Str* self, int i);

View File

@ -177,8 +177,10 @@ struct Str: pkpy_Str {
return pkpy_Str__replace2(this, &old, &new_); return pkpy_Str__replace2(this, &old, &new_);
} }
Str escape(bool single_quote = true) const; Str escape(char quote='\'') const{
void escape_(SStream& ss, bool single_quote = true) const; return pkpy_Str__escape(this, quote);
}
vector<std::string_view> split(const Str& sep) const; vector<std::string_view> split(const Str& sep) const;
vector<std::string_view> split(char sep) const; vector<std::string_view> split(char sep) const;

View File

@ -118,6 +118,62 @@ pkpy_Str pkpy_Str__upper(const pkpy_Str *self){
return retval; return retval;
} }
pkpy_Str pkpy_Str__escape(const pkpy_Str* self, char quote){
assert(quote == '"' || quote == '\'');
c11_vector buffer;
c11_vector__ctor(&buffer, sizeof(char));
c11_vector__reserve(&buffer, self->size);
c11_vector__push(char, &buffer, quote);
const char* data = pkpy_Str__data(self);
for(int i = 0; i < self->size; i++) {
char c = data[i];
switch(c) {
case '"': case '\'':
if(c == quote) c11_vector__push(char, &buffer, '\\');
c11_vector__push(char, &buffer, c);
break;
case '\\':
c11_vector__push(char, &buffer, '\\');
c11_vector__push(char, &buffer, '\\');
break;
case '\n':
c11_vector__push(char, &buffer, '\\');
c11_vector__push(char, &buffer, 'n');
break;
case '\r':
c11_vector__push(char, &buffer, '\\');
c11_vector__push(char, &buffer, 'r');
break;
case '\t':
c11_vector__push(char, &buffer, '\\');
c11_vector__push(char, &buffer, 't');
break;
case '\b':
c11_vector__push(char, &buffer, '\\');
c11_vector__push(char, &buffer, 'b');
break;
default:
if('\x00' <= c && c <= '\x1f') {
c11_vector__push(char, &buffer, '\\');
c11_vector__push(char, &buffer, 'x');
c11_vector__push(char, &buffer, PK_HEX_TABLE[c >> 4]);
c11_vector__push(char, &buffer, PK_HEX_TABLE[c & 0xf]);
} else {
c11_vector__push(char, &buffer, c);
}
}
}
c11_vector__push(char, &buffer, quote);
c11_vector__push(char, &buffer, '\0');
pkpy_Str retval = {
.size = buffer.count - 1,
.is_ascii = self->is_ascii,
.is_sso = false,
._ptr = (char*)buffer.data,
};
return retval;
}
pkpy_Str pkpy_Str__replace(const pkpy_Str *self, char old, char new_){ pkpy_Str pkpy_Str__replace(const pkpy_Str *self, char old, char new_){
pkpy_Str retval = pkpy_Str__copy(self); pkpy_Str retval = pkpy_Str__copy(self);
char* p = (char*)pkpy_Str__data(&retval); char* p = (char*)pkpy_Str__data(&retval);
@ -143,8 +199,9 @@ pkpy_Str pkpy_Str__replace2(const pkpy_Str *self, const pkpy_Str *old, const pkp
pkpy_Str tmp = pkpy_Str__substr2(self, start, self->size - start); pkpy_Str tmp = pkpy_Str__substr2(self, start, self->size - start);
c11_vector__extend(char, &buffer, pkpy_Str__data(&tmp), tmp.size); c11_vector__extend(char, &buffer, pkpy_Str__data(&tmp), tmp.size);
pkpy_Str__dtor(&tmp); pkpy_Str__dtor(&tmp);
c11_vector__push(char, &buffer, '\0');
pkpy_Str retval = { pkpy_Str retval = {
.size = buffer.count, .size = buffer.count - 1,
.is_ascii = self->is_ascii && old->is_ascii && new_->is_ascii, .is_ascii = self->is_ascii && old->is_ascii && new_->is_ascii,
.is_sso = false, .is_sso = false,
._ptr = (char*)buffer.data, ._ptr = (char*)buffer.data,
@ -189,8 +246,9 @@ pkpy_Str pkpy_Str__u8_slice(const pkpy_Str *self, int start, int stop, int step)
pkpy_Str__dtor(&unicode); pkpy_Str__dtor(&unicode);
} }
} }
c11_vector__push(char, &buffer, '\0');
pkpy_Str retval = { pkpy_Str retval = {
.size = buffer.count, .size = buffer.count - 1,
.is_ascii = self->is_ascii, .is_ascii = self->is_ascii,
.is_sso = false, .is_sso = false,
._ptr = (char*)buffer.data, ._ptr = (char*)buffer.data,

View File

@ -56,43 +56,6 @@ Str Str::strip(bool left, bool right) const {
} }
} }
Str Str::escape(bool single_quote) const {
SStream ss;
escape_(ss, single_quote);
return ss.str();
}
void Str::escape_(SStream& ss, bool single_quote) const {
ss << (single_quote ? '\'' : '"');
for(int i = 0; i < size; i++) {
char c = this->operator[] (i);
switch(c) {
case '"':
if(!single_quote) ss << '\\';
ss << '"';
break;
case '\'':
if(single_quote) ss << '\\';
ss << '\'';
break;
case '\\': ss << '\\' << '\\'; break;
case '\n': ss << "\\n"; break;
case '\r': ss << "\\r"; break;
case '\t': ss << "\\t"; break;
case '\b': ss << "\\b"; break;
default:
if('\x00' <= c && c <= '\x1f') {
ss << "\\x"; // << std::hex << std::setw(2) << std::setfill('0') << (int)c;
ss << PK_HEX_TABLE[c >> 4];
ss << PK_HEX_TABLE[c & 0xf];
} else {
ss << c;
}
}
}
ss << (single_quote ? '\'' : '"');
}
vector<std::string_view> Str::split(const Str& sep) const { vector<std::string_view> Str::split(const Str& sep) const {
vector<std::string_view> result; vector<std::string_view> result;
std::string_view tmp; std::string_view tmp;

View File

@ -38,7 +38,7 @@ struct JsonSerializer {
if(!is_type(k, VM::tp_str)) { if(!is_type(k, VM::tp_str)) {
vm->TypeError(_S("json keys must be string, got ", _type_name(vm, vm->_tp(k)))); vm->TypeError(_S("json keys must be string, got ", _type_name(vm, vm->_tp(k))));
} }
ss << _CAST(Str&, k).escape(false) << ": "; ss << _CAST(Str&, k).escape('"') << ": ";
write_object(v); write_object(v);
}); });
ss << '}'; ss << '}';
@ -57,7 +57,7 @@ struct JsonSerializer {
} else if(obj_t == vm->tp_bool) { } else if(obj_t == vm->tp_bool) {
ss << (obj == vm->True ? "true" : "false"); ss << (obj == vm->True ? "true" : "false");
} else if(obj_t == vm->tp_str) { } else if(obj_t == vm->tp_str) {
_CAST(Str&, obj).escape_(ss, false); ss << _CAST(Str&, obj).escape('"');
} else if(obj_t == vm->tp_list) { } else if(obj_t == vm->tp_list) {
write_array<List>(_CAST(List&, obj)); write_array<List>(_CAST(List&, obj));
} else if(obj_t == vm->tp_tuple) { } else if(obj_t == vm->tp_tuple) {