mirror of
https://github.com/Tencent/rapidjson.git
synced 2025-03-10 12:21:16 +01:00
Add Pointer default/copy constructor, assignment operator. Test constructor with tokens
This commit is contained in:
parent
c11547ebfa
commit
cf0ff19cac
@ -33,6 +33,16 @@ public:
|
||||
|
||||
static const SizeType kInvalidIndex = ~SizeType(0);
|
||||
|
||||
GenericPointer()
|
||||
: allocator_(),
|
||||
ownAllocator_(),
|
||||
nameBuffer_(),
|
||||
tokens_(),
|
||||
tokenCount_(),
|
||||
valid_(true)
|
||||
{
|
||||
}
|
||||
|
||||
GenericPointer(const Ch* source, Allocator* allocator = 0)
|
||||
: allocator_(allocator),
|
||||
ownAllocator_(),
|
||||
@ -55,16 +65,27 @@ public:
|
||||
Parse(source, length);
|
||||
}
|
||||
|
||||
GenericPointer(const Token* tokens, size_t tokenCount) :
|
||||
GenericPointer(const Token* tokens, size_t tokenCount)
|
||||
: allocator_(),
|
||||
ownAllocator_(),
|
||||
nameBuffer_(),
|
||||
tokens_(tokens),
|
||||
tokens_(const_cast<Token*>(tokens)),
|
||||
tokenCount_(tokenCount),
|
||||
valid_(true)
|
||||
{
|
||||
}
|
||||
|
||||
GenericPointer(const GenericPointer& rhs)
|
||||
: allocator_(),
|
||||
ownAllocator_(),
|
||||
nameBuffer_(),
|
||||
tokens_(),
|
||||
tokenCount_(),
|
||||
valid_()
|
||||
{
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
~GenericPointer() {
|
||||
if (nameBuffer_) {
|
||||
Allocator::Free(nameBuffer_);
|
||||
@ -73,6 +94,36 @@ public:
|
||||
RAPIDJSON_DELETE(ownAllocator_);
|
||||
}
|
||||
|
||||
GenericPointer& operator=(const GenericPointer& rhs) {
|
||||
this->~GenericPointer();
|
||||
|
||||
tokenCount_ = rhs.tokenCount_;
|
||||
valid_ = rhs.valid_;
|
||||
|
||||
if (rhs.nameBuffer_) {
|
||||
if (!allocator_)
|
||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
|
||||
|
||||
size_t nameBufferSize = tokenCount_; // null terminators
|
||||
for (Token *t = rhs.tokens_; t != rhs.tokens_ + tokenCount_; ++t)
|
||||
nameBufferSize += t->length;
|
||||
nameBuffer_ = (Ch*)allocator_->Malloc(nameBufferSize * sizeof(Ch));
|
||||
std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize);
|
||||
|
||||
tokens_ = (Token*)allocator_->Malloc(tokenCount_ * sizeof(Token));
|
||||
std::memcpy(tokens_, rhs.tokens_, tokenCount_ * sizeof(Token));
|
||||
|
||||
// Adjust pointers to name buffer
|
||||
std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
|
||||
for (Token *t = rhs.tokens_; t != rhs.tokens_ + tokenCount_; ++t)
|
||||
t->name += diff;
|
||||
}
|
||||
else
|
||||
tokens_ = rhs.tokens_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IsValid() const { return valid_; }
|
||||
|
||||
const Token* GetTokens() const { return tokens_; }
|
||||
@ -192,7 +243,7 @@ private:
|
||||
|
||||
// Create a buffer as same size of source
|
||||
RAPIDJSON_ASSERT(nameBuffer_ == 0);
|
||||
nameBuffer_ = (Ch*)allocator_->Malloc(length);
|
||||
nameBuffer_ = (Ch*)allocator_->Malloc(length * sizeof(Ch));
|
||||
|
||||
RAPIDJSON_ASSERT(tokens_ == 0);
|
||||
tokens_ = (Token*)allocator_->Malloc(length * sizeof(Token)); // Maximum possible tokens in the source
|
||||
@ -266,9 +317,6 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
GenericPointer(const GenericPointer& rhs);
|
||||
GenericPointer& operator=(const GenericPointer& rhs);
|
||||
|
||||
Allocator* allocator_;
|
||||
Allocator* ownAllocator_;
|
||||
Ch* nameBuffer_;
|
||||
|
@ -166,6 +166,82 @@ TEST(Pointer, Stringify) {
|
||||
}
|
||||
}
|
||||
|
||||
// Construct a Pointer with static tokens, no dynamic allocation involved.
|
||||
#define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, Pointer::kInvalidIndex }
|
||||
#define INDEX(i) { #i, sizeof(#i) - 1, i }
|
||||
|
||||
static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(0) }; // equivalent to "/foo/0"
|
||||
|
||||
#undef NAME
|
||||
#undef INDEX
|
||||
|
||||
TEST(Pointer, ConstructorWithToken) {
|
||||
Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
|
||||
EXPECT_TRUE(p.IsValid());
|
||||
EXPECT_EQ(2, p.GetTokenCount());
|
||||
EXPECT_EQ(3, p.GetTokens()[0].length);
|
||||
EXPECT_STREQ("foo", p.GetTokens()[0].name);
|
||||
EXPECT_EQ(1, p.GetTokens()[1].length);
|
||||
EXPECT_STREQ("0", p.GetTokens()[1].name);
|
||||
EXPECT_EQ(0, p.GetTokens()[1].index);
|
||||
}
|
||||
|
||||
TEST(Pointer, CopyConstructor) {
|
||||
{
|
||||
Pointer p("/foo/0");
|
||||
Pointer q(p);
|
||||
EXPECT_TRUE(q.IsValid());
|
||||
EXPECT_EQ(2, q.GetTokenCount());
|
||||
EXPECT_EQ(3, q.GetTokens()[0].length);
|
||||
EXPECT_STREQ("foo", q.GetTokens()[0].name);
|
||||
EXPECT_EQ(1, q.GetTokens()[1].length);
|
||||
EXPECT_STREQ("0", q.GetTokens()[1].name);
|
||||
EXPECT_EQ(0, q.GetTokens()[1].index);
|
||||
}
|
||||
|
||||
// Static tokens
|
||||
{
|
||||
Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
|
||||
Pointer q(p);
|
||||
EXPECT_TRUE(q.IsValid());
|
||||
EXPECT_EQ(2, q.GetTokenCount());
|
||||
EXPECT_EQ(3, q.GetTokens()[0].length);
|
||||
EXPECT_STREQ("foo", q.GetTokens()[0].name);
|
||||
EXPECT_EQ(1, q.GetTokens()[1].length);
|
||||
EXPECT_STREQ("0", q.GetTokens()[1].name);
|
||||
EXPECT_EQ(0, q.GetTokens()[1].index);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Pointer, Assignment) {
|
||||
{
|
||||
Pointer p("/foo/0");
|
||||
Pointer q;
|
||||
q = p;
|
||||
EXPECT_TRUE(q.IsValid());
|
||||
EXPECT_EQ(2, q.GetTokenCount());
|
||||
EXPECT_EQ(3, q.GetTokens()[0].length);
|
||||
EXPECT_STREQ("foo", q.GetTokens()[0].name);
|
||||
EXPECT_EQ(1, q.GetTokens()[1].length);
|
||||
EXPECT_STREQ("0", q.GetTokens()[1].name);
|
||||
EXPECT_EQ(0, q.GetTokens()[1].index);
|
||||
}
|
||||
|
||||
// Static tokens
|
||||
{
|
||||
Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
|
||||
Pointer q;
|
||||
q = p;
|
||||
EXPECT_TRUE(q.IsValid());
|
||||
EXPECT_EQ(2, q.GetTokenCount());
|
||||
EXPECT_EQ(3, q.GetTokens()[0].length);
|
||||
EXPECT_STREQ("foo", q.GetTokens()[0].name);
|
||||
EXPECT_EQ(1, q.GetTokens()[1].length);
|
||||
EXPECT_STREQ("0", q.GetTokens()[1].name);
|
||||
EXPECT_EQ(0, q.GetTokens()[1].index);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Pointer, Create) {
|
||||
Document d;
|
||||
EXPECT_EQ(&d, &Pointer("").Create(d, d.GetAllocator()));
|
||||
|
Loading…
x
Reference in New Issue
Block a user