|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I found an article
http://spec.winprog.org/streams/ as a starting point, but it seems to do alot of things that aren't very standard at all. One particular problem is, that he is using a vector as his input buffer and trys to assign an iterator to a char pointer. .... class winzoostreambuffer : private LoggerConsole, public sts::basic_streambuf<char, std::char_traits<char>> .... int winzoostreambuffer::uflow() { char c; // GetInput() returns a char from a custom console device while( c = GetInput() != '\n' ) _inputbuffer.pushback(c); _inputbuffer.push_back(c); _Pbeg = pCur =0, _PLength =0; // compiler complains here about assigning vector<char>::iterator to char * _GBeg = _GCur = _inputbuffer.begin(), _GLength =0; _Init( &_GBeg, &_GCur, &_Glength, &pBeg, &_PCur, &_PLnegth); } I don't think I can just static_cast it, can I? How do you go about using a vector as the underyling buffer? |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
"Christopher Pisz" <someone@somewhere.net> wrote in message news:475c5014$0$9588$4c368faf@roadrunner.com... >I found an article > http://spec.winprog.org/streams/ > as a starting point, but it seems to do alot of things that aren't very > standard at all. One particular problem is, that he is using a vector as > his input buffer and trys to assign an iterator to a char pointer. > > ... > class winzoostreambuffer : private LoggerConsole, public > sts::basic_streambuf<char, std::char_traits<char>> > ... > int winzoostreambuffer::uflow() > { > char c; > > // GetInput() returns a char from a custom console device > while( c = GetInput() != '\n' ) > _inputbuffer.pushback(c); > > _inputbuffer.push_back(c); > _Pbeg = pCur =0, _PLength =0; > > // compiler complains here about assigning vector<char>::iterator to > char * > _GBeg = _GCur = _inputbuffer.begin(), _GLength =0; > > _Init( &_GBeg, &_GCur, &_Glength, &pBeg, &_PCur, &_PLnegth); > } > > I don't think I can just static_cast it, can I? How do you go about using > a vector as the underyling buffer? > sorry, I should add that _PBeg, _PCur, _GBeg, and _GCur where all defined as private char * pointers to the "winzoostreambuffer" class and _PLength and _GLength are private ints to the class. I thought they were part of stream buffer, but appear to be some kind of intermediates before giving them to streambuffer's Init function which takes char * arguments |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
"Christopher Pisz" <someone@somewhere.net> wrote in message news:475c5250$0$9566$4c368faf@roadrunner.com... > > "Christopher Pisz" <someone@somewhere.net> wrote in message > news:475c5014$0$9588$4c368faf@roadrunner.com... >>I found an article >> http://spec.winprog.org/streams/ >> as a starting point, but it seems to do alot of things that aren't very >> standard at all. One particular problem is, that he is using a vector as >> his input buffer and trys to assign an iterator to a char pointer. >> >> ... >> class winzoostreambuffer : private LoggerConsole, public >> sts::basic_streambuf<char, std::char_traits<char>> >> ... >> int winzoostreambuffer::uflow() >> { >> char c; >> >> // GetInput() returns a char from a custom console device >> while( c = GetInput() != '\n' ) >> _inputbuffer.pushback(c); >> >> _inputbuffer.push_back(c); >> _Pbeg = pCur =0, _PLength =0; >> >> // compiler complains here about assigning vector<char>::iterator to >> char * >> _GBeg = _GCur = _inputbuffer.begin(), _GLength =0; >> >> _Init( &_GBeg, &_GCur, &_Glength, &pBeg, &_PCur, &_PLnegth); >> } >> >> I don't think I can just static_cast it, can I? How do you go about using >> a vector as the underyling buffer? >> > > > sorry, I should add that > > _PBeg, _PCur, _GBeg, and _GCur where all defined as private char * > pointers to the "winzoostreambuffer" class > and _PLength and _GLength are private ints to the class. I thought they > were part of stream buffer, but appear to be some kind of intermediates > before giving them to streambuffer's Init function which takes char * > arguments > > I tryed changing to _GBeg = GCur = &(*(_inputbuffer.begin())), GLen = 0; and it compiled, but warned about assigning a __w64 int to a int, I guess because my compiler uses 64 bit pointers. I also got an assertion when executing the test case, saying, "vector iterator not dereferenceable" I also tryed using the addres of front and the address of back+1, but got the same assertion. I can only assume that vector does not allocate its elements in consecutive memory locations and therefore doesn't want me using pointers at all. Is that correct? If so, am I not able to use a vector as the buffer for a basic_streambuf? |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Dec 9, 9:29 pm, "Christopher Pisz" <some...@somewhere.net> wrote:
> I found an articlehttp://spec.winprog.org/streams/ as a > starting point, but it seems to do alot of things that aren't > very standard at all. And it seems fairly complex for something that is very, very simple. > One particular problem is, that he is using a vector as his > input buffer and trys to assign an iterator to a char pointer. Which, of course, doesn't work. You can, however, use &v[0] to get the address of the first element, and it is guaranteed that all of the following elements will be contiguous. > ... > class winzoostreambuffer : private LoggerConsole, public > sts::basic_streambuf<char, std::char_traits<char>> > ... > int winzoostreambuffer::uflow() > { > char c; > // GetInput() returns a char from a custom console device > while( c = GetInput() != '\n' ) > _inputbuffer.pushback(c); > _inputbuffer.push_back(c); > _Pbeg = pCur =0, _PLength =0; > > // compiler complains here about assigning vector<char>::iterator to char > * > _GBeg = _GCur = _inputbuffer.begin(), _GLength =0; > _Init( &_GBeg, &_GCur, &_Glength, &pBeg, &_PCur, &_PLnegth); > } > I don't think I can just static_cast it, can I? How do you go > about using a vector as the underyling buffer? The usual way is by using &vect[0] to get the address, and vect.size() for the length. Be very, very careful not to do anything later which will invalidate the pointer, however. FWIW: you don't have to override uflow(). The usual solution just involves overriding underflow, with something like: int MyStreamBuf::underflow() { if ( gptr() == egptr() ) { // Fill buffer... if ( ! buffer.empty() ) { setg( &buffer[ 0 ], &buffer[ 0 ], &buffer[ 0 ] + buffer.size() ) ; } } return gptr() == egptr() ? EOF : *gptr() ; } -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Dec 9, 9:38 pm, "Christopher Pisz" <some...@somewhere.net> wrote:
> "Christopher Pisz" <some...@somewhere.net> wrote in message > news:475c5014$0$9588$4c368faf@roadrunner.com... > >I found an article [...] > sorry, I should add that > _PBeg, _PCur, _GBeg, and _GCur where all defined as private char * pointers > to the "winzoostreambuffer" class > and _PLength and _GLength are private ints to the class. I > thought they were part of stream buffer, but appear to be some > kind of intermediates before giving them to streambuffer's > Init function which takes char * arguments std::streambuf doesn't have an Init() function. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Dec 10, 8:37 am, "Christopher Pisz" <some...@somewhere.net> wrote:
> "Christopher Pisz" <some...@somewhere.net> wrote in message > news:475c5250$0$9566$4c368faf@roadrunner.com... > > "Christopher Pisz" <some...@somewhere.net> wrote in message > >news:475c5014$0$9588$4c368faf@roadrunner.com... > >>I found an article > >>http://spec.winprog.org/streams/ > >> as a starting point, but it seems to do alot of things that aren't very > >> standard at all. One particular problem is, that he is using a vector as > >> his input buffer and trys to assign an iterator to a char pointer. > >> ... > >> class winzoostreambuffer : private LoggerConsole, public > >> sts::basic_streambuf<char, std::char_traits<char>> > >> ... > >> int winzoostreambuffer::uflow() > >> { > >> char c; > >> // GetInput() returns a char from a custom console device > >> while( c = GetInput() != '\n' ) > >> _inputbuffer.pushback(c); > >> _inputbuffer.push_back(c); > >> _Pbeg = pCur =0, _PLength =0; > >> // compiler complains here about assigning vector<char>::iterator to > >> char * > >> _GBeg = _GCur = _inputbuffer.begin(), _GLength =0; While I'm at it: although I don't think it's your problem, the names above result in undefined behavior. You're not allowed to use names which start with an underscore followed by a capital letter. > >> _Init( &_GBeg, &_GCur, &_Glength, &pBeg, &_PCur, &_PLnegth); > >> } > >> I don't think I can just static_cast it, can I? How do you go about using > >> a vector as the underyling buffer? > > sorry, I should add that > > _PBeg, _PCur, _GBeg, and _GCur where all defined as private char * > > pointers to the "winzoostreambuffer" class > > and _PLength and _GLength are private ints to the class. I thought they > > were part of stream buffer, but appear to be some kind of intermediates > > before giving them to streambuffer's Init function which takes char * > > arguments > I tryed changing to _GBeg = GCur = &(*(_inputbuffer.begin())), > GLen = 0; and it compiled, but warned about assigning a __w64 > int to a int, I guess because my compiler uses 64 bit > pointers. Or maybe because _GLength is a char* (although you still shouldn't be getting a warning for that). If _GBeg and GCur are char*, and _inputbuffer is an std::vector<char>, the above should be legal, and there's no reason to complain. For more information (and in general anyway), you should split up the assignments into separate statements. There is practically never any reason to use the comma operator (except obfuscation). > I also got an assertion when executing the test case, saying, > "vector iterator not dereferenceable" Hmmm. Off hand, that sounds like the vector was empty. If the vector is empty, begin() returns the same iterator as end(), and you're not allowed to dereference that. > I also tryed using the addres of front and the address of > back+1, but got the same assertion. Again, if the array is empty, you're not allowed to call front() or back(). > I can only assume that vector does not allocate its elements > in consecutive memory locations and therefore doesn't want me > using pointers at all. Is that correct? Of course not. Using set::vector< char > is pretty much standard practice in a streambuf which requires buffering of an unknown size. The normal way of doing this would be: if ( buffer.empty() ) { setg( NULL, NULL, NULL ) ; } else { setg( &buffer[ 0 ], &buffer[ 0 ], &buffer[ 0 ] + buffer.size() ) ; } (For an explination of a really simple example of user defined streambufs, see http://kanze.james.neuf.fr/articles-en.html.) -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
"James Kanze" <james.kanze@gmail.com> wrote in message news:8e63264c-4eea-4093-bf14-f7e97ed171a7@e67g2000hsc.googlegroups.com... (For an explination of a really simple example of user defined streambufs, see http://kanze.james.neuf.fr/articles-en.html.) Took a look at the site, but the link to the full source code is broken. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Dec 11, 4:21 am, "Christopher Pisz" <some...@somewhere.net> wrote:
> "James Kanze" <james.ka...@gmail.com> wrote in message > news:8e63264c-4eea-4093-bf14-f7e97ed171a7@e67g2000hsc.googlegroups.com... > (For an explination of a really simple example of user defined > streambufs, seehttp://kanze.james.neuf.fr/articles-en.html.) > Took a look at the site, but the link to the full source code > is broken. So it is. I'd forgotten that there were links in the articles when I did some renaming some years back. If you use the link from the starting page, however, it will work. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
![]() |
| Outils de la discussion | |
|
|