Removes the remaining uses of the list wrapper class and the list wrapper class.

BUG=2164
R=pbos@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/7019007

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5378 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrike@webrtc.org 2014-01-13 22:41:34 +00:00
parent dde7aee40f
commit 3907c2e7e5
12 changed files with 292 additions and 1777 deletions

View File

@ -57,7 +57,7 @@ public:
// Add/remove participants as candidates for mixing.
virtual int32_t SetMixabilityStatus(MixerParticipant& participant,
const bool mixable) = 0;
bool mixable) = 0;
// mixable is set to true if a participant is a candidate for mixing.
virtual int32_t MixabilityStatus(MixerParticipant& participant,
bool& mixable) = 0;

View File

@ -11,6 +11,7 @@
#ifndef WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_
#define WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_AUDIO_CONFERENCE_MIXER_IMPL_H_
#include <list>
#include <map>
#include "webrtc/engine_configurations.h"
@ -19,13 +20,15 @@
#include "webrtc/modules/audio_conference_mixer/source/memory_pool.h"
#include "webrtc/modules/audio_conference_mixer/source/time_scheduler.h"
#include "webrtc/modules/interface/module_common_types.h"
#include "webrtc/system_wrappers/interface/list_wrapper.h"
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
namespace webrtc {
class AudioProcessing;
class CriticalSectionWrapper;
typedef std::list<AudioFrame*> AudioFrameList;
typedef std::list<MixerParticipant*> MixerParticipantList;
// Cheshire cat implementation of MixerParticipant's non virtual functions.
class MixHistory
{
@ -74,7 +77,7 @@ public:
const uint32_t amountOf10MsBetweenCallbacks);
virtual int32_t UnRegisterMixerStatusCallback();
virtual int32_t SetMixabilityStatus(MixerParticipant& participant,
const bool mixable);
bool mixable);
virtual int32_t MixabilityStatus(MixerParticipant& participant,
bool& mixable);
virtual int32_t SetMinimumMixingFrequency(Frequency freq);
@ -98,18 +101,18 @@ private:
// used to be mixed but shouldn't be mixed any longer. These AudioFrames
// should be ramped out over this AudioFrame to avoid audio discontinuities.
void UpdateToMix(
ListWrapper& mixList,
ListWrapper& rampOutList,
AudioFrameList* mixList,
AudioFrameList* rampOutList,
std::map<int, MixerParticipant*>* mixParticipantList,
uint32_t& maxAudioFrameCounter);
size_t& maxAudioFrameCounter);
// Return the lowest mixing frequency that can be used without having to
// downsample any audio.
int32_t GetLowestMixingFrequency();
int32_t GetLowestMixingFrequencyFromList(ListWrapper& mixList);
int32_t GetLowestMixingFrequencyFromList(MixerParticipantList* mixList);
// Return the AudioFrames that should be mixed anonymously.
void GetAdditionalAudio(ListWrapper& additionalFramesList);
void GetAdditionalAudio(AudioFrameList* additionalFramesList);
// Update the MixHistory of all MixerParticipants. mixedParticipantsList
// should contain a map of MixerParticipants that have been mixed.
@ -117,44 +120,44 @@ private:
std::map<int, MixerParticipant*>& mixedParticipantsList);
// Clears audioFrameList and reclaims all memory associated with it.
void ClearAudioFrameList(ListWrapper& audioFrameList);
void ClearAudioFrameList(AudioFrameList* audioFrameList);
// Update the list of MixerParticipants who have a positive VAD. mixList
// should be a list of AudioFrames
void UpdateVADPositiveParticipants(
ListWrapper& mixList);
AudioFrameList* mixList);
// This function returns true if it finds the MixerParticipant in the
// specified list of MixerParticipants.
bool IsParticipantInList(
MixerParticipant& participant,
ListWrapper& participantList);
MixerParticipantList* participantList) const;
// Add/remove the MixerParticipant to the specified
// MixerParticipant list.
bool AddParticipantToList(
MixerParticipant& participant,
ListWrapper& participantList);
MixerParticipantList* participantList);
bool RemoveParticipantFromList(
MixerParticipant& removeParticipant,
ListWrapper& participantList);
MixerParticipantList* participantList);
// Mix the AudioFrames stored in audioFrameList into mixedAudio.
int32_t MixFromList(
AudioFrame& mixedAudio,
const ListWrapper& audioFrameList);
const AudioFrameList* audioFrameList);
// Mix the AudioFrames stored in audioFrameList into mixedAudio. No
// record will be kept of this mix (e.g. the corresponding MixerParticipants
// will not be marked as IsMixed()
int32_t MixAnonomouslyFromList(AudioFrame& mixedAudio,
const ListWrapper& audioFrameList);
const AudioFrameList* audioFrameList);
bool LimitMixedAudio(AudioFrame& mixedAudio);
// Scratch memory
// Note that the scratch memory may only be touched in the scope of
// Process().
uint32_t _scratchParticipantsToMixAmount;
size_t _scratchParticipantsToMixAmount;
ParticipantStatistics _scratchMixedParticipants[
kMaximumAmountOfMixedParticipants];
uint32_t _scratchVadPositiveParticipantsAmount;
@ -172,9 +175,9 @@ private:
AudioMixerOutputReceiver* _mixReceiver;
AudioMixerStatusReceiver* _mixerStatusCallback;
uint32_t _amountOf10MsBetweenCallbacks;
uint32_t _amountOf10MsUntilNextCallback;
bool _mixerStatusCb;
uint32_t _amountOf10MsBetweenCallbacks;
uint32_t _amountOf10MsUntilNextCallback;
bool _mixerStatusCb;
// The current sample frequency and sample size when mixing.
Frequency _outputFrequency;
@ -184,10 +187,11 @@ private:
MemoryPool<AudioFrame>* _audioFramePool;
// List of all participants. Note all lists are disjunct
ListWrapper _participantList; // May be mixed.
ListWrapper _additionalParticipantList; // Always mixed, anonomously.
MixerParticipantList _participantList; // May be mixed.
// Always mixed, anonomously.
MixerParticipantList _additionalParticipantList;
uint32_t _numMixedParticipants;
size_t _numMixedParticipants;
uint32_t _timeStamp;

