2009-10-18 5 views

Répondre

0

Jetez un oeil à la mise en œuvre de la STL pour sstream et sstream.tcc (liens vers la mise en œuvre SGI STL). La classe de base stringstream est basic_stringstream, qui implémente l'interface basic_iostream.

// [27.7.4] Template class basic_stringstream 
    /** 
    * @brief Controlling input and output for std::string. 
    * 
    * This class supports reading from and writing to objects of type 
    * std::basic_string, using the inherited functions from 
    * std::basic_iostream. To control the associated sequence, an instance 
    * of std::basic_stringbuf is used, which this page refers to as @c sb. 
    */ 

Il est la classe de base basic_stringbuf qui dérive de basic_streambuf. Cela contient le tampon.

// [27.7.1] template class basic_stringbuf 
    /** 
    * @brief The actual work of input and output (for std::string). 
    * 
    * This class associates either or both of its input and output sequences 
    * with a sequence of characters, which can be initialized from, or made 
    * available as, a @c std::basic_string. (Paraphrased from [27.7.1]/1.) 
    * 
    * For this class, open modes (of type @c ios_base::openmode) have 
    * @c in set if the input sequence can be read, and @c out set if the 
    * output sequence can be written. 
    */ 
1

veeeery schématiquement, pour un flux « d'entrée »:

class BufferedInputStream 
{ 
public: 
    BufferedInputStream(SomeExternalDevice d) 
    : m_Device(d), 
    m_Current(m_Buffer), 
    m_End(m_Buffer) 
    {} 

    char get(){ 
    if (!IsDataAvailableInBuffer()){ 
     ReadAChunkFromDiskAndPutItInBuffer(); 
    } 
    return PopByteFromBuffer(); 
    } 

private: 

    bool IsDataAvailableInBuffer()const{ 
    return m_Current != m_End; 
    } 

    void ReadAChunkFromDiskAndPutItInBuffer(){ 
    // Buffer must be empty 
    assert(!IsDataAvailableInBuffer()); 

    // Read bytes from the device 
    bytes_read = Read(m_Device, m_Buffer, BufferSize); 

    // Reposition the "begin" and "end" pointers 
    m_Current = m_Buffer; 
    m_End = m_Buffer + bytes_read; 
    } 

    char PopByteFromBuffer(){ 
    assert(IsDataAvailableInBuffer()); 
    return *m_Current++; 
    } 

    // For example, an OS file handle 
    SomeExternalDevice m_Device; 

    // The buffer itself 
    char m_Buffer[BufferSize]; 

    // Begin of buffer contents 
    char* m_Current; 

    // End of buffer contents 
    char* m_End; 
}; 

De cette façon, les données sont lues à partir du disque en morceaux de la taille de la mémoire tampon, et la plupart des appels à « get() » ne doivent pas se retrouver dans les appels au système d'exploitation, car ils peuvent simplement renvoyer un octet à partir du tampon.

Questions connexes