2010-05-24 5 views
3

J'ai une application Visual Studio 2008 C++ où je voudrais traiter un flux comme un ensemble d'itérateurs.copier depuis un std :: istreambuf_iterator <> vers un std :: vector <>

Par exemple, si je devais recevoir un tableau de structures WIN32_FIND_DATA sur le ruisseau, je voudrais pouvoir faire quelque chose comme ceci:

IStreamBuf<WIN32_FIND_DATA> sb(stream); 
std::vector<WIN32_FIND_DATA> buffer; 
std::copy(std::istreambuf_iterator<WIN32_FIND_DATA>(&sb), 
      std::istreambuf_iterator<WIN32_FIND_DATA>(), 
      std::back_inserter(buffer)); 

Pour ce faire, je l'ai défini une classe dérivé de std::basic_streambuf<>:

template< typename T > 
class IStreamBuf : public std::basic_streambuf<byte> 
{ 
public: 

    IStreamBuf(IStream* stream) : stream_(stream) 
    {   
    }; 

protected: 

    virtual traits_type::int_type underflow() 
    { 
     DWORD bytes_read = 0; 
     HRESULT hr = stream_->Read(&buffer_, sizeof(T), &bytes_read); 
     if(FAILED(hr)) 
      return traits_type::eof(); 

     traits_type::char_type* begin = 
      reinterpret_cast< traits_type::char_type* >(&buffer_); 
     setg(begin, begin, begin + bytes_read); 
     return traits_type::to_int_type(*gptr()); 
    }; 

private: 

    // buffer to hold current item of type T 
    T buffer_; 

    // stream used to receive data 
    IStream* stream_; 
}; // class IStreamBuf 

Ce que je ne peux pas comprendre comment aller avec grâce d'un tableau de byte s à un tableau de WIN32_FIND_DATA s. Parce que std::basic_streambuf<> nécessite un paramètre de modèle std::char_traits<>, je suis sous l'impression qu'il ne peut utiliser que des types intégrés comme char ou byte, pas une structure comme WIN32_FIND_DATA. Correct?

Toutes les suggestions sur la façon de faire ce travail?

Merci, PaulH

Répondre

1

Un istreambuf_iterator fonctionne au niveau de la mémoire tampon, où il est juste un flux d'octets. Si vous voulez traiter des structures, vous voulez probablement utiliser un istream_iterator à la place, et créer un operator>> pour lire les structures WIN32_FIND_DATA. Vous pouvez également envisager de créer/utiliser un proxy pour le WIN32_FIND_DATA.

+0

La raison pour laquelle je suis allé avec le 'std :: istreambuf_iterator's est le' std :: istream_iterator' fonctionne sur l'entrée formatée. Donc, j'aurais un peu de surcharge supplémentaire (objets de sentinelle, contrôle de drapeau de flux, etc.) Pouvez-vous élaborer sur ce que vous entendez par "un proxy pour le WIN32_FIND_DATA". De préférence un petit exemple? – PaulH

+0

@PaulH: vous ne devez manipuler que des objets de sentinelle si vous lisez vous-même depuis le tampon sous-jacent - la lecture du flux à l'aide des fonctions de lecture de flux existantes ne nécessite pas d'objet sentinelle. Un exemple de proxy est à: http://stackoverflow.com/questions/2531874/how-might-i-wrap-the-findxfile-style-apis-to-the-stl-style-iterator-pattern-in-c –

+0

Je viens de l'essayer en utilisant 'istream_iterator'. Il a filtré les caractères d'espaces blancs hors du nom de fichier. – PaulH

Questions connexes