+string_t string_new(const char*text, int len)
+{
+ string_t s;
+ s.len = len;
+ s.str = text;
+ return s;
+}
+string_t string_new2(const char*text)
+{
+ string_t s;
+ if(text) {
+ s.len = strlen(text);
+ } else {
+ s.len = 0;
+ }
+ s.str = text;
+ return s;
+}
+string_t* string_new3(const char*text, int len)
+{
+ if(!text) {
+ string_t*s = malloc(sizeof(string_t));
+ s->len = 0;
+ s->str = 0;
+ return s;
+ } else {
+ string_t*s = malloc(sizeof(string_t)+len+1);
+ s->len = len;
+ s->str = (const char*)(s+1);
+ memcpy((char*)s->str, text, len);
+ ((char*)s->str)[len]=0;
+ return s;
+ }
+}
+string_t* string_new4(const char*text)
+{
+ int l = strlen(text);
+ return string_new3(text, l);
+}
+
+void string_free(string_t*s)
+{
+ if(!s)
+ return;
+ s->len = 0;
+ if((string_t*)(s->str) == s+1) {
+ s->str = 0;
+ rfx_free(s);
+ } else {
+ rfx_free((char*)(s->str));
+ s->str = 0;
+ rfx_free(s);
+ }
+}
+char* string_cstr(string_t*str)
+{
+ return strdup_n(str->str, str->len);
+}
+char* string_escape(string_t*str)
+{
+ int t;
+ int len = 0;
+ for(t=0;t<str->len;t++) {
+ if(str->str[t]<0x20)
+ len+=3;
+ else
+ len++;
+ }
+ char*s = malloc(len+1);
+ char*p=s;
+ for(t=0;t<str->len;t++) {
+ if(str->str[t]<0x20) {
+ *p++ ='\\';
+ unsigned char c = str->str[t];
+ *p++ = "0123456789abcdef"[c>>4];
+ *p++ = "0123456789abcdef"[c&0x0f];
+ } else {
+ *p++ = str->str[t];
+ }
+ }
+ *p++ = 0;
+ assert(p == &s[len+1]);
+ return s;
+}
+
+unsigned int crc32_add_byte(unsigned int checksum, unsigned char b)
+{
+ if(!crc32)
+ crc32_init();
+ return checksum>>8 ^ crc32[(b^checksum)&0xff];
+}
+unsigned int crc32_add_string(unsigned int checksum, const char*s)
+{
+ if(!s)
+ return checksum;
+ while(*s) {
+ checksum = crc32_add_byte(checksum, *s);
+ s++;
+ }
+ return checksum;
+}
+
+unsigned int string_hash(const string_t*str)
+{
+ int t;
+ unsigned int checksum = 0;
+ if(!crc32)
+ crc32_init();
+ for(t=0;t<str->len;t++) {
+ checksum = checksum>>8 ^ crc32[(str->str[t]^checksum)&0xff];
+ }
+ return checksum;
+}
+unsigned int string_hash2(const char*str)
+{
+ unsigned int checksum = 0;
+ const char*p = str;
+ if(!crc32)
+ crc32_init();
+ while(*p) {
+ checksum = checksum>>8 ^ crc32[(*p^checksum)&0xff];
+ p++;
+ }
+ return checksum;
+}
+unsigned int string_hash3(const char*str, int len)
+{
+ string_t s;
+ s.str = str;
+ s.len = len;
+ return string_hash(&s);
+}