1/*
2 * Copyright 2014, Rene Gollent, rene@gollent.com.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "ImageDebugLoadingStateHandlerRoster.h"
8
9#include <new>
10
11#include <AutoDeleter.h>
12#include <AutoLocker.h>
13
14#include "DwarfLoadingStateHandler.h"
15#include "ImageDebugInfoLoadingState.h"
16#include "ImageDebugLoadingStateHandler.h"
17#include "SpecificImageDebugInfoLoadingState.h"
18
19
20/*static*/ ImageDebugLoadingStateHandlerRoster*
21	ImageDebugLoadingStateHandlerRoster::sDefaultInstance = NULL;
22
23
24ImageDebugLoadingStateHandlerRoster::ImageDebugLoadingStateHandlerRoster()
25	:
26	fLock("loading state handler roster"),
27	fStateHandlers(20, false)
28{
29}
30
31
32ImageDebugLoadingStateHandlerRoster::~ImageDebugLoadingStateHandlerRoster()
33{
34	for (int32 i = 0; ImageDebugLoadingStateHandler* handler
35			= fStateHandlers.ItemAt(i); i++) {
36		handler->ReleaseReference();
37	}
38}
39
40
41/*static*/ ImageDebugLoadingStateHandlerRoster*
42ImageDebugLoadingStateHandlerRoster::Default()
43{
44	return sDefaultInstance;
45}
46
47
48/*static*/ status_t
49ImageDebugLoadingStateHandlerRoster::CreateDefault()
50{
51	if (sDefaultInstance != NULL)
52		return B_OK;
53
54	ImageDebugLoadingStateHandlerRoster* roster
55		= new(std::nothrow) ImageDebugLoadingStateHandlerRoster;
56	if (roster == NULL)
57		return B_NO_MEMORY;
58	ObjectDeleter<ImageDebugLoadingStateHandlerRoster> rosterDeleter(roster);
59
60	status_t error = roster->Init();
61	if (error != B_OK)
62		return error;
63
64	error = roster->RegisterDefaultHandlers();
65	if (error != B_OK)
66		return error;
67
68	sDefaultInstance = rosterDeleter.Detach();
69	return B_OK;
70}
71
72
73/*static*/ void
74ImageDebugLoadingStateHandlerRoster::DeleteDefault()
75{
76	ImageDebugLoadingStateHandlerRoster* roster = sDefaultInstance;
77	sDefaultInstance = NULL;
78	delete roster;
79}
80
81
82status_t
83ImageDebugLoadingStateHandlerRoster::Init()
84{
85	return fLock.InitCheck();
86}
87
88
89status_t
90ImageDebugLoadingStateHandlerRoster::RegisterDefaultHandlers()
91{
92	ImageDebugLoadingStateHandler* handler;
93	BReference<ImageDebugLoadingStateHandler> handlerReference;
94
95	handler = new(std::nothrow) DwarfLoadingStateHandler();
96	if (handler == NULL)
97		return B_NO_MEMORY;
98	handlerReference.SetTo(handler, true);
99
100	if (!RegisterHandler(handler))
101		return B_NO_MEMORY;
102
103	return B_OK;
104}
105
106
107status_t
108ImageDebugLoadingStateHandlerRoster::FindStateHandler(
109	SpecificImageDebugInfoLoadingState* state,
110	ImageDebugLoadingStateHandler*& _handler)
111{
112	AutoLocker<BLocker> locker(fLock);
113
114	bool found = false;
115	ImageDebugLoadingStateHandler* handler = NULL;
116	for (int32 i = 0; (handler = fStateHandlers.ItemAt(i)); i++) {
117		if ((found = handler->SupportsState(state)))
118			break;
119	}
120
121	if (!found)
122		return B_ENTRY_NOT_FOUND;
123
124	handler->AcquireReference();
125	_handler = handler;
126	return B_OK;
127}
128
129
130bool
131ImageDebugLoadingStateHandlerRoster::RegisterHandler(
132	ImageDebugLoadingStateHandler* handler)
133{
134	if (!fStateHandlers.AddItem(handler))
135		return false;
136
137	handler->AcquireReference();
138	return true;
139}
140
141
142void
143ImageDebugLoadingStateHandlerRoster::UnregisterHandler(
144	ImageDebugLoadingStateHandler* handler)
145{
146	if (fStateHandlers.RemoveItem(handler))
147		handler->ReleaseReference();
148}
149