View File

@ -1,107 +0,0 @@
/*
* 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.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_
#include "webrtc/system_wrappers/interface/constructor_magic.h"
namespace webrtc {
class CriticalSectionWrapper;
class ListItem {
friend class ListWrapper;
public:
ListItem(const void* ptr);
ListItem(const unsigned int item);
virtual ~ListItem();
void* GetItem() const;
unsigned int GetUnsignedItem() const;
protected:
ListItem* next_;
ListItem* prev_;
private:
const void* item_ptr_;
const unsigned int item_;
};
class ListWrapper {
public:
ListWrapper();
virtual ~ListWrapper();
// Returns the number of elements stored in the list.
unsigned int GetSize() const;
// Puts a pointer to anything last in the list.
int PushBack(const void* ptr);
// Puts a pointer to anything first in the list.
int PushFront(const void* ptr);
// Puts a copy of the specified integer last in the list.
int PushBack(const unsigned int item_id);
// Puts a copy of the specified integer first in the list.
int PushFront(const unsigned int item_id);
// Pops the first ListItem from the list
int PopFront();
// Pops the last ListItem from the list
int PopBack();
// Returns true if the list is empty
bool Empty() const;
// Returns a pointer to the first ListItem in the list.
ListItem* First() const;
// Returns a pointer to the last ListItem in the list.
ListItem* Last() const;
// Returns a pointer to the ListItem stored after item in the list.
ListItem* Next(ListItem* item) const;
// Returns a pointer to the ListItem stored before item in the list.
ListItem* Previous(ListItem* item) const;
// Removes item from the list.
int Erase(ListItem* item);
// Insert list item after existing_previous_item. Please note that new_item
// must be created using new ListItem(). The map will take ownership of
// new_item following a successfull insert. If insert fails new_item will
// not be released by the List
int Insert(ListItem* existing_previous_item,
ListItem* new_item);
// Insert list item before existing_next_item. Please note that new_item
// must be created using new ListItem(). The map will take ownership of
// new_item following a successfull insert. If insert fails new_item will
// not be released by the List
int InsertBefore(ListItem* existing_next_item,
ListItem* new_item);
private:
void PushBackImpl(ListItem* item);
void PushFrontImpl(ListItem* item);
CriticalSectionWrapper* critical_section_;
ListItem* first_;
ListItem* last_;
unsigned int size_;
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_LIST_WRAPPER_H_

View File

@ -1,241 +0,0 @@
/*
* 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 "webrtc/system_wrappers/interface/list_wrapper.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc {
ListItem::ListItem(const void* item)
: next_(0),
prev_(0),
item_ptr_(item),
item_(0) {
}
ListItem::ListItem(const unsigned int item)
: next_(0),
prev_(0),
item_ptr_(0),
item_(item) {
}
ListItem::~ListItem() {
}
void* ListItem::GetItem() const {
return const_cast<void*>(item_ptr_);
}
unsigned int ListItem::GetUnsignedItem() const {
return item_;
}
ListWrapper::ListWrapper()
: critical_section_(CriticalSectionWrapper::CreateCriticalSection()),
first_(0),
last_(0),
size_(0) {
}
ListWrapper::~ListWrapper() {
if (!Empty()) {
// TODO(hellner) I'm not sure this loggin is useful.
WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,
"Potential memory leak in ListWrapper");
// Remove all remaining list items.
while (Erase(First()) == 0)
{}
}
delete critical_section_;
}
bool ListWrapper::Empty() const {
return !first_ && !last_;
}
unsigned int ListWrapper::GetSize() const {
return size_;
}
int ListWrapper::PushBack(const void* ptr) {
ListItem* item = new ListItem(ptr);
CriticalSectionScoped lock(critical_section_);
PushBackImpl(item);
return 0;
}
int ListWrapper::PushBack(const unsigned int item_id) {
ListItem* item = new ListItem(item_id);
CriticalSectionScoped lock(critical_section_);
PushBackImpl(item);
return 0;
}
int ListWrapper::PushFront(const unsigned int item_id) {
ListItem* item = new ListItem(item_id);
CriticalSectionScoped lock(critical_section_);
PushFrontImpl(item);
return 0;
}
int ListWrapper::PushFront(const void* ptr) {
ListItem* item = new ListItem(ptr);
CriticalSectionScoped lock(critical_section_);
PushFrontImpl(item);
return 0;
}
int ListWrapper::PopFront() {
return Erase(first_);
}
int ListWrapper::PopBack() {
return Erase(last_);
}
ListItem* ListWrapper::First() const {
return first_;
}
ListItem* ListWrapper::Last() const {
return last_;
}
ListItem* ListWrapper::Next(ListItem* item) const {
if (!item) {
return 0;
}
return item->next_;
}
ListItem* ListWrapper::Previous(ListItem* item) const {
if (!item) {
return 0;
}
return item->prev_;
}
int ListWrapper::Insert(ListItem* existing_previous_item, ListItem* new_item) {
if (!new_item) {
return -1;
}
// Allow existing_previous_item to be NULL if the list is empty.
// TODO(hellner) why allow this? Keep it as is for now to avoid
// breaking API contract.
if (!existing_previous_item && !Empty()) {
return -1;
}
CriticalSectionScoped lock(critical_section_);
if (!existing_previous_item) {
PushBackImpl(new_item);
return 0;
}
ListItem* next_item = existing_previous_item->next_;
new_item->next_ = existing_previous_item->next_;
new_item->prev_ = existing_previous_item;
existing_previous_item->next_ = new_item;
if (next_item) {
next_item->prev_ = new_item;
} else {
last_ = new_item;
}
size_++;
return 0;
}
int ListWrapper::InsertBefore(ListItem* existing_next_item,
ListItem* new_item) {
if (!new_item) {
return -1;
}
// Allow existing_next_item to be NULL if the list is empty.
// Todo: why allow this? Keep it as is for now to avoid breaking API
// contract.
if (!existing_next_item && !Empty()) {
return -1;
}
CriticalSectionScoped lock(critical_section_);
if (!existing_next_item) {
PushBackImpl(new_item);
return 0;
}
ListItem* previous_item = existing_next_item->prev_;
new_item->next_ = existing_next_item;
new_item->prev_ = previous_item;
existing_next_item->prev_ = new_item;
if (previous_item) {
previous_item->next_ = new_item;
} else {
first_ = new_item;
}
size_++;
return 0;
}
int ListWrapper::Erase(ListItem* item) {
if (!item) {
return -1;
}
size_--;
ListItem* previous_item = item->prev_;
ListItem* next_item = item->next_;
if (!previous_item) {
if (next_item) {
next_item->prev_ = 0;
}
first_ = next_item;
} else {
previous_item->next_ = next_item;
}
if (!next_item) {
if (previous_item) {
previous_item->next_ = 0;
}
last_ = previous_item;
} else {
next_item->prev_ = previous_item;
}
delete item;
return 0;
}
void ListWrapper::PushBackImpl(ListItem* item) {
if (Empty()) {
first_ = item;
last_ = item;
size_++;
return;
}
item->prev_ = last_;
last_->next_ = item;
last_ = item;
size_++;
}
void ListWrapper::PushFrontImpl(ListItem* item) {
if (Empty()) {
first_ = item;
last_ = item;
size_++;
return;
}
item->next_ = first_;
first_->prev_ = item;
first_ = item;
size_++;
}
} // namespace webrtc

View File

@ -1,78 +0,0 @@
/*
* 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.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_
#include "webrtc/system_wrappers/interface/constructor_magic.h"
namespace webrtc {
class CriticalSectionWrapper;
class ListNoStlItem {
public:
ListNoStlItem(const void* ptr);
ListNoStlItem(const unsigned int item);
virtual ~ListNoStlItem();
void* GetItem() const;
unsigned int GetUnsignedItem() const;
protected:
ListNoStlItem* next_;
ListNoStlItem* prev_;
private:
friend class ListNoStl;
const void* item_ptr_;
const unsigned int item_;
DISALLOW_COPY_AND_ASSIGN(ListNoStlItem);
};
class ListNoStl {
public:
ListNoStl();
virtual ~ListNoStl();
// ListWrapper functions
unsigned int GetSize() const;
int PushBack(const void* ptr);
int PushBack(const unsigned int item_id);
int PushFront(const void* ptr);
int PushFront(const unsigned int item_id);
int PopFront();
int PopBack();
bool Empty() const;
ListNoStlItem* First() const;
ListNoStlItem* Last() const;
ListNoStlItem* Next(ListNoStlItem* item) const;
ListNoStlItem* Previous(ListNoStlItem* item) const;
int Erase(ListNoStlItem* item);
int Insert(ListNoStlItem* existing_previous_item,
ListNoStlItem* new_item);
int InsertBefore(ListNoStlItem* existing_next_item,
ListNoStlItem* new_item);
private:
void PushBack(ListNoStlItem* item);
void PushFront(ListNoStlItem* item);
CriticalSectionWrapper* critical_section_;
ListNoStlItem* first_;
ListNoStlItem* last_;
unsigned int size_;
DISALLOW_COPY_AND_ASSIGN(ListNoStl);
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_NO_STL_H_

View File

@ -1,207 +0,0 @@
/*
* 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 "webrtc/system_wrappers/interface/list_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc {
ListItem::ListItem(const void* item)
: this_iter_(),
item_ptr_(item),
item_(0) {
}
ListItem::ListItem(const unsigned int item)
: this_iter_(),
item_ptr_(0),
item_(item) {
}
ListItem::~ListItem() {
}
void* ListItem::GetItem() const {
return const_cast<void*>(item_ptr_);
}
unsigned int ListItem::GetUnsignedItem() const {
return item_;
}
ListWrapper::ListWrapper()
: list_() {
}
ListWrapper::~ListWrapper() {
if (!Empty()) {
// TODO(hellner) I'm not sure this loggin is useful.
WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,
"Potential memory leak in ListWrapper");
// Remove all remaining list items.
while (Erase(First()) == 0) {}
}
}
bool ListWrapper::Empty() const {
return list_.empty();
}
unsigned int ListWrapper::GetSize() const {
return list_.size();
}
int ListWrapper::PushBack(const void* ptr) {
ListItem* item = new ListItem(ptr);
list_.push_back(item);
return 0;
}
int ListWrapper::PushBack(const unsigned int item_id) {
ListItem* item = new ListItem(item_id);
list_.push_back(item);
return 0;
}
int ListWrapper::PushFront(const unsigned int item_id) {
ListItem* item = new ListItem(item_id);
list_.push_front(item);
return 0;
}
int ListWrapper::PushFront(const void* ptr) {
ListItem* item = new ListItem(ptr);
list_.push_front(item);
return 0;
}
int ListWrapper::PopFront() {
if (list_.empty()) {
return -1;
}
list_.pop_front();
return 0;
}
int ListWrapper::PopBack() {
if (list_.empty()) {
return -1;
}
list_.pop_back();
return 0;
}
ListItem* ListWrapper::First() const {
if (list_.empty()) {
return NULL;
}
std::list<ListItem*>::iterator item_iter = list_.begin();
ListItem* return_item = (*item_iter);
return_item->this_iter_ = item_iter;
return return_item;
}
ListItem* ListWrapper::Last() const {
if (list_.empty()) {
return NULL;
}
// std::list::end() addresses the last item + 1. Decrement so that the
// actual last is accessed.
std::list<ListItem*>::iterator item_iter = list_.end();
--item_iter;
ListItem* return_item = (*item_iter);
return_item->this_iter_ = item_iter;
return return_item;
}
ListItem* ListWrapper::Next(ListItem* item) const {
if (item == NULL) {
return NULL;
}
std::list<ListItem*>::iterator item_iter = item->this_iter_;
++item_iter;
if (item_iter == list_.end()) {
return NULL;
}
ListItem* return_item = (*item_iter);
return_item->this_iter_ = item_iter;
return return_item;
}
ListItem* ListWrapper::Previous(ListItem* item) const {
if (item == NULL) {
return NULL;
}
std::list<ListItem*>::iterator item_iter = item->this_iter_;
if (item_iter == list_.begin()) {
return NULL;
}
--item_iter;
ListItem* return_item = (*item_iter);
return_item->this_iter_ = item_iter;
return return_item;
}
int ListWrapper::Insert(ListItem* existing_previous_item,
ListItem* new_item) {
// Allow existing_previous_item to be NULL if the list is empty.
// TODO(hellner) why allow this? Keep it as is for now to avoid
// breaking API contract.
if (!existing_previous_item && !Empty()) {
return -1;
}
if (!new_item) {
return -1;
}
std::list<ListItem*>::iterator insert_location = list_.begin();
if (!Empty()) {
insert_location = existing_previous_item->this_iter_;
if (insert_location != list_.end()) {
++insert_location;
}
}
list_.insert(insert_location, new_item);
return 0;
}
int ListWrapper::InsertBefore(ListItem* existing_next_item,
ListItem* new_item) {
// Allow existing_next_item to be NULL if the list is empty.
// Todo: why allow this? Keep it as is for now to avoid breaking API
// contract.
if (!existing_next_item && !Empty()) {
return -1;
}
if (!new_item) {
return -1;
}
std::list<ListItem*>::iterator insert_location = list_.begin();
if (!Empty()) {
insert_location = existing_next_item->this_iter_;
}
list_.insert(insert_location, new_item);
return 0;
}
int ListWrapper::Erase(ListItem* item) {
if (item == NULL) {
return -1;
}
list_.erase(item->this_iter_);
return 0;
}
} // namespace webrtc

View File

@ -1,65 +0,0 @@
/*
* 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.
*/
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_
#include <list>
#include "webrtc/system_wrappers/interface/constructor_magic.h"
namespace webrtc {
class ListItem {
public:
ListItem(const void* ptr);
ListItem(const unsigned int item);
virtual ~ListItem();
void* GetItem() const;
unsigned int GetUnsignedItem() const;
private:
friend class ListWrapper;
mutable std::list<ListItem*>::iterator this_iter_;
const void* item_ptr_;
const unsigned int item_;
DISALLOW_COPY_AND_ASSIGN(ListItem);
};
class ListWrapper {
public:
ListWrapper();
~ListWrapper();
// ListWrapper functions
unsigned int GetSize() const;
int PushBack(const void* ptr);
int PushBack(const unsigned int item_id);
int PushFront(const void* ptr);
int PushFront(const unsigned int item_id);
int PopFront();
int PopBack();
bool Empty() const;
ListItem* First() const;
ListItem* Last() const;
ListItem* Next(ListItem* item) const;
ListItem* Previous(ListItem* item) const;
int Erase(ListItem* item);
int Insert(ListItem* existing_previous_item, ListItem* new_item);
int InsertBefore(ListItem* existing_next_item, ListItem* new_item);
private:
mutable std::list<ListItem*> list_;
DISALLOW_COPY_AND_ASSIGN(ListWrapper);
};
} // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_LIST_STL_H_

