* Copyright 2014, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "ImageDebugLoadingStateHandlerRoster.h"
#include <new>
#include <AutoDeleter.h>
#include <AutoLocker.h>
#include "DwarfLoadingStateHandler.h"
#include "ImageDebugInfoLoadingState.h"
#include "ImageDebugLoadingStateHandler.h"
#include "SpecificImageDebugInfoLoadingState.h"
ImageDebugLoadingStateHandlerRoster*
ImageDebugLoadingStateHandlerRoster::sDefaultInstance = NULL;
ImageDebugLoadingStateHandlerRoster::ImageDebugLoadingStateHandlerRoster()
:
fLock("loading state handler roster"),
fStateHandlers(20)
{
}
ImageDebugLoadingStateHandlerRoster::~ImageDebugLoadingStateHandlerRoster()
{
for (int32 i = 0; ImageDebugLoadingStateHandler* handler
= fStateHandlers.ItemAt(i); i++) {
handler->ReleaseReference();
}
}
ImageDebugLoadingStateHandlerRoster*
ImageDebugLoadingStateHandlerRoster::Default()
{
return sDefaultInstance;
}
status_t
ImageDebugLoadingStateHandlerRoster::CreateDefault()
{
if (sDefaultInstance != NULL)
return B_OK;
ImageDebugLoadingStateHandlerRoster* roster
= new(std::nothrow) ImageDebugLoadingStateHandlerRoster;
if (roster == NULL)
return B_NO_MEMORY;
ObjectDeleter<ImageDebugLoadingStateHandlerRoster> rosterDeleter(roster);
status_t error = roster->Init();
if (error != B_OK)
return error;
error = roster->RegisterDefaultHandlers();
if (error != B_OK)
return error;
sDefaultInstance = rosterDeleter.Detach();
return B_OK;
}
void
ImageDebugLoadingStateHandlerRoster::DeleteDefault()
{
ImageDebugLoadingStateHandlerRoster* roster = sDefaultInstance;
sDefaultInstance = NULL;
delete roster;
}
status_t
ImageDebugLoadingStateHandlerRoster::Init()
{
return fLock.InitCheck();
}
status_t
ImageDebugLoadingStateHandlerRoster::RegisterDefaultHandlers()
{
ImageDebugLoadingStateHandler* handler;
BReference<ImageDebugLoadingStateHandler> handlerReference;
handler = new(std::nothrow) DwarfLoadingStateHandler();
if (handler == NULL)
return B_NO_MEMORY;
handlerReference.SetTo(handler, true);
if (!RegisterHandler(handler))
return B_NO_MEMORY;
return B_OK;
}
status_t
ImageDebugLoadingStateHandlerRoster::FindStateHandler(
SpecificImageDebugInfoLoadingState* state,
ImageDebugLoadingStateHandler*& _handler)
{
AutoLocker<BLocker> locker(fLock);
bool found = false;
ImageDebugLoadingStateHandler* handler = NULL;
for (int32 i = 0; (handler = fStateHandlers.ItemAt(i)); i++) {
if ((found = handler->SupportsState(state)))
break;
}
if (!found)
return B_ENTRY_NOT_FOUND;
handler->AcquireReference();
_handler = handler;
return B_OK;
}
bool
ImageDebugLoadingStateHandlerRoster::RegisterHandler(
ImageDebugLoadingStateHandler* handler)
{
if (!fStateHandlers.AddItem(handler))
return false;
handler->AcquireReference();
return true;
}
void
ImageDebugLoadingStateHandlerRoster::UnregisterHandler(
ImageDebugLoadingStateHandler* handler)
{
if (fStateHandlers.RemoveItem(handler))
handler->ReleaseReference();
}