/CSipSimple/jni/webrtc/sources/system_wrappers/source/list_unittest.cc
https://bitbucket.org/bohlooli/csipsimple2 · C++ · 479 lines · 406 code · 43 blank · 30 comment · 90 complexity · 9a4dff992d2cda4eebf9e6dc8deb4190 MD5 · raw file
- /*
- * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
- #include "gtest/gtest.h"
- #include "system_wrappers/interface/list_wrapper.h"
- #include "system_wrappers/interface/scoped_ptr.h"
- using ::webrtc::ListWrapper;
- using ::webrtc::ListItem;
- using ::webrtc::scoped_ptr;
- // Note: kNumberOfElements needs to be even.
- const unsigned int kNumberOfElements = 10;
- // An opaque implementation of dynamic or statically allocated unsigned ints.
- // This class makes it possible to use the exact same code for testing of both
- // the dynamic and static implementation of ListWrapper.
- // Clarification: ListWrapper has two versions of PushBack(..). It takes an
- // unsigned integer or a void pointer. The integer implementation takes care
- // of memory management. The void pointer version expect the caller to manage
- // the memory associated with the void pointer.
- // This class works like the integer version but can be implemented on top of
- // either the integer version or void pointer version of ListWrapper.
- // Note: the non-virtual fuctions behave the same for both versions.
- class ListWrapperSimple {
- public:
- static ListWrapperSimple* Create(bool static_allocation);
- virtual ~ListWrapperSimple() {}
- // These three functions should be used for manipulating ListItems so that
- // they are the type corresponding to the underlying implementation.
- virtual unsigned int GetUnsignedItem(
- const ListItem* item) const = 0;
- virtual ListItem* CreateListItem(unsigned int item_id) = 0;
- unsigned int GetSize() const {
- return list_.GetSize();
- }
- virtual int PushBack(const unsigned int item_id) = 0;
- virtual int PushFront(const unsigned int item_id) = 0;
- virtual int PopFront() = 0;
- virtual int PopBack() = 0;
- bool Empty() const {
- return list_.Empty();
- }
- ListItem* First() const {
- return list_.First();
- }
- ListItem* Last() const {
- return list_.Last();
- }
- ListItem* Next(ListItem* item) const {
- return list_.Next(item);
- }
- ListItem* Previous(ListItem* item) const {
- return list_.Previous(item);
- }
- virtual int Erase(ListItem* item) = 0;
- int Insert(ListItem* existing_previous_item,
- ListItem* new_item) {
- const int retval = list_.Insert(existing_previous_item, new_item);
- if (retval != 0) {
- EXPECT_TRUE(DestroyListItem(new_item));
- }
- return retval;
- }
- int InsertBefore(ListItem* existing_next_item,
- ListItem* new_item) {
- const int retval = list_.InsertBefore(existing_next_item, new_item);
- if (retval != 0) {
- EXPECT_TRUE(DestroyListItem(new_item));
- }
- return retval;
- }
- protected:
- ListWrapperSimple() {}
- virtual bool DestroyListItemContent(ListItem* item) = 0;
- bool DestroyListItem(ListItem* item) {
- const bool retval = DestroyListItemContent(item);
- delete item;
- return retval;
- }
- ListWrapper list_;
- };
- void ClearList(ListWrapperSimple* list_wrapper) {
- if (list_wrapper == NULL) {
- return;
- }
- ListItem* list_item = list_wrapper->First();
- while (list_item != NULL) {
- EXPECT_EQ(list_wrapper->Erase(list_item), 0);
- list_item = list_wrapper->First();
- }
- }
- class ListWrapperStatic : public ListWrapperSimple {
- public:
- ListWrapperStatic() {}
- virtual ~ListWrapperStatic() {
- ClearList(this);
- }
- virtual unsigned int GetUnsignedItem(const ListItem* item) const {
- return item->GetUnsignedItem();
- }
- virtual ListItem* CreateListItem(unsigned int item_id) {
- return new ListItem(item_id);
- }
- virtual bool DestroyListItemContent(ListItem* item) {
- return true;
- }
- virtual int PushBack(const unsigned int item_id) {
- return list_.PushBack(item_id);
- }
- virtual int PushFront(const unsigned int item_id) {
- return list_.PushFront(item_id);
- }
- virtual int PopFront() {
- return list_.PopFront();
- }
- virtual int PopBack() {
- return list_.PopBack();
- }
- virtual int Erase(ListItem* item) {
- return list_.Erase(item);
- }
- };
- class ListWrapperDynamic : public ListWrapperSimple {
- public:
- ListWrapperDynamic() {}
- virtual ~ListWrapperDynamic() {
- ClearList(this);
- }
- virtual unsigned int GetUnsignedItem(const ListItem* item) const {
- const unsigned int* return_value_pointer =
- reinterpret_cast<unsigned int*> (item->GetItem());
- if (return_value_pointer == NULL) {
- return -1;
- }
- return *return_value_pointer;
- }
- virtual ListItem* CreateListItem(unsigned int item_id) {
- unsigned int* item_id_pointer = new unsigned int;
- if (item_id_pointer == NULL) {
- return NULL;
- }
- *item_id_pointer = item_id;
- ListItem* return_value = new ListItem(
- reinterpret_cast<void*>(item_id_pointer));
- if (return_value == NULL) {
- delete item_id_pointer;
- return NULL;
- }
- return return_value;
- }
- virtual bool DestroyListItemContent(ListItem* item) {
- if (item == NULL) {
- return false;
- }
- bool return_value = false;
- unsigned int* item_id_ptr = reinterpret_cast<unsigned int*>(
- item->GetItem());
- if (item_id_ptr != NULL) {
- return_value = true;
- delete item_id_ptr;
- }
- return return_value;
- }
- virtual int PushBack(const unsigned int item_id) {
- unsigned int* item_id_ptr = new unsigned int;
- if (item_id_ptr == NULL) {
- return -1;
- }
- *item_id_ptr = item_id;
- const int return_value = list_.PushBack(
- reinterpret_cast<void*>(item_id_ptr));
- if (return_value != 0) {
- delete item_id_ptr;
- }
- return return_value;
- }
- virtual int PushFront(const unsigned int item_id) {
- unsigned int* item_id_ptr = new unsigned int;
- if (item_id_ptr == NULL) {
- return -1;
- }
- *item_id_ptr = item_id;
- const int return_value = list_.PushFront(
- reinterpret_cast<void*>(item_id_ptr));
- if (return_value != 0) {
- delete item_id_ptr;
- }
- return return_value;
- }
- virtual int PopFront() {
- return Erase(list_.First());
- }
- virtual int PopBack() {
- return Erase(list_.Last());
- }
- virtual int Erase(ListItem* item) {
- if (item == NULL) {
- return -1;
- }
- int retval = 0;
- if (!DestroyListItemContent(item)) {
- retval = -1;
- ADD_FAILURE();
- }
- if (list_.Erase(item) != 0) {
- retval = -1;
- }
- return retval;
- }
- };
- ListWrapperSimple* ListWrapperSimple::Create(bool static_allocation) {
- if(static_allocation)
- {
- return new ListWrapperStatic();
- }
- return new ListWrapperDynamic();
- }
- ListWrapperSimple* CreateAscendingList(bool static_allocation) {
- ListWrapperSimple* return_value = ListWrapperSimple::Create(
- static_allocation);
- if (return_value == NULL) {
- return NULL;
- }
- for (unsigned int i = 0; i < kNumberOfElements; ++i) {
- if (return_value->PushBack(i) == -1) {
- ClearList(return_value);
- delete return_value;
- return NULL;
- }
- }
- return return_value;
- }
- ListWrapperSimple* CreateDescendingList(bool static_allocation) {
- ListWrapperSimple* return_value = ListWrapperSimple::Create(
- static_allocation);
- if (return_value == NULL) {
- return NULL;
- }
- for (unsigned int i = 0; i < kNumberOfElements; ++i) {
- if (return_value->PushBack(kNumberOfElements - i - 1) == -1) {
- ClearList(return_value);
- delete return_value;
- return NULL;
- }
- }
- return return_value;
- }
- // [0,kNumberOfElements - 1,1,kNumberOfElements - 2,...] (this is why
- // kNumberOfElements need to be even)
- ListWrapperSimple* CreateInterleavedList(bool static_allocation) {
- ListWrapperSimple* return_value = ListWrapperSimple::Create(
- static_allocation);
- if (return_value == NULL) {
- return NULL;
- }
- unsigned int uneven_count = 0;
- unsigned int even_count = 0;
- for (unsigned int i = 0; i < kNumberOfElements; i++) {
- unsigned int push_value = 0;
- if ((i % 2) == 0) {
- push_value = even_count;
- even_count++;
- } else {
- push_value = kNumberOfElements - uneven_count - 1;
- uneven_count++;
- }
- if (return_value->PushBack(push_value) == -1) {
- ClearList(return_value);
- delete return_value;
- return NULL;
- }
- }
- return return_value;
- }
- void PrintList(const ListWrapperSimple* list) {
- ListItem* list_item = list->First();
- printf("[");
- while (list_item != NULL)
- {
- printf("%3u", list->GetUnsignedItem(list_item));
- list_item = list->Next(list_item);
- }
- printf("]\n");
- }
- bool CompareLists(const ListWrapperSimple* lhs, const ListWrapperSimple* rhs) {
- const unsigned int list_size = lhs->GetSize();
- if (lhs->GetSize() != rhs->GetSize()) {
- return false;
- }
- if (lhs->Empty()) {
- return rhs->Empty();
- }
- unsigned int i = 0;
- ListItem* lhs_item = lhs->First();
- ListItem* rhs_item = rhs->First();
- while (i < list_size) {
- if (lhs_item == NULL) {
- return false;
- }
- if (rhs_item == NULL) {
- return false;
- }
- if (lhs->GetUnsignedItem(lhs_item) != rhs->GetUnsignedItem(rhs_item)) {
- return false;
- }
- i++;
- lhs_item = lhs->Next(lhs_item);
- rhs_item = rhs->Next(rhs_item);
- }
- return true;
- }
- TEST(ListWrapperTest,ReverseNewIntList) {
- // Create a new temporary list with elements reversed those of
- // new_int_list_
- const scoped_ptr<ListWrapperSimple> descending_list(
- CreateDescendingList(rand()%2));
- ASSERT_FALSE(descending_list.get() == NULL);
- ASSERT_FALSE(descending_list->Empty());
- ASSERT_EQ(kNumberOfElements,descending_list->GetSize());
- const scoped_ptr<ListWrapperSimple> ascending_list(
- CreateAscendingList(rand()%2));
- ASSERT_FALSE(ascending_list.get() == NULL);
- ASSERT_FALSE(ascending_list->Empty());
- ASSERT_EQ(kNumberOfElements,ascending_list->GetSize());
- scoped_ptr<ListWrapperSimple> list_to_reverse(
- ListWrapperSimple::Create(rand()%2));
- // Reverse the list using PushBack and Previous.
- for (ListItem* item = ascending_list->Last(); item != NULL;
- item = ascending_list->Previous(item)) {
- list_to_reverse->PushBack(ascending_list->GetUnsignedItem(item));
- }
- ASSERT_TRUE(CompareLists(descending_list.get(), list_to_reverse.get()));
- scoped_ptr<ListWrapperSimple> list_to_un_reverse(
- ListWrapperSimple::Create(rand()%2));
- ASSERT_FALSE(list_to_un_reverse.get() == NULL);
- // Reverse the reversed list using PushFront and Next.
- for (ListItem* item = list_to_reverse->First(); item != NULL;
- item = list_to_reverse->Next(item)) {
- list_to_un_reverse->PushFront(list_to_reverse->GetUnsignedItem(item));
- }
- ASSERT_TRUE(CompareLists(ascending_list.get(), list_to_un_reverse.get()));
- }
- TEST(ListWrapperTest,PopTest) {
- scoped_ptr<ListWrapperSimple> ascending_list(CreateAscendingList(rand()%2));
- ASSERT_FALSE(ascending_list.get() == NULL);
- ASSERT_FALSE(ascending_list->Empty());
- EXPECT_EQ(0, ascending_list->PopFront());
- EXPECT_EQ(1U, ascending_list->GetUnsignedItem(ascending_list->First()));
- EXPECT_EQ(0, ascending_list->PopBack());
- EXPECT_EQ(kNumberOfElements - 2, ascending_list->GetUnsignedItem(
- ascending_list->Last()));
- EXPECT_EQ(kNumberOfElements - 2, ascending_list->GetSize());
- }
- // Use Insert to interleave two lists.
- TEST(ListWrapperTest,InterLeaveTest) {
- scoped_ptr<ListWrapperSimple> interleave_list(
- CreateAscendingList(rand()%2));
- ASSERT_FALSE(interleave_list.get() == NULL);
- ASSERT_FALSE(interleave_list->Empty());
- scoped_ptr<ListWrapperSimple> descending_list(
- CreateDescendingList(rand()%2));
- ASSERT_FALSE(descending_list.get() == NULL);
- for (unsigned int i = 0; i < kNumberOfElements/2; ++i) {
- ASSERT_EQ(0, interleave_list->PopBack());
- ASSERT_EQ(0, descending_list->PopBack());
- }
- ASSERT_EQ(kNumberOfElements/2, interleave_list->GetSize());
- ASSERT_EQ(kNumberOfElements/2, descending_list->GetSize());
- unsigned int insert_position = kNumberOfElements/2;
- ASSERT_EQ(insert_position * 2, kNumberOfElements);
- while (!descending_list->Empty())
- {
- ListItem* item = descending_list->Last();
- ASSERT_FALSE(item == NULL);
- const unsigned int item_id = descending_list->GetUnsignedItem(item);
- ASSERT_EQ(0, descending_list->Erase(item));
- ListItem* insert_item = interleave_list->CreateListItem(item_id);
- ASSERT_FALSE(insert_item == NULL);
- item = interleave_list->First();
- ASSERT_FALSE(item == NULL);
- for (unsigned int j = 0; j < insert_position - 1; ++j) {
- item = interleave_list->Next(item);
- ASSERT_FALSE(item == NULL);
- }
- EXPECT_EQ(0, interleave_list->Insert(item, insert_item));
- --insert_position;
- }
- scoped_ptr<ListWrapperSimple> interleaved_list(
- CreateInterleavedList(rand()%2));
- ASSERT_FALSE(interleaved_list.get() == NULL);
- ASSERT_FALSE(interleaved_list->Empty());
- ASSERT_TRUE(CompareLists(interleaved_list.get(), interleave_list.get()));
- }
- // Use InsertBefore to interleave two lists.
- TEST(ListWrapperTest,InterLeaveTestII) {
- scoped_ptr<ListWrapperSimple> interleave_list(
- CreateDescendingList(rand()%2));
- ASSERT_FALSE(interleave_list.get() == NULL);
- ASSERT_FALSE(interleave_list->Empty());
- scoped_ptr<ListWrapperSimple> ascending_list(CreateAscendingList(rand()%2));
- ASSERT_FALSE(ascending_list.get() == NULL);
- for (unsigned int i = 0; i < kNumberOfElements/2; ++i) {
- ASSERT_EQ(0, interleave_list->PopBack());
- ASSERT_EQ(0, ascending_list->PopBack());
- }
- ASSERT_EQ(kNumberOfElements/2, interleave_list->GetSize());
- ASSERT_EQ(kNumberOfElements/2, ascending_list->GetSize());
- unsigned int insert_position = kNumberOfElements/2;
- ASSERT_EQ(insert_position * 2, kNumberOfElements);
- while (!ascending_list->Empty())
- {
- ListItem* item = ascending_list->Last();
- ASSERT_FALSE(item == NULL);
- const unsigned int item_id = ascending_list->GetUnsignedItem(item);
- ASSERT_EQ(0,ascending_list->Erase(item));
- ListItem* insert_item = interleave_list->CreateListItem(item_id);
- ASSERT_FALSE(insert_item == NULL);
- item = interleave_list->First();
- ASSERT_FALSE(item == NULL);
- for (unsigned int j = 0; j < insert_position - 1; ++j) {
- item = interleave_list->Next(item);
- ASSERT_FALSE(item == NULL);
- }
- EXPECT_EQ(interleave_list->InsertBefore(item, insert_item), 0);
- --insert_position;
- }
- scoped_ptr<ListWrapperSimple> interleaved_list(
- CreateInterleavedList(rand()%2));
- ASSERT_FALSE(interleaved_list.get() == NULL);
- ASSERT_FALSE(interleaved_list->Empty());
- ASSERT_TRUE(CompareLists(interleaved_list.get(), interleave_list.get()));
- }