-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can IStreamWrapper work with istream? #918
Labels
Comments
Try to reduce the test case.. |
I tried and it worked with #include "rapidjson/document.h"
#include "rapidjson/istreamwrapper.h"
#include <iostream>
int main() {
rapidjson::IStreamWrapper isw(std::cin);
rapidjson::Document d;
std::cout << "Parse: " << (d.ParseStream(isw).HasParseError() ? "Error" : "Ok") << std::endl;
} $ g++ -I ~/github/rapidjson/include a.cpp
$ echo "{}" | ./a.out
Parse: Ok
$ echo "[1,2]" | ./a.out
Parse: Ok
$ echo "[1,2,]" | ./a.out
Parse: Error
$ |
Hi Milo, Thanks for trying this out. In my case, it failed probably because of the particularity of how fcgi_streambuf works. I worked around this problem by slightly modifying the FileReadSteam class to work with std::cin. class InputReadStream {
public:
typedef char Ch; // Character type (byte) - needed as a template type
InputReadStream(char* buffer, size_t bufferSize, size_t clen) :
clen_(clen), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0),
current_(buffer_), readCount_(0), count_(0), eof_(false)
{
Read();
}
Ch Peek() const { return *current_; }
Ch Take() { Ch c = *current_; Read(); return c; }
size_t Tell() const
{ return count_ + static_cast<size_t>(current_ - buffer_); }
// Not implemented
void Put(Ch) { RAPIDJSON_ASSERT(false); }
void Flush() { RAPIDJSON_ASSERT(false); }
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
// For encoding detection only.
const Ch* Peek4() const
{
return (current_ + 4 <= bufferLast_) ? current_ : 0;
}
private:
void Read()
{
if (current_ < bufferLast_)
++current_;
else if (!eof_)
{
readCount_ = min(bufferSize_, clen_ - count_);
cin.read(buffer_, readCount_);
bufferLast_ = buffer_ + readCount_ - 1;
current_ = buffer_;
count_ += readCount_;
if (readCount_ < bufferSize_)
{
buffer_[readCount_] = '\0';
++bufferLast_;
eof_ = true;
}
}
}
Ch *buffer_;
size_t bufferSize_;
Ch *bufferLast_;
Ch *current_;
size_t readCount_;
size_t count_; // Number of characters read
size_t clen_;
bool eof_;
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I am trying to parse a JSON document in a FastCGI request body. FastCGI allows you to read in the request body using istream cin. The IStreamWrapper document says the following:
IStreamWrapper wraps any class drived from std::istream, such as std::istringstream, std::stringstream, std::ifstream, std::fstream, into RapidJSON's input stream.
Can I do the following?
IStreamWrapper isw(cin);
Document d;
d.ParseStream(ism);
It compiles but it does not seem to work, at least in the FastCGI context. It hits the following assert.
include/rapidjson/reader.h:769: void rapidjson::GenericReader<SourceEncoding, TargetEncoding, StackAllocator>::ParseNull(InputStream &, Handler &) [with parseFlags = 0U, InputStream = rapidjson::BasicIStreamWrapper<std::basic_istream<char, std::char_traits>>, Handler = rapidjson::GenericDocument<rapidjson::UTF8, rapidjson::MemoryPoolAllocatorrapidjson::CrtAllocator, rapidjson::CrtAllocator>, SourceEncoding = rapidjson::UTF8, TargetEncoding = rapidjson::UTF8, StackAllocator = rapidjson::CrtAllocator]: Assertion `is.Peek() == 'n'' failed.
The call stack is as follows:
#0 0x0000003d54a32625 in raise () from /lib64/libc.so.6
#1 0x0000003d54a33e05 in abort () from /lib64/libc.so.6
#2 0x0000003d54a2b74e in __assert_fail_base () from /lib64/libc.so.6
#3 0x0000003d54a2b810 in __assert_fail () from /lib64/libc.so.6
#4 0x00000000004b1280 in rapidjson::GenericReader<rapidjson::UTF8, rapidjson::UTF8, rapidjson::CrtAllocator>::ParseNull (this=0x7fff1a7ed008,
is=..., handler=...)
at rapidjson/reader.h:769
#5 0x00000000004b1161 in rapidjson::GenericReader<rapidjson::UTF8, rapidjson::UTF8, rapidjson::CrtAllocator>::ParseValue (this=0x7fff1a7ed008,
is=..., handler=...)
at rapidjson/reader.h:1465
#6 0x00000000004aea98 in rapidjson::GenericReader<rapidjson::UTF8, rapidjson::UTF8, rapidjson::CrtAllocator>::Parse (this=0x7fff1a7ed008, is=...,
handler=...)
at rapidjson/reader.h:487
#7 0x00000000004adb82 in rapidjson::GenericDocument<rapidjson::UTF8, rapidjson::MemoryPoolAllocatorrapidjson::CrtAllocator, rapidjson::CrtAllocator>::ParseStream (this=0x7fff5255df58, is=...)
at rapidjson/document.h:2209
#8 0x00000000004ada57 in rapidjson::GenericDocument<rapidjson::UTF8, rapidjson::MemoryPoolAllocatorrapidjson::CrtAllocator, rapidjson::CrtAllocator>::ParseStream (this=0x7fff5255df58, is=...)
at rapidjson/document.h:2235
The text was updated successfully, but these errors were encountered: