mysql 字符串解析_MySQL 动态字符串处理详解
MySQL中,常常會看到一些關于動態字符串的處理,列如:DYNAMIC_STRING。
為了記錄動態字符串的實際長度,緩沖區的最大長度,以及每次字符串需要調整時,及時分配新的內存,以及調整長度。MySQL使用了DYNAMIC_STRING來保存動態字符串相關的信息:typedef?struct?st_dynamic_string
{char*str;size_tlength,?max_length,?alloc_increment;
}?DYNAMIC_STRING;
在這個結構體中,str存儲實際字符串的首地址,length記錄字符串的實際長度,max_length記錄字符串緩沖區最多可以存放多少字符,alloc_increment表示當字符串需要分配內存時,每次分配多少內存。
下面看看這個結構體的初始化過程:my_bool?init_dynamic_string(?DYNAMIC_STRING?*str,?const?char?*init_str,?size_t?init_alloc,?size_t?alloc_increment?){size_t?length;
DBUG_ENTER(?"init_dynamic_string"?);if?(?!alloc_increment?)
alloc_increment?=?128;
length?=?1;if?(?init_str?&&?(length?=?strlen(?init_str?)?+?1)?
init_alloc?=?(?(length?+?alloc_increment?-?1)?/?alloc_increment)?*?alloc_increment;if?(?!init_alloc?)
init_alloc?=?alloc_increment;if?(?!(str->str?=?(char?*)?my_malloc(?init_alloc,?MYF(?MY_WME?)?)?)?)
DBUG_RETURN(?TRUE?);
str->length?=?length?-?1;if?(?init_str?)memcpy(?str->str,?init_str,?length?);
str->max_length=?init_alloc;
str->alloc_increment=?alloc_increment;
DBUG_RETURN(?FALSE?);
}
從上述函數可以看到,初始化時,初始分配的字符串緩沖區大小init_alloc會根據需要初始的字符串來做判斷。在分配好該DYNAMIC_STRING空間之后,我們會根據緩沖區的大小,字符串的實際長度,以及alloc_increment來初始化:
length:字符串的實際長度
max_length:緩沖區的最大長度
alloc_increment:空間不夠時,下次分配內存的單元大小.
初始化這些內容之后,如果下次需要在該緩沖區添加更多字符,就可以根據這些值來判斷是否需要對該緩沖區擴容:my_bool?dynstr_append_mem(?DYNAMIC_STRING?*str,?const?char?*append,?size_t?length?)
{
char?*new_ptr;if?(?str->length?+?length?>=?str->max_length?)?/*?如果新增字符串后,總長度超過緩沖區大小?*/
{/*?需要分配多少個alloc_increment?大小的內存,才能存下新增后的字符串?*/
size_t?new_length?=?(str->length?+?length?+?str->alloc_increment)?/
str->alloc_increment;
new_length?*=?str->alloc_increment;if?(?!(new_ptr?=?(char?*)?my_realloc(?str->str,?new_length,?MYF(?MY_WME?)?)?)?)return(TRUE);
str->str=?new_ptr;
str->max_length?=?new_length;
}/*?將新分配的內容,append到str之后?*/
memcpy(?str->str?+?str->length,?append,?length?);
str->length+=?length;??????????????????????????????/*?擴容之后str新的長度?*/
str->str[str->length]=?0;?/*?Safety?for?C?programs?*/????????/*?字符串最后一個字符為’\0'?*/
return(FALSE);
}
從上述代碼可以看到,在字符串初始化化好之后,之后如果需要給該字符串增加新的內容,只需要根據之前存儲的信息來動態的realloc就好了。由于該結構體記錄了字符串相關的完整內容,所以動態的擴容會非常方便處理。
當然,除了這些,還有比如字符串截斷,字符串初始設置,轉義OS的引號等等:
將字符串偏移大于N之后的截斷。my_bool?dynstr_trunc(?DYNAMIC_STRING?*str,?size_t?n?)
{
str->length?-=?n;
str->str[str->length]?=?'\0';return(FALSE);
}
返回字符串中第一次出現某個字符的地址。若沒有,則返回字符串結尾的地址(指向’’)char?*strcend(?register?const?char?*s,?register?pchar?c?){for?(;;?)
{if?(?*s?==?(char)?c?)return(?(char?*)?s);if?(?!*s++?)return(?(char?*)?s?-?1);
}
}
字符串內容擴容:my_bool?dynstr_realloc(?DYNAMIC_STRING?*str,?size_t?additional_size?)
{
DBUG_ENTER(?"dynstr_realloc"?);if?(?!additional_size?)
DBUG_RETURN(?FALSE?);if?(?str->length?+?additional_size?>?str->max_length?)?/*?如果新的字符串內容超過緩沖區的最大長度?*/
{
str->max_length?=?(?(str->length?+?additional_size?+?str->alloc_increment?-?1)?/
str->alloc_increment)?*?str->alloc_increment;if?(?!(str->str?=?(char?*)?my_realloc(?str->str,?str->max_length,?MYF(?MY_WME?)?)?)?)
DBUG_RETURN(?TRUE?);
}
DBUG_RETURN(?FALSE?);
}
對字符串用引號括起來,對其中的單引號進行轉義,主要用于執行一些系統命令(system(cmd))。
比如:ls -al 會變成 ‘ls -al’
比如:ls -a’l會變成’ls -a\’l’/*
*?Concatenates?any?number?of?strings,?escapes?any?OS?quote?in?the?result?then
*?surround?the?whole?affair?in?another?set?of?quotes?which?is?finally?appended
*?to?specified?DYNAMIC_STRING.?This?function?is?especially?useful?when
*?building?strings?to?be?executed?with?the?system()?function.
*
*?@param?str?Dynamic?String?which?will?have?addtional?strings?appended.
*?@param?append?String?to?be?appended.
*?@param?...?Optional.?Additional?string(s)?to?be?appended.
*
*?@?note?The?final?argument?in?the?list?must?be?NullS?even?if?no?additional
*?options?are?passed.
*
*?@return?True?=?Success.
*/my_bool?dynstr_append_os_quoted(?DYNAMIC_STRING?*str,?const?char?*append,?...?){const?char*quote_str=?"\'";const?uintquote_len=?1;
my_boolret=?TRUE;
va_listdirty_text;
ret?&=?dynstr_append_mem(?str,?quote_str,?quote_len?);?/*?Leading?quote?*/
va_start(?dirty_text,?append?);while?(?append?!=?NullS?)
{const?char*cur_pos=?append;const?char*next_pos=?cur_pos;/*?Search?for?quote?in?each?string?and?replace?with?escaped?quote?*/
while?(?*(next_pos?=?strcend(?cur_pos,?quote_str[0]?)?)?!=?'\0'?)
{
ret&=?dynstr_append_mem(?str,?cur_pos,?(uint)?(next_pos?-?cur_pos)?);
ret&=?dynstr_append_mem(?str,?"\\",?1?);
ret&=?dynstr_append_mem(?str,?quote_str,?quote_len?);
cur_pos?=?next_pos?+?1;
}
ret&=?dynstr_append_mem(?str,?cur_pos,?(uint)?(next_pos?-?cur_pos)?);
append=?va_arg(?dirty_text,?char?*?);
}
va_end(?dirty_text?);
ret?&=?dynstr_append_mem(?str,?quote_str,?quote_len?);?/*?Trailing?quote?*/
return(ret);
}
通過定義動態字符串的結構體信息,每次分次進行字符串添加更多字符,都會根據字符串的當前的長度動態的擴容。而且每次擴容后,該結構體都記錄的當前字符串的實際信息(當前字符串的長度,緩沖器可容納字符串的長度,進行擴容的單元長度)。這樣,動態字符串的處理操作就變得非常方便了。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的mysql 字符串解析_MySQL 动态字符串处理详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql增加从库_不停止MySQL服务
- 下一篇: jdby mysql_06_dljd_m