MySQL 之動態字串處理_PHP教程

來源:互聯網
上載者:User

MySQL 之動態字串處理


MySQL中,常常會看到一些關於動態字串的處理,列如:DYNAMIC_STRING。為了記錄動態字串的實際長度,緩衝區的最大長度,以及每次字串需要調整時,及時分配新的記憶體,以及調整長度。MySQL使用了DYNAMIC_STRING來儲存動態字串相關的資訊:

 
  1. typedef struct st_dynamic_string
  2. {
  3. char *str;
  4. size_t length,max_length,alloc_increment;
  5. } DYNAMIC_STRING;
在這個結構體中,str儲存實際字串的首地址,length記錄字串的實際長度,max_length記錄字串緩衝區最多可以存放多少字元,alloc_increment表示當字串需要分配記憶體時,每次分配多少記憶體。

下面看看這個結構體的初始化過程:

 
  1. my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,size_t init_alloc, size_t alloc_increment)
  2. {
  3. size_t length;
  4. DBUG_ENTER("init_dynamic_string");

  5. if (!alloc_increment)
  6. alloc_increment=128;
  7. length=1;
  8. if (init_str && (length= strlen(init_str)+1) < init_alloc)
  9. init_alloc=((length+alloc_increment-1)/alloc_increment)*alloc_increment;
  10. if (!init_alloc)
  11. init_alloc=alloc_increment;

  12. if (!(str->str=(char*) my_malloc(init_alloc,MYF(MY_WME))))
  13. DBUG_RETURN(TRUE);
  14. str->length=length-1;
  15. if (init_str)
  16. memcpy(str->str,init_str,length);
  17. str->max_length=init_alloc;
  18. str->alloc_increment=alloc_increment;
  19. DBUG_RETURN(FALSE);
  20. }
從上述函數可以看到,初始化時,初始分配的字串緩衝區大小init_alloc會根據需要初始的字串來做判斷。在分配好該DYNAMIC_STRING空間之後,我們會根據緩衝區的大小,字串的實際長度,以及alloc_increment來初始化:length:字串的實際長度max_length:緩衝區的最大長度alloc_increment:空間不夠時,下次分配記憶體的單元大小.

初始化這些內容之後,如果下次需要在該緩衝區添加更多字元,就可以根據這些值來判斷是否需要對該緩衝區擴容:

 
  1. my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
  2. size_t length)
  3. {
  4. char *new_ptr;
  5. if (str->length+length >= str->max_length) //如果新增字串後,總長度超過緩衝區大小
  6. {
  7. //需要分配多少個alloc_increment 大小的記憶體,才能存下新增後的字串
  8. size_t new_length=(str->length+length+str->alloc_increment)/
  9. str->alloc_increment;
  10. new_length*=str->alloc_increment;

  11. if (!(new_ptr=(char*) my_realloc(str->str,new_length,MYF(MY_WME))))
  12. return TRUE;
  13. str->str=new_ptr;
  14. str->max_length=new_length;
  15. }
  16. //將新分配的內容,append到str之後
  17. memcpy(str->str + str->length,append,length);
  18. str->length+=length; //擴容之後str新的長度
  19. str->str[str->length]=0; /* Safety for C programs */ //字串最後一個字元為’\0'
  20. return FALSE;
  21. }
從上述代碼可以看到,在字串初始化化好之後,之後如果需要給該字串增加新的內容,只需要根據之前儲存的資訊來動態realloc就好了。由於該結構體記錄了字串相關的完整內容,所以動態擴容會非常方便處理。
當然,除了這些,還有比如字串截斷,字串初始設定,轉義OS的引號等等:將字串位移大於N之後的截斷。

 
  1. my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n)
  2. {
  3. str->length-=n;
  4. str->str[str->length]= '\0';
  5. return FALSE;
  6. }
返回字串中第一次出現某個字元的地址。若沒有,則返回字串結尾的地址(指向’\0')

 
  1. char *strcend(register const char *s, register pchar c)
  2. {
  3. for (;;)
  4. {
  5. if (*s == (char) c) return (char*) s;
  6. if (!*s++) return (char*) s-1;
  7. }
  8. }
字串內容擴容:

 
  1. my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size)
  2. {
  3. DBUG_ENTER("dynstr_realloc");

  4. if (!additional_size) DBUG_RETURN(FALSE);
  5. if (str->length + additional_size > str->max_length) //如果新的字串內容超過緩衝區的最大長度
  6. {
  7. str->max_length=((str->length + additional_size+str->alloc_increment-1)/
  8. str->alloc_increment)*str->alloc_increment;
  9. if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))
  10. DBUG_RETURN(TRUE);
  11. }
  12. DBUG_RETURN(FALSE);
  13. }
對字串用引號括起來,對其中的單引號進行轉義,主要用於執行一些系統命令(system(cmd))。比如:ls -al 會變成 \'ls -al\'比如:ls -a’l會變成\’ls -a\\\’l\'

 
  1. /*
  2. Concatenates any number of strings, escapes any OS quote in the result then
  3. surround the whole affair in another set of quotes which is finally appended
  4. to specified DYNAMIC_STRING. This function is especially useful when
  5. building strings to be executed with the system() function.

  6. @param str Dynamic String which will have addtional strings appended.
  7. @param append String to be appended.
  8. @param ... Optional. Additional string(s) to be appended.

  9. @note The final argument in the list must be NullS even if no additional
  10. options are passed.

  11. @return True = Success.
  12. */

  13. my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...)
  14. {

  15. const char *quote_str= "\'";
  16. const uint quote_len= 1;
  17. my_bool ret= TRUE;
  18. va_list dirty_text;

  19. ret&= dynstr_append_mem(str, quote_str, quote_len); /* Leading quote */
  20. va_start(dirty_text, append);
  21. while (append != NullS)
  22. {
  23. const char *cur_pos= append;
  24. const char *next_pos= cur_pos;

  25. /* Search for quote in each string and replace with escaped quote */
  26. while(*(next_pos= strcend(cur_pos, quote_str[0])) != '\0')
  27. {
  28. ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));
  29. ret&= dynstr_append_mem(str ,"\\", 1);
  30. ret&= dynstr_append_mem(str, quote_str, quote_len);
  31. cur_pos= next_pos + 1;
  32. }
  33. ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));
  34. append= va_arg(dirty_text, char *);
  35. }
  36. va_end(dirty_text);
  37. ret&= dynstr_append_mem(str, quote_str, quote_len); /* Trailing quote */

  38. return ret;
  39. }
通過定義動態字串的結構體資訊,每次分次進行字串添加更多字元,都會根據字串的當前的長度動態擴容。而且每次擴容後,該結構體都記錄的當前字串的實際資訊(當前字串的長度,緩衝器可容納字串的長度,進行擴容的單元長度)。這樣,動態字串的處理操作就變得非常方便了。



http://www.bkjia.com/PHPjc/1079090.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1079090.htmlTechArticleMySQL 之動態字串處理 MySQL中,常常會看到一些關於動態字串的處理,列如:DYNAMIC_STRING。為了記錄動態字串的實際長度,緩衝區的最...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.