Commit 04515a63 authored by miloyip@gmail.com's avatar miloyip@gmail.com

Implemented FileWriteStream with buffering

git-svn-id: https://rapidjson.googlecode.com/svn/trunk@23 c5894555-1306-4e8d-425f-1f6f381ee07c
parent bce34fbe
......@@ -5,18 +5,21 @@
#include "rapidjson/reader.h"
#include "rapidjson/writer.h"
#include "rapidjson/filestream.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h"
using namespace rapidjson;
int main(int argc, char* argv[]) {
// Prepare JSON reader and input stream.
Reader reader;
FileStream is(stdin);
char readBuffer[65536];
FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
// Prepare JSON writer and output stream.
FileStream os(stdout);
Writer<FileStream> writer(os);
char writeBuffer[65536];
FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
Writer<FileWriteStream> writer(os);
// JSON reader parse from the input stream and let writer generate the output.
if (!reader.Parse<0>(is, writer)) {
......
......@@ -2,18 +2,21 @@
#include "rapidjson/reader.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/filestream.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h"
using namespace rapidjson;
int main(int argc, char* argv[]) {
// Prepare reader and input stream.
Reader reader;
FileStream is(stdin);
char readBuffer[65536];
FileReadStream is(stdin, readBuffer, sizeof(readBuffer));
// Prepare writer and output stream.
FileStream os(stdout);
PrettyWriter<FileStream> writer(os);
char writeBuffer[65536];
FileWriteStream os(stdout, writeBuffer, sizeof(writeBuffer));
PrettyWriter<FileWriteStream> writer(os);
// JSON reader parse from the input stream and let writer generate the output.
if (!reader.Parse<0>(is, writer)) {
......
......@@ -46,7 +46,6 @@ private:
if (readCount_ < bufferSize_) {
buffer_[readCount_] = '\0';
++bufferLast_;
++count_;
eof_ = true;
}
}
......
......@@ -34,10 +34,8 @@ private:
current_ = (char)c;
count_++;
}
else if (current_ != '\0') {
else if (current_ != '\0')
current_ = '\0';
count_++;
}
}
FILE* fp_;
......
#ifndef RAPIDJSON_FILEWRITESTREAM_H_
#define RAPIDJSON_FILEWRITESTREAM_H_
#include "rapidjson.h"
#include <cstdio>
namespace rapidjson {
//! Wrapper of C file stream for input using fread().
/*!
\implements Stream
*/
class FileWriteStream {
public:
typedef char Ch; //!< Character type. Only support char.
FileWriteStream(FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
RAPIDJSON_ASSERT(fp_ != 0);
}
void Put(char c) {
if (current_ >= bufferEnd_)
Flush();
*current_++ = c;
}
void PutN(char c, size_t n) {
size_t avail = bufferEnd_ - current_;
while (n > avail) {
memset(current_, c, avail);
current_ += avail;
Flush();
n -= avail;
avail = bufferEnd_ - current_;
}
if (n > 0) {
memset(current_, c, n);
current_ += n;
}
}
void Flush() {
if (current_ != buffer_) {
fwrite(buffer_, 1, current_ - buffer_, fp_);
current_ = buffer_;
}
}
// Not implemented
char Peek() const { RAPIDJSON_ASSERT(false); }
char Take() { RAPIDJSON_ASSERT(false); }
size_t Tell() const { RAPIDJSON_ASSERT(false); }
char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
private:
FILE* fp_;
char *buffer_;
char *bufferEnd_;
char *current_;
};
//! Implement specialized version of PutN() with memset() for better performance.
template<>
inline void PutN(FileWriteStream& stream, char c, size_t n) {
stream.PutN(c, n);
}
} // namespace rapidjson
#endif // RAPIDJSON_FILESTREAM_H_
#include "unittest.h"
#include "rapidjson/filestream.h"
#include "rapidjson/filereadstream.h"
#include "rapidjson/filewritestream.h"
using namespace rapidjson;
......@@ -17,7 +18,6 @@ class FileStreamTest : public ::testing::Test {
json_ = (char*)malloc(length_ + 1);
fread(json_, 1, length_, fp);
json_[length_] = '\0';
length_++; // include the null terminator
fclose(fp);
}
......@@ -31,7 +31,7 @@ protected:
size_t length_;
};
TEST_F(FileStreamTest, Read) {
TEST_F(FileStreamTest, FileStream_Read) {
FILE *fp = fopen(filename_, "rb");
ASSERT_TRUE(fp != 0);
FileStream s(fp);
......@@ -48,18 +48,16 @@ TEST_F(FileStreamTest, Read) {
fclose(fp);
}
TEST_F(FileStreamTest, BufferedRead) {
TEST_F(FileStreamTest, FileReadStream) {
FILE *fp = fopen(filename_, "rb");
ASSERT_TRUE(fp != 0);
char buffer[65536];
FileReadStream s(fp, buffer, sizeof(buffer));
for (size_t i = 0; i < length_; i++) {
if (json_[i] != s.Peek())
__asm int 3;
ASSERT_EQ(json_[i], s.Peek());
ASSERT_EQ(json_[i], s.Peek()); // 2nd time should be the same
ASSERT_EQ(json_[i], s.Take());
EXPECT_EQ(json_[i], s.Peek());
EXPECT_EQ(json_[i], s.Peek()); // 2nd time should be the same
EXPECT_EQ(json_[i], s.Take());
}
EXPECT_EQ(length_, s.Tell());
......@@ -67,3 +65,29 @@ TEST_F(FileStreamTest, BufferedRead) {
fclose(fp);
}
TEST_F(FileStreamTest, FileWriteStream) {
char filename[L_tmpnam];
tmpnam(filename);
FILE *fp = fopen(filename, "wb");
char buffer[65536];
FileWriteStream os(fp, buffer, sizeof(buffer));
for (size_t i = 0; i < length_; i++)
os.Put(json_[i]);
os.Flush();
fclose(fp);
// Read it back to verify
fp = fopen(filename, "rb");
FileReadStream is(fp, buffer, sizeof(buffer));
for (size_t i = 0; i < length_; i++)
EXPECT_EQ(json_[i], is.Take());
EXPECT_EQ(length_, is.Tell());
fclose(fp);
//std::cout << filename << std::endl;
remove(filename);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment