// Tencent is pleased to support the open source community by making RapidJSON available.
// 
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// http://opensource.org/licenses/MIT
//
// Unless required by applicable law or agreed to in writing, software distributed 
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
// specific language governing permissions and limitations under the License.

#include "unittest.h"

#include "rapidjson/allocators.h"

using namespace rapidjson;

template <typename Allocator>
void TestAllocator(Allocator& a) {
    EXPECT_TRUE(a.Malloc(0) == 0);

    uint8_t* p = static_cast<uint8_t*>(a.Malloc(100));
    EXPECT_TRUE(p != 0);
    for (size_t i = 0; i < 100; i++)
        p[i] = static_cast<uint8_t>(i);

    // Expand
    uint8_t* q = static_cast<uint8_t*>(a.Realloc(p, 100, 200));
    EXPECT_TRUE(q != 0);
    for (size_t i = 0; i < 100; i++)
        EXPECT_EQ(i, q[i]);
    for (size_t i = 100; i < 200; i++)
        q[i] = static_cast<uint8_t>(i);

    // Shrink
    uint8_t *r = static_cast<uint8_t*>(a.Realloc(q, 200, 150));
    EXPECT_TRUE(r != 0);
    for (size_t i = 0; i < 150; i++)
        EXPECT_EQ(i, r[i]);

    Allocator::Free(r);

    // Realloc to zero size
    EXPECT_TRUE(a.Realloc(a.Malloc(1), 1, 0) == 0);
}

TEST(Allocator, CrtAllocator) {
    CrtAllocator a;
    TestAllocator(a);
}

TEST(Allocator, MemoryPoolAllocator) {
    MemoryPoolAllocator<> a;
    TestAllocator(a);

    for (size_t i = 1; i < 1000; i++) {
        EXPECT_TRUE(a.Malloc(i) != 0);
        EXPECT_LE(a.Size(), a.Capacity());
    }
}

TEST(Allocator, Alignment) {
#if RAPIDJSON_64BIT == 1
    EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000000), RAPIDJSON_ALIGN(0));
    for (uint64_t i = 1; i < 8; i++) {
        EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000008), RAPIDJSON_ALIGN(i));
        EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000000, 0x00000010), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0x00000000, 0x00000008) + i));
        EXPECT_EQ(RAPIDJSON_UINT64_C2(0x00000001, 0x00000000), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0x00000000, 0xFFFFFFF8) + i));
        EXPECT_EQ(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF8), RAPIDJSON_ALIGN(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF0) + i));
    }
#else
    EXPECT_EQ(0u, RAPIDJSON_ALIGN(0u));
    for (uint32_t i = 1; i < 4; i++) {
        EXPECT_EQ(4u, RAPIDJSON_ALIGN(i));
        EXPECT_EQ(8u, RAPIDJSON_ALIGN(4u + i));
        EXPECT_EQ(0xFFFFFFF8u, RAPIDJSON_ALIGN(0xFFFFFFF4u + i));
        EXPECT_EQ(0xFFFFFFFCu, RAPIDJSON_ALIGN(0xFFFFFFF8u + i));
    }
#endif
}

TEST(Allocator, Issue399) {
    MemoryPoolAllocator<> a;
    void* p = a.Malloc(100);
    void* q = a.Realloc(p, 100, 200);
    EXPECT_EQ(p, q);

    // exhuasive testing
    for (size_t j = 1; j < 32; j++) {
        a.Clear();
        a.Malloc(j); // some unaligned size
        p = a.Malloc(1);
        for (size_t i = 1; i < 1024; i++) {
            q = a.Realloc(p, i, i + 1);
            EXPECT_EQ(p, q);
            p = q;
        }
    }
}
