最近在寫一個關于用HTTP控制storm的的UI功能,已經實作完成,采用在nginx裡面加入對應的子產品調用來實作,子產品中調用一個動态加載的SO,這個SO用THRIFT和zookeeper client實作對storm的控制和資訊的存儲固化。開始我使用了std::string來做字元串處理。後來發現string實在太多未知的對象建構和記憶體配置設定,加上我想把so改用純C的實作。std::string自然就需要被替換。在網絡上找了很久相關C語言的string 實作,沒有。于是參照《C語言接口與實作》裡字元串操作的實作接口,是實作了一個便捷的C字元串處理的接口,接口如下:
typedef char* cstring;
/*init and destory*/
cstring cstr_init();
cstring cstr_initchar(const char* v, size_t v_size);
void cstr_destroy(cstring s);
/*get string context*/
char* cstr_value(cstring s);
/*cstring size*/
size_t cstr_size(cstring s);
uint8_t cstr_empty(cstring s);
/*update size by '\0'*/
void cstr_update(cstring s);
/*cstring cat*/
cstring cstr_cat(cstring dst, cstring src);
cstring cstr_catchar(cstring dst, const char* v, size_t v_size);
/*cstring copy*/
cstring cstr_cpy(cstring dst, cstring src);
cstring cstr_cpychar(cstring dst, const char* v, size_t v_size);
/*cstring cmp*/
int32_t cstr_cmp(cstring s1, cstring s2);
int32_t cstr_cmpchar(cstring s, const char* v, size_t v_size);
/*cstring lower upper*/
void cstr_tolower(cstring s);
void cstr_toupper(cstring s);
/*del cset from cstring*/
cstring cstr_trim(cstring s, const char* cset);
void cstr_clear(cstring s);
/*sprintf format*/
cstring str_printf(cstring s, const char* fmt, ...);
/*number to cstring*/
cstring itocstr(cstring s, int64_t v);
/*cstring to number*/
int64_t cstrtoi(cstring s);
/*cstring dump*/
void cstr_dump(cstring s);
#endif
其中cstring是一個字元串句柄,指向具體的字元串内容,cstring的前面還有8個位元組,前面4個位元組表示字元串的長度,後面4個位元組表示緩沖區還剩餘的長度。其結構如下:
/*define string struct*/
typedef struct string_s{
int32_t len;<span style="white-space:pre"> </span>/*字元串的長度*/
int32_t free;<span style="white-space:pre"> </span>/*緩沖區還剩餘的長度*/
char buf[];<span style="white-space:pre"> </span>/*cstring的指針位址*/
}string_t;
函數cstr_init()會為string_t開辟一個大于其sizeof大小的記憶體塊,前面8位元組用于struct結構資訊的存儲,後面用于字元串内容存儲。在調用類似cstr_cat函數如果free的記憶體不夠時,接口會自動配置設定一個更大的記憶體塊來代替。這樣做的目的是為了調用者不用關心記憶體溢出的問題。
關于這個接口的全部代碼實作,已經放到gti hub上,可以做為C的字元串操作的參考。git位址https://github.com/yuanrongxi/c_string