2014-09-28 12 views
6

Non riesco a trovare una buona spiegazione di ciò che consume() e commit() in realtà significa, in realtà non capisco affatto streambuf.boost streambuf consumare e commit, che cos'è

La mia comprensione è che uno streambuf è solo un array di caratteri. Ma perché è nella documentazione,

basic_streambuf::data 
Get a list of buffers that represents the input sequence. 

quindi in realtà ci sono molti buffer? E qual è la "sequenza di input" e la "sequenza di output"? Sono questi altri due buffer?

Cosa fa realmente il seguente codice?

streambuf b; 
size_t size; 
size = read(socket, b.prepare(1024)); 
b.commit(size); 
size = write(socket, b.data()); 
b.consume(size); 

quando chiamo b.prepare(), lo fa allocare un nuovo buffer per il read() per inserire i dati? Quindi quando vengono trasferiti i dati da quel buffer al buffer streambuf sottostante? Ho pensato che fosse il commit(), ma

basic_streambuf::commit 
Move characters from the output sequence to the input sequence. 

così sembra che impegnare effettivamente muove i dati dal 'sequenza di uscita' a 'sequenza di ingresso' senza mai menzionare il buffer sottostante utilizzato per memorizzare i dati!

risposta

6

Boost ASIO streambuf è più di un semplice array di caratteri. Dalla documentazione basic_streambuf:

La classe basic_streambuf è derivata da std :: streambuf ad associare le sequenze di ingresso e di uscita del streambuf con uno o più array di caratteri. Questi array di caratteri sono interni all'oggetto basic_streambuf, ma viene fornito l'accesso diretto agli elementi dell'array per consentire loro di essere utilizzati in modo efficiente con operazioni di I/O. I caratteri scritti nella sequenza di output di un oggetto basic_streambuf vengono aggiunti alla sequenza di input dello stesso oggetto.

La documentazione prosegue per parlare di possibili strategie di implementazione. L'oggetto streambuf può semplicemente utilizzare un singolo array di caratteri contigui con puntatori per gestire le sequenze di input e output. Ma l'interfaccia consente schemi più complicati.

Hai chiesto cosa fa effettivamente lo snippet di codice, ma questo dipende dall'implementazione sottostante. In breve, prepare() assicura che il buffer sottostante sia abbastanza grande da contenere ciò che stai cercando di inserire. Inoltre ti dà accesso al buffer tramite un oggetto mutuable_buffers. Una volta che i dati sono stati scritti nello streambuf (presumibilmente, quando viene chiamato il gestore di lettura), commit() rende i dati disponibili alla sequenza di input. È possibile accedere a quei byte utilizzando i dati(). Dopo aver terminato con i dati nel buffer (poiché lo hai copiato, elaborato o quant'altro), consume() rimuove i dati dalla sequenza di input. Una successiva chiamata a data() non conterrebbe i byte della precedente chiamata.

Si è inoltre affermato che il buffer sottostante utilizzato per memorizzare i dati non viene mai menzionato, e che è corretto. Spetta agli autori ASIO decidere come memorizzare i dati effettivi.