English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

MySQL-DYNAMIC_STRING zur dynamischen Verarbeitung von Zeichenfolgen

在MySQL中,常常会看到一些关于动态字符串的处理,例如:DYNAMIC_STRING。

为了记录动态字符串的实际长度,缓冲区的最大长度,以及每次字符串需要调整时,及时分配新的内存,以及调整长度。MySQL使用了DYNAMIC_STRING来保存动态字符串相关的信息:

typedef struct st_dynamic_string
{
 char *str;
 size_t length, 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 )
 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;
 }
/* Fügt den neu zugewiesenen Inhalt, append, an str hinzu */
 memcpy(str->str + str->length, append, length );
 str->length += length;               /* Neue Länge von str nach Erweiterung */
 str->str[str->length] = 0; /* Safety for C programs */    /* Der letzte Zeichen des Strings ist '\0' */
 return(FALSE);
}

Wie aus dem obigen Code zu sehen ist, nach der Initialisierung des Strings, wenn neue Inhalte für diesen String hinzugefügt werden müssen, reicht es aus, auf die zuvor gespeicherten Informationen zurückzugreifen, um das dynamische realloc durchzuführen. Da diese Struktur die vollständigen Inhalte des Strings enthält, ist die dynamische Erweiterung sehr leicht zu verarbeiten.

Natürlich, abgesehen davon, gibt es auch wie das Schneiden von Strings, das Initialisieren von Strings, das Entschlüsseln der Anführungszeichen des OS usw.:

Schneidet den String ab, der größer als N ist.

my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n )
{
 str->length -= n;
 str->str[str->length] = '\0';
 return(FALSE);
}

Gibt die Adresse des ersten Auftretens eines bestimmten Zeichens im String zurück. Wenn nicht vorhanden, gibt es die Adresse des Endes des Strings zurück (zeigt auf '')

char *strcend(register const char *s, register pchar c )
{
 for (;; )
 {
 if ( *s == (char)c )
  return((char *) s);
 if (!*s++ )
  return((char *) s - 1);
 }
}

Stringinhalt erweitern:

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 ) /* Wenn der neue Stringinhalt die maximale Länge des Puffers übersteigt */
 {
 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 );
}

Stringe in Anführungszeichen umgeben, einfache Anführungszeichen im String werden escapet, wird hauptsächlich verwendet, um einige Systemkommandos (system(cmd)) auszuführen.

z.B.: ls -al wird zu ‘ls -al'

z.B.: ls -a'l wird zu '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 uint quote_len = 1;
 my_bool ret = TRUE;
 va_list dirty_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;
/* Suche nach Anfuhrraum in jeder Zeichenfolge und Ersetzen durchflüchtigten Anfuhrraum */
 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 ); /* Nachfolgender Anfuhrraum */
 return(ret);
}

Durch Definition der Strukturinformationen des dynamischen String-Strukturen, bei jeder zusätzlichen Zeichenfolge wird dynamisch nach der aktuellen Länge des Strings erweitert. Und nach jeder Erweiterung wird die aktuelle Informationen des String (aktuelle Länge des Strings, Länge des Puffers, der den String enthalten kann, und die Länge der Erweiterungseinheit) von der Struktur aufbewahrt. Auf diese Weise wird die Verarbeitung der dynamischen String-Operationen sehr bequem.

Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet bezogen und gehört dem Urheberrechtlichem Eigentümer. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine Haftung für rechtliche Fragen. Wenn Sie verdächtige urheberrechtliche Inhalte finden, senden Sie bitte eine E-Mail an: notice#w3Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet bezogen und gehört dem Urheberrechtlichem Eigentümer. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine Haftung für rechtliche Fragen. Wenn Sie verdächtige urheberrechtliche Inhalte finden, senden Sie bitte eine E-Mail an: notice#w

Gefällt mir