View File

@ -1,475 +0,0 @@
/*
* 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 "webrtc/system_wrappers/interface/list_wrapper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/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()));
}

View File

@ -37,7 +37,6 @@
'../interface/event_wrapper.h',
'../interface/file_wrapper.h',
'../interface/fix_interlocked_exchange_pointer_win.h',
'../interface/list_wrapper.h',
'../interface/logcat_trace_context.h',
'../interface/logging.h',
'../interface/ref_count.h',
@ -83,7 +82,6 @@
'event_win.h',
'file_impl.cc',
'file_impl.h',
'list_no_stl.cc',
'logcat_trace_context.cc',
'logging.cc',
'rw_lock.cc',

View File

@ -23,7 +23,6 @@
'condition_variable_unittest.cc',
'critical_section_unittest.cc',
'event_tracer_unittest.cc',
'list_unittest.cc',
'logging_unittest.cc',
'data_log_unittest.cc',
'data_log_unittest_disabled.cc',

View File

@ -1,174 +0,0 @@
/*
* 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 <stdio.h>
#include <stdlib.h>
#include "webrtc/system_wrappers/interface/list_wrapper.h"
const int kNumberOfElements = 10;
void FailTest(bool failed)
{
if (failed)
{
printf("Test failed!\n");
printf("Press enter to continue:");
getchar();
exit(0);
}
}
int GetStoredIntegerValue(ListItem* list_item)
{
void* list_item_pointer = list_item->GetItem();
if (list_item_pointer != NULL)
{
return *(reinterpret_cast<int*>(list_item_pointer));
}
return static_cast<int>(list_item->GetUnsignedItem());
}
void PrintList(ListWrapper& list)
{
ListItem* list_item = list.First();
printf("List: ");
while (list_item != NULL)
{
int item_value = GetStoredIntegerValue(list_item);
FailTest(item_value < 0);
printf(" %d",item_value);
list_item = list.Next(list_item);
}
printf("\n");
}
// The list should always be in ascending order
void ListSanity(ListWrapper& list)
{
if(list.Empty())
{
return;
}
ListItem* item_iter = list.First();
// Fake a previous value for the first iteration
int previous_value = GetStoredIntegerValue(item_iter) - 1;
while (item_iter != NULL)
{
const int value = GetStoredIntegerValue(item_iter);
FailTest(value != previous_value + 1);
previous_value = value;
item_iter = list.Next(item_iter);
}
}
int main(int /*argc*/, char* /*argv*/[])
{
printf("List Test:\n");
int element_array[kNumberOfElements];
for (int i = 0; i < kNumberOfElements; i++)
{
element_array[i] = i;
}
// Test PushBack 1
ListWrapper test_list;
for (int i = 2; i < kNumberOfElements - 2; i++)
{
FailTest(test_list.PushBack((void*)&element_array[i]) != 0);
}
// Test PushBack 2
FailTest(test_list.PushBack(element_array[kNumberOfElements - 2]) != 0);
FailTest(test_list.PushBack(element_array[kNumberOfElements - 1]) != 0);
// Test PushFront 2
FailTest(test_list.PushFront(element_array[1]) != 0);
// Test PushFront 1
FailTest(test_list.PushFront((void*)&element_array[0]) != 0);
// Test GetSize
FailTest(test_list.GetSize() != kNumberOfElements);
PrintList(test_list);
//Test PopFront
FailTest(test_list.PopFront() != 0);
//Test PopBack
FailTest(test_list.PopBack() != 0);
// Test GetSize
FailTest(test_list.GetSize() != kNumberOfElements - 2);
// Test Empty
FailTest(test_list.Empty());
// Test First
ListItem* first_item = test_list.First();
FailTest(first_item == NULL);
// Test Last
ListItem* last_item = test_list.Last();
FailTest(last_item == NULL);
// Test Next
ListItem* second_item = test_list.Next(first_item);
FailTest(second_item == NULL);
FailTest(test_list.Next(last_item) != NULL);
FailTest(test_list.Next(NULL) != NULL);
// Test Previous
ListItem* second_to_last_item = test_list.Previous(last_item);
FailTest(second_to_last_item == NULL);
FailTest(test_list.Previous(first_item) != NULL);
FailTest(test_list.Previous(NULL) != NULL);
// Test GetUnsignedItem
FailTest(last_item->GetUnsignedItem() !=
kNumberOfElements - 2);
FailTest(last_item->GetItem() !=
NULL);
// Test GetItem
FailTest(GetStoredIntegerValue(second_to_last_item) !=
kNumberOfElements - 3);
FailTest(second_to_last_item->GetUnsignedItem() != 0);
// Pop last and first since they are pushed as unsigned items.
FailTest(test_list.PopFront() != 0);
FailTest(test_list.PopBack() != 0);
// Test Insert. Please note that old iterators are no longer valid at
// this point.
ListItem* insert_item_last = new ListItem(reinterpret_cast<void*>(&element_array[kNumberOfElements - 2]));
FailTest(test_list.Insert(test_list.Last(),insert_item_last) != 0);
FailTest(test_list.Insert(NULL,insert_item_last) == 0);
ListItem* insert_item_last2 = new ListItem(reinterpret_cast<void*>(&element_array[kNumberOfElements - 2]));
FailTest(test_list.Insert(insert_item_last2,NULL) == 0);
// test InsertBefore
ListItem* insert_item_first = new ListItem(reinterpret_cast<void*>(&element_array[1]));
FailTest(test_list.InsertBefore(test_list.First(),insert_item_first) != 0);
FailTest(test_list.InsertBefore(NULL,insert_item_first) == 0);
ListItem* insert_item_first2 = new ListItem(reinterpret_cast<void*>(&element_array[1]));
FailTest(test_list.InsertBefore(insert_item_first2,NULL) == 0);
PrintList(test_list);
ListSanity(test_list);
// Erase the whole list
int counter = 0;
while (test_list.PopFront() == 0)
{
FailTest(counter++ > kNumberOfElements);
}
PrintList(test_list);
// Test APIs when list is empty
FailTest(test_list.GetSize() != 0);
FailTest(test_list.PopFront() != -1);
FailTest(test_list.PopBack() != -1);
FailTest(!test_list.Empty());
FailTest(test_list.First() != NULL);
FailTest(test_list.Last() != NULL);
FailTest(test_list.Next(NULL) != NULL);
FailTest(test_list.Previous(NULL) != NULL);
FailTest(test_list.Erase(NULL) != -1);
// Test Insert APIs when list is empty
ListItem* new_item = new ListItem(reinterpret_cast<void*>(&element_array[0]));
FailTest(test_list.Insert(NULL,new_item) != 0);
FailTest(test_list.Empty());
FailTest(test_list.PopFront() != 0);
ListItem* new_item2 = new ListItem(reinterpret_cast<void*>(&element_array[0]));
FailTest(test_list.InsertBefore(NULL,new_item2) != 0);
FailTest(test_list.Empty());
printf("Tests passed successfully!\n");
}