2016-01-28 3 views
4

У меня есть следующая реализация на основе, например, this question and answerКак реализовать пользовательский std :: streambuf's seekoff()?

struct membuf : std::streambuf 
{ 
    membuf(char* begin, char* end) 
    { 
    this->setg(begin, begin, end); 
    } 

protected: 
    virtual pos_type seekoff(off_type off, 
          std::ios_base::seekdir dir, 
          std::ios_base::openmode which = std::ios_base::in) 
    { 
    std::istream::pos_type ret; 
    if(dir == std::ios_base::cur) 
    { 
     this->gbump(off); 
    } 
    // something is missing here... 
    } 
}; 

Я хотел бы использовать его в своих методах следующим образом:

char buffer[] = { 0x01, 0x0a }; 
    membuf sbuf(buffer, buffer + sizeof(buffer)); 
    std::istream in(&sbuf); 

, а затем вызвать, например, tellg() на in и получите правильный результат.

Пока это почти идеально - оно не останавливается в конце потока.

Как я должен обновить это, чтобы он работал правильно?

Мое основное мотивирование состоит в том, чтобы имитировать поведение std::ifstream, но с двоичным char[], поданным в них в тестах (вместо того, чтобы полагаться на двоичные файлы).

+0

Что значит «это не останавливается»? – SergeyA

+0

@SergeyA Где-то в моем клиентском коде я вызываю 'in.tellg()' и проверяю его меньше, чем моя желаемая позиция «назначения». Это не удается и читает еще один элемент цикла, чем хотелось бы. – Patryk

+0

Пока неясно, что вы подразумеваете под «неудачей». Ожидается, что Tellg сообщит вам текущую позицию буфера, не более того, не меньше. Если вам удастся выйти за пределы буфера, tellg скажет вам об этом. – SergeyA

ответ

3

Кажется, что мне не хватало возврата с текущей позицией. Таким образом, окончательное осуществление seekoff выглядит следующим образом:

pos_type seekoff(off_type off, 
        std::ios_base::seekdir dir, 
        std::ios_base::openmode which = std::ios_base::in) 
    { 
    if (dir == std::ios_base::cur) gbump(off); 

    return gptr() - eback(); 
    } 
0

Принятая ответ не работает в тех случаях, когда направление искать устанавливается либо std::ios_base::beg или std::ios_base::end. Для поддержки этих случаев продлить реализацию:

pos_type seekoff(off_type off, 
       std::ios_base::seekdir dir, 
       std::ios_base::openmode which = std::ios_base::in) { 
    if (dir == std::ios_base::cur) 
    gbump(off); 
    else if (dir == std::ios_base::end) 
    setg(eback(), egptr() + off, egptr()); 
    else if (dir == std::ios_base::beg) 
    setg(eback(), eback() + off, egptr()); 
    return gptr() - eback(); 
} 
Смежные вопросы