English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In MySQL, spesso si vedono alcune operazioni sulla stringa dinamica, come: DYNAMIC_STRING.
Per registrare la lunghezza effettiva della stringa dinamica, la lunghezza massima del buffer, e allocare nuove memorie in tempo quando la stringa deve essere adattata, MySQL utilizza DYNAMIC_STRING per salvare le informazioni correlate alla stringa dinamica:
typedef struct st_dynamic_string { char *str; size_t length, max_length, alloc_increment; DYNAMIC_STRING;
In this structure, str stores the actual address of the string, length records the actual length of the string, max_length records how many characters the string buffer can store at most, and alloc_increment indicates how much memory is allocated each time the string needs to allocate memory.
Let's take a look at the initialization process of this structure:
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 ); }
From the above functions, we can see that during initialization, the initial allocation size of the string buffer init_alloc will be judged according to the required initial string. After the DYNAMIC_STRING space is allocated, we will initialize it according to the buffer size, the actual length of the string, and alloc_increment:
length: The actual length of the string
max_length: The maximum length of the buffer
alloc_increment: When there is not enough space, the size of the next allocated memory unit.
Dopo aver inizializzato questi contenuti, se in futuro è necessario aggiungere più caratteri a questo buffer, è possibile determinare se è necessario espandere il buffer in base a questi valori:
my_bool dynstr_append_mem( DYNAMIC_STRING *str, const char *append, size_t length ) { char *new_ptr; if ( str->length + length >= str->max_length ) /* Se la lunghezza totale dopo l'aggiunta della stringa supera la dimensione del buffer */ { /* Quanta memoria deve essere allocata per alloc_increment per contenere la stringa aggiunta */ 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; } /* Aggiungere il nuovo contenuto allocato, append, alla fine di str */ memcpy( str->str + str->length, append, length ); str->length += length; /* La nuova lunghezza di str dopo l'espansione */ str->str[str->length] = 0; /* Sicurezza per i programmi C */ /* L'ultimo carattere della stringa è '\0' */ return(FALSE); }
Come si può vedere dal codice sopra, dopo aver inizializzato la stringa, se è necessario aggiungere nuovo contenuto a questa stringa, è sufficiente realloc dinamicamente in base alle informazioni memorizzate in precedenza. Poiché questa struttura registra il contenuto completo della stringa, l'espansione dinamica è molto facile da gestire.
Certo, oltre a questi, ci sono anche come il taglio della stringa, l'impostazione iniziale della stringa, l'escape dei virgoletti dell'OS, ecc.:
Tagliare la stringa di scarto dopo l'offset superiore a N.
my_bool dynstr_trunc( DYNAMIC_STRING *str, size_t n ) { str->length -= n; str->str[str->length] = '\0'; return(FALSE); }
Restituisce l'indirizzo della prima occorrenza di un carattere nella stringa. Se non c'è, restituisce l'indirizzo della fine della stringa (che punta a '')
char *strcend( register const char *s, register pchar c ) { for (;; ) { if ( *s == (char) c ) return( (char *) s); if ( !*s++ ) return( (char *) s - 1); } }
Espansione del contenuto della stringa:
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 ) /* Se il nuovo contenuto della stringa supera la lunghezza massima del buffer */ { 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 ); }
Mette le stringhe tra virgolette, scappa i virgoletti singoli al loro interno, principalmente utilizzato per eseguire alcuni comandi di sistema (system(cmd)).
ad esempio: ls -al diventa ‘ls -al'
ad esempio: ls -a'l diventa 'ls -a\'l'
/* * Concatena un numero qualsiasi di stringhe, scappa da qualsiasi virgoletta di sistema nel risultato quindi * avvolge l'intera questione in un altro set di virgolette che alla fine viene aggiunto * a DYNAMIC_STRING specificato. Questa funzione è particolarmente utile quando * costruzione di stringhe da eseguire con la funzione system(). * * @param str Stringa dinamica a cui verranno aggiunte ulteriori stringhe. * @param append Stringa da aggiungere. * @param ... Opzionale. Stringhe aggiuntive da aggiungere. * * @note L'ultimo argomento nella lista deve essere NullS anche se non ci sono ulteriori * Opzioni vengono trasmesse. * * @return True = Successo. */ 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); /* Citazione iniziale */ va_start(dirty_text, append); while (append != NullS) { const char *cur_pos = append; const char *next_pos = cur_pos; /* Ricerca della citazione in ogni stringa e sostituzione con citazione evitata */ 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); }
Definendo le informazioni della struttura della stringa dinamica, ogni volta che si aggiungono più caratteri alla stringa in modo incrementale, si espande dinamicamente in base alla lunghezza attuale della stringa. E dopo ogni espansione, la struttura registra le informazioni effettive della stringa attuale (la lunghezza della stringa attuale, la lunghezza che può contenere il buffer, la lunghezza dell'unità di espansione). In questo modo, le operazioni di gestione delle stringhe dinamiche diventano molto facili.
Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, il copyright spetta ai rispettivi autori, il contenuto è stato contribuito e caricato dagli utenti di Internet autonomamente, questo sito non detiene i diritti di proprietà, non è stato editato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito eliminerà immediatamente il contenuto sospetto di violazione del copyright.