1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* ---- includes ----------------------------------------------------------- */
18
19#include "b_BasicEm/Functions.h"
20#include "b_BasicEm/Context.h"
21#include "b_BasicEm/String.h"
22
23/* ------------------------------------------------------------------------- */
24
25/* ========================================================================= */
26/*                                                                           */
27/* ---- \ghd{ auxiliary functions } ---------------------------------------- */
28/*                                                                           */
29/* ========================================================================= */
30
31/* ------------------------------------------------------------------------- */
32
33/* ========================================================================= */
34/*                                                                           */
35/* ---- \ghd{ constructor / destructor } ----------------------------------- */
36/*                                                                           */
37/* ========================================================================= */
38
39/* ------------------------------------------------------------------------- */
40
41void bbs_Context_init( struct bbs_Context* cpA )
42{
43	uint32 iL;
44	for( iL = 0; iL < bbs_CONTEXT_MAX_ERRORS; iL++ )
45	{
46		cpA->errStackE[ iL ].errorE = bbs_ERR_OK;
47		cpA->errStackE[ iL ].fileE[ 0 ] = 0;
48		cpA->errStackE[ iL ].lineE = 0;
49		cpA->errStackE[ iL ].textE[ 0 ] = 0;
50	}
51
52	cpA->errIndexE = 0;
53
54	bbs_MemTbl_init( cpA, &cpA->memTblE );
55
56	for( iL = 0; iL < bbs_CONTEXT_MAX_MEM_MANAGERS; iL++ )
57	{
58		bbs_DynMemManager_init( cpA, &cpA->dynMemManagerArrE[ iL ] );
59	}
60
61	cpA->dynMemManagerArrSizeE = 0;
62	cpA->errorHandlerE = NULL;
63	cpA->callbackHandlerE = NULL;
64	cpA->userPtrE = NULL;
65}
66
67/* ------------------------------------------------------------------------- */
68
69void bbs_Context_exit( struct bbs_Context* cpA )
70{
71	uint32 iL;
72	for( iL = 0; iL < bbs_CONTEXT_MAX_ERRORS; iL++ )
73	{
74		cpA->errStackE[ iL ].errorE = bbs_ERR_OK;
75		cpA->errStackE[ iL ].fileE[ 0 ] = 0;
76		cpA->errStackE[ iL ].lineE = 0;
77		cpA->errStackE[ iL ].textE[ 0 ] = 0;
78	}
79
80	cpA->errIndexE = 0;
81
82	bbs_MemTbl_exit( cpA, &cpA->memTblE );
83
84	for( iL = 0; iL < cpA->dynMemManagerArrSizeE; iL++ )
85	{
86		bbs_DynMemManager_freeAll( cpA, &cpA->dynMemManagerArrE[ iL ] );
87	}
88
89	for( iL = 0; iL < bbs_CONTEXT_MAX_MEM_MANAGERS; iL++ )
90	{
91		bbs_DynMemManager_exit( cpA, &cpA->dynMemManagerArrE[ iL ] );
92	}
93
94	cpA->dynMemManagerArrSizeE = 0;
95	cpA->errorHandlerE = NULL;
96	cpA->callbackHandlerE = NULL;
97	cpA->userPtrE = NULL;
98}
99
100/* ------------------------------------------------------------------------- */
101
102/* ========================================================================= */
103/*                                                                           */
104/* ---- \ghd{ operators } -------------------------------------------------- */
105/*                                                                           */
106/* ========================================================================= */
107
108/* ------------------------------------------------------------------------- */
109
110void bbs_Context_copy( struct bbs_Context* cpA, const struct bbs_Context* srcPtrA )
111{
112	bbs_ERROR0( "void bbs_Context_copy( struct bbs_Context* cpA, const struct bbs_Context* srcPtrA ):\n"
113		        "A comtext object cannot be copied" );
114}
115
116/* ------------------------------------------------------------------------- */
117
118/* ========================================================================= */
119/*                                                                           */
120/* ---- \ghd{ query functions } -------------------------------------------- */
121/*                                                                           */
122/* ========================================================================= */
123
124/* ------------------------------------------------------------------------- */
125
126/* ========================================================================= */
127/*                                                                           */
128/* ---- \ghd{ modify functions } ------------------------------------------- */
129/*                                                                           */
130/* ========================================================================= */
131
132/* ------------------------------------------------------------------------- */
133
134struct bbs_Error bbs_Error_create( uint32 errorA,
135								   uint32 lineA,
136								   const char* fileA,
137								   const char* textA,
138								   ... )
139{
140	struct bbs_Error errorL;
141	errorL.errorE = errorA;
142	errorL.lineE = lineA;
143
144	if( fileA != NULL )
145	{
146		uint32 lenL = bbs_strlen( fileA );
147		uint32 ofsL = ( lenL + 1 > bbs_ERROR_MAX_FILE_CHARS ) ? lenL + 1 - bbs_ERROR_MAX_FILE_CHARS : 0;
148		bbs_strcpy( errorL.fileE, fileA + ofsL );
149	}
150	else
151	{
152		errorL.fileE[ 0 ] = 0;
153	}
154
155	if( textA != NULL )
156	{
157		va_list argsL;
158		va_start( argsL, textA );
159		bbs_vsnprintf( errorL.textE, bbs_ERROR_MAX_TEXT_CHARS, textA, argsL );
160		va_end( argsL );
161	}
162	else
163	{
164		errorL.textE[ 0 ] = 0;
165	}
166
167	return errorL;
168}
169
170/* ------------------------------------------------------------------------- */
171
172/* ========================================================================= */
173/*                                                                           */
174/* ---- \ghd{ I/O } -------------------------------------------------------- */
175/*                                                                           */
176/* ========================================================================= */
177
178/* ------------------------------------------------------------------------- */
179
180/* ========================================================================= */
181/*                                                                           */
182/* ---- \ghd{ exec functions } --------------------------------------------- */
183/*                                                                           */
184/* ========================================================================= */
185
186/* ------------------------------------------------------------------------- */
187
188flag bbs_Context_pushError( struct bbs_Context* cpA, struct bbs_Error errorA )
189{
190	flag returnL = FALSE;
191	if( cpA->errIndexE < bbs_CONTEXT_MAX_ERRORS )
192	{
193		cpA->errStackE[ cpA->errIndexE++ ] = errorA;
194		returnL = TRUE;
195	}
196
197	if( cpA->errorHandlerE != NULL )
198	{
199		cpA->errorHandlerE( cpA );
200	}
201
202	return returnL;
203}
204
205/* ------------------------------------------------------------------------- */
206
207struct bbs_Error bbs_Context_popError( struct bbs_Context* cpA )
208{
209	if( cpA->errIndexE > 0 )
210	{
211		return cpA->errStackE[ --( cpA->errIndexE ) ];
212	}
213	else
214	{
215		return cpA->errStackE[ 0 ];
216	}
217}
218
219/* ------------------------------------------------------------------------- */
220
221struct bbs_Error bbs_Context_peekError( struct bbs_Context* cpA )
222{
223	if( cpA->errIndexE > 0 )
224	{
225		return cpA->errStackE[ cpA->errIndexE - 1 ];
226	}
227	else
228	{
229		return cpA->errStackE[ 0 ];
230	}
231}
232
233/* ------------------------------------------------------------------------- */
234
235flag bbs_Context_error( struct bbs_Context* cpA )
236{
237	return cpA->errIndexE > 0;
238}
239
240/* ------------------------------------------------------------------------- */
241
242bbs_errorFPtr bbs_Context_setErrorHandler( struct bbs_Context* cpA,
243									       bbs_errorFPtr errorHandlerA )
244{
245	bbs_errorFPtr oldErrorHandlerL = cpA->errorHandlerE;
246	cpA->errorHandlerE = errorHandlerA;
247	return oldErrorHandlerL;
248}
249
250/* ------------------------------------------------------------------------- */
251
252void bbs_Context_doCallback( struct bbs_Context* cpA )
253{
254	if( cpA->callbackHandlerE != NULL )
255	{
256		uint32 errorL = ( *cpA->callbackHandlerE )( cpA );
257		if( errorL != bbs_ERR_OK )
258		{
259			bbs_Context_pushError( cpA, bbs_Error_create( errorL, 0, NULL, NULL ) );
260		}
261	}
262}
263
264/* ------------------------------------------------------------------------- */
265
266bbs_callbackFPtr bbs_Context_setCallbackHandler( struct bbs_Context* cpA,
267									       bbs_callbackFPtr callbackHandlerA )
268{
269	bbs_callbackFPtr oldCallbackHandlerL = cpA->callbackHandlerE;
270	cpA->callbackHandlerE = callbackHandlerA;
271	return oldCallbackHandlerL;
272}
273
274/* ------------------------------------------------------------------------- */
275
276/** adds a static memory segment to memory table of context */
277void bbs_Context_addStaticSeg(	struct bbs_Context* cpA,
278							    uint16* memPtrA, /* pointer to memory */
279								uint32 sizeA,    /* size of memory segment in 16 bit units */
280								flag sharedA,    /* Indicates that this segment is to be shared among multiple objects */
281								uint32 idA )     /* ID of segment, id=0: unspecified */
282{
283	struct bbs_MemSeg memSegL;
284	bbs_DEF_fNameL( "void bbs_Context_addStaticSeg(....)" )
285
286
287	/* checks */
288	if( sharedA && cpA->memTblE.ssSizeE == bbs_MAX_MEM_SEGS )
289	{
290		bbs_ERROR1( "%s:\nShared Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL );
291		return;
292	}
293	if( sharedA && cpA->memTblE.esSizeE == bbs_MAX_MEM_SEGS )
294	{
295		bbs_ERROR1( "%s:\nExclusive Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL );
296		return;
297	}
298
299
300	bbs_MemSeg_init( cpA, &memSegL );
301	memSegL.memPtrE = memPtrA;
302	memSegL.sizeE = sizeA;
303	memSegL.allocIndexE = 0;
304	memSegL.sharedE = sharedA;
305	memSegL.idE = idA;
306	memSegL.dynMemManagerPtrE = NULL;
307
308	if( sharedA )
309	{
310		cpA->memTblE.ssArrE[ cpA->memTblE.ssSizeE++ ] = memSegL;
311	}
312	else
313	{
314		cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ] = memSegL;
315		cpA->memTblE.espArrE[ cpA->memTblE.esSizeE ] = &cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ];
316		cpA->memTblE.esSizeE++;
317	}
318}
319
320/* ------------------------------------------------------------------------- */
321
322/* adds a dynamic memory segment to memory table of context
323 * Upon destruction of the context object any residual will be freed automatically
324 */
325void bbs_Context_addDynamicSeg(	struct bbs_Context* cpA,
326								bbs_mallocFPtr mallocFPtrA,	/* function pointer to external mem alloc function (s. comment of type declaration)*/
327								bbs_freeFPtr freeFPtrA,     /* function pointer to external mem free function */
328								flag sharedA,    /* Indicates that this segment is to be shared among multiple objects */
329								uint32 idA )     /* ID of segment, id=0: unspecified */
330{
331	struct bbs_DynMemManager memManagerL;
332	struct bbs_MemSeg memSegL;
333	bbs_DEF_fNameL( "void bbs_Context_addDynamicSeg(....)" )
334
335
336	/* checks */
337	if( cpA->dynMemManagerArrSizeE == bbs_CONTEXT_MAX_MEM_MANAGERS )
338	{
339		bbs_ERROR1( "%s:\nMemory Manager Table is full! Increase bbs_CONTEXT_MAX_MEM_MANAGERS", fNameL );
340		return;
341	}
342	if( sharedA && cpA->memTblE.ssSizeE == bbs_MAX_MEM_SEGS )
343	{
344		bbs_ERROR1( "%s:\nShared Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL );
345		return;
346	}
347	if( sharedA && cpA->memTblE.esSizeE == bbs_MAX_MEM_SEGS )
348	{
349		bbs_ERROR1( "%s:\nExclusive Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL );
350		return;
351	}
352
353	bbs_DynMemManager_init( cpA, &memManagerL );
354	memManagerL.mallocFPtrE = mallocFPtrA;
355	memManagerL.freeFPtrE = freeFPtrA;
356	memManagerL.memPtrE = NULL;
357	cpA->dynMemManagerArrE[ cpA->dynMemManagerArrSizeE++ ] = memManagerL;
358
359	bbs_MemSeg_init( cpA, &memSegL );
360	memSegL.memPtrE = NULL;
361	memSegL.sizeE = 0;
362	memSegL.allocIndexE = 0;
363	memSegL.sharedE = sharedA;
364	memSegL.idE = idA;
365	memSegL.dynMemManagerPtrE = &cpA->dynMemManagerArrE[ cpA->dynMemManagerArrSizeE - 1 ];
366
367	if( sharedA )
368	{
369		cpA->memTblE.ssArrE[ cpA->memTblE.ssSizeE++ ] = memSegL;
370	}
371	else
372	{
373		cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ] = memSegL;
374		cpA->memTblE.espArrE[ cpA->memTblE.esSizeE ] = &cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ];
375		cpA->memTblE.esSizeE++;
376	}
377}
378
379/* ------------------------------------------------------------------------- */
380
381uint32 bbs_Context_exclAllocSize( struct bbs_Context* cpA, uint32 segIndexA )
382{
383	return bbs_MemSeg_allocatedSize( cpA, &cpA->memTblE.esArrE[ segIndexA ] );
384}
385
386/* ------------------------------------------------------------------------- */
387
388uint32 bbs_Context_shrdAllocSize( struct bbs_Context* cpA, uint32 segIndexA )
389{
390	return bbs_MemSeg_allocatedSize( cpA, &cpA->memTblE.ssArrE[ segIndexA ] );
391}
392
393/* ------------------------------------------------------------------------- */
394
395void bbs_Context_quickInit( struct bbs_Context* cpA,
396	 					    bbs_mallocFPtr mallocFPtrA,	/* function pointer to external mem alloc function (s. comment of type declaration)*/
397						    bbs_freeFPtr freeFPtrA,
398						    bbs_errorFPtr errorHandlerA )
399{
400	bbs_Context_init( cpA );
401	bbs_Context_addDynamicSeg( cpA, mallocFPtrA, freeFPtrA, FALSE, 0 );
402	bbs_Context_addDynamicSeg( cpA, mallocFPtrA, freeFPtrA, TRUE, 0 );
403	bbs_Context_setErrorHandler( cpA, errorHandlerA );
404}
405
406/* ------------------------------------------------------------------------- */
407
408/* ========================================================================= */
409
410
411