Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
R
rapidjson
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
rapidjson
Commits
b60bcc27
Commit
b60bcc27
authored
Jul 27, 2014
by
Milo Yip
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add MemoryBuffer and MemoryStream
parent
c4ce48cd
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
246 additions
and
60 deletions
+246
-60
memorybuffer.h
include/rapidjson/memorybuffer.h
+55
-0
memorystream.h
include/rapidjson/memorystream.h
+47
-0
encodedstreamtest.cpp
test/unittest/encodedstreamtest.cpp
+144
-60
No files found.
include/rapidjson/memorybuffer.h
0 → 100644
View file @
b60bcc27
#ifndef RAPIDJSON_MEMORYBUFFER_H_
#define RAPIDJSON_MEMORYBUFFER_H_
#include "rapidjson.h"
#include "internal/stack.h"
namespace
rapidjson
{
//! Represents an in-memory output byte stream.
/*!
This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream.
It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file.
Differences between MemoryBuffer and StringBuffer:
1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer.
2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator.
\tparam Allocator type for allocating memory buffer.
\note implements Stream concept
*/
template
<
typename
Allocator
=
CrtAllocator
>
struct
GenericMemoryBuffer
{
typedef
char
Ch
;
// byte
GenericMemoryBuffer
(
Allocator
*
allocator
=
0
,
size_t
capacity
=
kDefaultCapacity
)
:
stack_
(
allocator
,
capacity
)
{}
void
Put
(
Ch
c
)
{
*
stack_
.
template
Push
<
Ch
>
()
=
c
;
}
void
Flush
()
{}
void
Clear
()
{
stack_
.
Clear
();
}
Ch
*
Push
(
size_t
count
)
{
return
stack_
.
template
Push
<
Ch
>
(
count
);
}
void
Pop
(
size_t
count
)
{
stack_
.
template
Pop
<
Ch
>
(
count
);
}
const
Ch
*
GetBuffer
()
const
{
return
stack_
.
template
Bottom
<
Ch
>
();
}
size_t
GetSize
()
const
{
return
stack_
.
GetSize
();
}
static
const
size_t
kDefaultCapacity
=
256
;
mutable
internal
::
Stack
<
Allocator
>
stack_
;
};
typedef
GenericMemoryBuffer
<>
MemoryBuffer
;
//! Implement specialized version of PutN() with memset() for better performance.
template
<>
inline
void
PutN
(
MemoryBuffer
&
memoryBuffer
,
char
c
,
size_t
n
)
{
memset
(
memoryBuffer
.
stack_
.
Push
<
char
>
(
n
),
c
,
n
*
sizeof
(
c
));
}
}
// namespace rapidjson
#endif // RAPIDJSON_MEMORYBUFFER_H_
include/rapidjson/memorystream.h
0 → 100644
View file @
b60bcc27
#ifndef RAPIDJSON_MEMORYSTREAM_H_
#define RAPIDJSON_MEMORYSTREAM_H_
#include "rapidjson.h"
namespace
rapidjson
{
//! Represents an in-memory input byte stream.
/*!
This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream.
It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file.
Differences between MemoryStream and StringStream:
1. StringStream has encoding but MemoryStream is a byte stream.
2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source.
3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4().
\note implements Stream concept
*/
struct
MemoryStream
{
typedef
char
Ch
;
// byte
MemoryStream
(
const
Ch
*
src
,
size_t
size
)
:
src_
(
src
),
begin_
(
src
),
end_
(
src
+
size
),
size_
(
size
)
{}
Ch
Peek
()
const
{
return
*
src_
;
}
Ch
Take
()
{
return
(
src_
==
end_
)
?
'\0'
:
*
src_
++
;
}
size_t
Tell
()
const
{
return
static_cast
<
size_t
>
(
src_
-
begin_
);
}
Ch
*
PutBegin
()
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
void
Put
(
Ch
)
{
RAPIDJSON_ASSERT
(
false
);
}
void
Flush
()
{
RAPIDJSON_ASSERT
(
false
);
}
size_t
PutEnd
(
Ch
*
)
{
RAPIDJSON_ASSERT
(
false
);
return
0
;
}
// For encoding detection only.
const
Ch
*
Peek4
()
const
{
return
Tell
()
+
4
<=
size_
?
src_
:
0
;
}
const
Ch
*
src_
;
//!< Current read position.
const
Ch
*
begin_
;
//!< Original head of the string.
const
Ch
*
end_
;
//!< End of stream.
size_t
size_
;
//!< Size of the stream.
};
}
// namespace rapidjson
#endif // RAPIDJSON_MEMORYBUFFER_H_
test/unittest/encodedstreamtest.cpp
View file @
b60bcc27
...
...
@@ -3,6 +3,8 @@
#include "rapidjson/filewritestream.h"
#include "rapidjson/encodedstream.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/memorystream.h"
#include "rapidjson/memorybuffer.h"
using
namespace
rapidjson
;
...
...
@@ -55,61 +57,154 @@ protected:
template
<
typename
FileEncoding
,
typename
MemoryEncoding
>
void
TestEncodedInputStream
(
const
char
*
filename
)
{
char
buffer
[
16
];
FILE
*
fp
=
Open
(
filename
);
ASSERT_TRUE
(
fp
!=
0
);
FileReadStream
fs
(
fp
,
buffer
,
sizeof
(
buffer
));
EncodedInputStream
<
FileEncoding
,
FileReadStream
>
eis
(
fs
);
StringStream
s
(
json_
);
while
(
eis
.
Peek
()
!=
'\0'
)
{
unsigned
expected
,
actual
;
EXPECT_TRUE
(
UTF8
<>::
Decode
(
s
,
&
expected
));
EXPECT_TRUE
(
MemoryEncoding
::
Decode
(
eis
,
&
actual
));
EXPECT_EQ
(
expected
,
actual
);
// Test FileReadStream
{
char
buffer
[
16
];
FILE
*
fp
=
Open
(
filename
);
ASSERT_TRUE
(
fp
!=
0
);
FileReadStream
fs
(
fp
,
buffer
,
sizeof
(
buffer
));
EncodedInputStream
<
FileEncoding
,
FileReadStream
>
eis
(
fs
);
StringStream
s
(
json_
);
while
(
eis
.
Peek
()
!=
'\0'
)
{
unsigned
expected
,
actual
;
EXPECT_TRUE
(
UTF8
<>::
Decode
(
s
,
&
expected
));
EXPECT_TRUE
(
MemoryEncoding
::
Decode
(
eis
,
&
actual
));
EXPECT_EQ
(
expected
,
actual
);
}
EXPECT_EQ
(
'\0'
,
s
.
Peek
());
fclose
(
fp
);
}
// Test MemoryStream
{
size_t
size
;
char
*
data
=
ReadFile
(
filename
,
true
,
&
size
);
MemoryStream
ms
(
data
,
size
);
EncodedInputStream
<
FileEncoding
,
MemoryStream
>
eis
(
ms
);
StringStream
s
(
json_
);
while
(
eis
.
Peek
()
!=
'\0'
)
{
unsigned
expected
,
actual
;
EXPECT_TRUE
(
UTF8
<>::
Decode
(
s
,
&
expected
));
EXPECT_TRUE
(
MemoryEncoding
::
Decode
(
eis
,
&
actual
));
EXPECT_EQ
(
expected
,
actual
);
}
EXPECT_EQ
(
'\0'
,
s
.
Peek
());
free
(
data
);
}
EXPECT_EQ
(
'\0'
,
s
.
Peek
());
fclose
(
fp
);
}
void
TestAutoUTFInputStream
(
const
char
*
filename
)
{
char
buffer
[
16
];
FILE
*
fp
=
Open
(
filename
);
ASSERT_TRUE
(
fp
!=
0
);
FileReadStream
fs
(
fp
,
buffer
,
sizeof
(
buffer
));
AutoUTFInputStream
<
unsigned
,
FileReadStream
>
eis
(
fs
);
StringStream
s
(
json_
);
while
(
eis
.
Peek
()
!=
'\0'
)
{
unsigned
expected
,
actual
;
EXPECT_TRUE
(
UTF8
<>::
Decode
(
s
,
&
expected
));
EXPECT_TRUE
(
AutoUTF
<
unsigned
>::
Decode
(
eis
,
&
actual
));
EXPECT_EQ
(
expected
,
actual
);
// Test FileReadStream
{
char
buffer
[
16
];
FILE
*
fp
=
Open
(
filename
);
ASSERT_TRUE
(
fp
!=
0
);
FileReadStream
fs
(
fp
,
buffer
,
sizeof
(
buffer
));
AutoUTFInputStream
<
unsigned
,
FileReadStream
>
eis
(
fs
);
StringStream
s
(
json_
);
while
(
eis
.
Peek
()
!=
'\0'
)
{
unsigned
expected
,
actual
;
EXPECT_TRUE
(
UTF8
<>::
Decode
(
s
,
&
expected
));
EXPECT_TRUE
(
AutoUTF
<
unsigned
>::
Decode
(
eis
,
&
actual
));
EXPECT_EQ
(
expected
,
actual
);
}
EXPECT_EQ
(
'\0'
,
s
.
Peek
());
fclose
(
fp
);
}
// Test MemoryStream
{
size_t
size
;
char
*
data
=
ReadFile
(
filename
,
true
,
&
size
);
MemoryStream
ms
(
data
,
size
);
AutoUTFInputStream
<
unsigned
,
MemoryStream
>
eis
(
ms
);
StringStream
s
(
json_
);
while
(
eis
.
Peek
()
!=
'\0'
)
{
unsigned
expected
,
actual
;
EXPECT_TRUE
(
UTF8
<>::
Decode
(
s
,
&
expected
));
EXPECT_TRUE
(
AutoUTF
<
unsigned
>::
Decode
(
eis
,
&
actual
));
EXPECT_EQ
(
expected
,
actual
);
}
EXPECT_EQ
(
'\0'
,
s
.
Peek
());
free
(
data
);
}
EXPECT_EQ
(
'\0'
,
s
.
Peek
());
fclose
(
fp
);
}
template
<
typename
FileEncoding
,
typename
MemoryEncoding
>
void
TestEncodedOutputStream
(
const
char
*
expectedFilename
,
bool
putBOM
)
{
char
filename
[
L_tmpnam
];
TempFilename
(
filename
);
FILE
*
fp
=
fopen
(
filename
,
"wb"
);
char
buffer
[
16
];
FileWriteStream
os
(
fp
,
buffer
,
sizeof
(
buffer
));
EncodedOutputStream
<
FileEncoding
,
FileWriteStream
>
eos
(
os
,
putBOM
);
StringStream
s
(
json_
);
while
(
s
.
Peek
()
!=
'\0'
)
{
bool
success
=
Transcoder
<
UTF8
<>
,
MemoryEncoding
>::
Transcode
(
s
,
eos
);
EXPECT_TRUE
(
success
);
// Test FileWriteStream
{
char
filename
[
L_tmpnam
];
TempFilename
(
filename
);
FILE
*
fp
=
fopen
(
filename
,
"wb"
);
char
buffer
[
16
];
FileWriteStream
os
(
fp
,
buffer
,
sizeof
(
buffer
));
EncodedOutputStream
<
FileEncoding
,
FileWriteStream
>
eos
(
os
,
putBOM
);
StringStream
s
(
json_
);
while
(
s
.
Peek
()
!=
'\0'
)
{
bool
success
=
Transcoder
<
UTF8
<>
,
MemoryEncoding
>::
Transcode
(
s
,
eos
);
EXPECT_TRUE
(
success
);
}
eos
.
Flush
();
fclose
(
fp
);
EXPECT_TRUE
(
CompareFile
(
filename
,
expectedFilename
));
remove
(
filename
);
}
// Test MemoryBuffer
{
MemoryBuffer
mb
;
EncodedOutputStream
<
FileEncoding
,
MemoryBuffer
>
eos
(
mb
,
putBOM
);
StringStream
s
(
json_
);
while
(
s
.
Peek
()
!=
'\0'
)
{
bool
success
=
Transcoder
<
UTF8
<>
,
MemoryEncoding
>::
Transcode
(
s
,
eos
);
EXPECT_TRUE
(
success
);
}
eos
.
Flush
();
EXPECT_TRUE
(
CompareBufferFile
(
mb
.
GetBuffer
(),
mb
.
GetSize
(),
expectedFilename
));
}
eos
.
Flush
();
fclose
(
fp
);
EXPECT_TRUE
(
CompareFile
(
filename
,
expectedFilename
));
remove
(
filename
);
}
bool
CompareFile
(
char
*
filename
,
const
char
*
expectedFilename
)
{
void
TestAutoUTFOutputStream
(
UTFType
type
,
bool
putBOM
,
const
char
*
expectedFilename
)
{
// Test FileWriteStream
{
char
filename
[
L_tmpnam
];
TempFilename
(
filename
);
FILE
*
fp
=
fopen
(
filename
,
"wb"
);
char
buffer
[
16
];
FileWriteStream
os
(
fp
,
buffer
,
sizeof
(
buffer
));
AutoUTFOutputStream
<
unsigned
,
FileWriteStream
>
eos
(
os
,
type
,
putBOM
);
StringStream
s
(
json_
);
while
(
s
.
Peek
()
!=
'\0'
)
{
bool
success
=
Transcoder
<
UTF8
<>
,
AutoUTF
<
unsigned
>
>::
Transcode
(
s
,
eos
);
EXPECT_TRUE
(
success
);
}
eos
.
Flush
();
fclose
(
fp
);
EXPECT_TRUE
(
CompareFile
(
filename
,
expectedFilename
));
remove
(
filename
);
}
// Test MemoryBuffer
{
MemoryBuffer
mb
;
AutoUTFOutputStream
<
unsigned
,
MemoryBuffer
>
eos
(
mb
,
type
,
putBOM
);
StringStream
s
(
json_
);
while
(
s
.
Peek
()
!=
'\0'
)
{
bool
success
=
Transcoder
<
UTF8
<>
,
AutoUTF
<
unsigned
>
>::
Transcode
(
s
,
eos
);
EXPECT_TRUE
(
success
);
}
eos
.
Flush
();
EXPECT_TRUE
(
CompareBufferFile
(
mb
.
GetBuffer
(),
mb
.
GetSize
(),
expectedFilename
));
}
}
bool
CompareFile
(
const
char
*
filename
,
const
char
*
expectedFilename
)
{
size_t
actualLength
,
expectedLength
;
char
*
actualBuffer
=
ReadFile
(
filename
,
false
,
&
actualLength
);
char
*
expectedBuffer
=
ReadFile
(
expectedFilename
,
true
,
&
expectedLength
);
...
...
@@ -119,23 +214,12 @@ protected:
return
ret
;
}
void
TestAutoUTFOutputStream
(
UTFType
type
,
bool
putBOM
,
const
char
*
expectedFilename
)
{
char
filename
[
L_tmpnam
];
TempFilename
(
filename
);
FILE
*
fp
=
fopen
(
filename
,
"wb"
);
char
buffer
[
16
];
FileWriteStream
os
(
fp
,
buffer
,
sizeof
(
buffer
));
AutoUTFOutputStream
<
unsigned
,
FileWriteStream
>
eos
(
os
,
type
,
putBOM
);
StringStream
s
(
json_
);
while
(
s
.
Peek
()
!=
'\0'
)
{
bool
success
=
Transcoder
<
UTF8
<>
,
AutoUTF
<
unsigned
>
>::
Transcode
(
s
,
eos
);
EXPECT_TRUE
(
success
);
}
eos
.
Flush
();
fclose
(
fp
);
EXPECT_TRUE
(
CompareFile
(
filename
,
expectedFilename
));
remove
(
filename
);
bool
CompareBufferFile
(
const
char
*
actualBuffer
,
size_t
actualLength
,
const
char
*
expectedFilename
)
{
size_t
expectedLength
;
char
*
expectedBuffer
=
ReadFile
(
expectedFilename
,
true
,
&
expectedLength
);
bool
ret
=
(
expectedLength
==
actualLength
)
&&
memcmp
(
expectedBuffer
,
actualBuffer
,
actualLength
)
==
0
;
free
(
expectedBuffer
);
return
ret
;
}
char
*
json_
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment