| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* ---- includes ----------------------------------------------------------- */ |
| |
| #include "b_BasicEm/Functions.h" |
| #include "b_BasicEm/Context.h" |
| #include "b_BasicEm/String.h" |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /* ========================================================================= */ |
| /* */ |
| /* ---- \ghd{ auxiliary functions } ---------------------------------------- */ |
| /* */ |
| /* ========================================================================= */ |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /* ========================================================================= */ |
| /* */ |
| /* ---- \ghd{ constructor / destructor } ----------------------------------- */ |
| /* */ |
| /* ========================================================================= */ |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| void bbs_Context_init( struct bbs_Context* cpA ) |
| { |
| uint32 iL; |
| for( iL = 0; iL < bbs_CONTEXT_MAX_ERRORS; iL++ ) |
| { |
| cpA->errStackE[ iL ].errorE = bbs_ERR_OK; |
| cpA->errStackE[ iL ].fileE[ 0 ] = 0; |
| cpA->errStackE[ iL ].lineE = 0; |
| cpA->errStackE[ iL ].textE[ 0 ] = 0; |
| } |
| |
| cpA->errIndexE = 0; |
| |
| bbs_MemTbl_init( cpA, &cpA->memTblE ); |
| |
| for( iL = 0; iL < bbs_CONTEXT_MAX_MEM_MANAGERS; iL++ ) |
| { |
| bbs_DynMemManager_init( cpA, &cpA->dynMemManagerArrE[ iL ] ); |
| } |
| |
| cpA->dynMemManagerArrSizeE = 0; |
| cpA->errorHandlerE = NULL; |
| cpA->callbackHandlerE = NULL; |
| cpA->userPtrE = NULL; |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| void bbs_Context_exit( struct bbs_Context* cpA ) |
| { |
| uint32 iL; |
| for( iL = 0; iL < bbs_CONTEXT_MAX_ERRORS; iL++ ) |
| { |
| cpA->errStackE[ iL ].errorE = bbs_ERR_OK; |
| cpA->errStackE[ iL ].fileE[ 0 ] = 0; |
| cpA->errStackE[ iL ].lineE = 0; |
| cpA->errStackE[ iL ].textE[ 0 ] = 0; |
| } |
| |
| cpA->errIndexE = 0; |
| |
| bbs_MemTbl_exit( cpA, &cpA->memTblE ); |
| |
| for( iL = 0; iL < cpA->dynMemManagerArrSizeE; iL++ ) |
| { |
| bbs_DynMemManager_freeAll( cpA, &cpA->dynMemManagerArrE[ iL ] ); |
| } |
| |
| for( iL = 0; iL < bbs_CONTEXT_MAX_MEM_MANAGERS; iL++ ) |
| { |
| bbs_DynMemManager_exit( cpA, &cpA->dynMemManagerArrE[ iL ] ); |
| } |
| |
| cpA->dynMemManagerArrSizeE = 0; |
| cpA->errorHandlerE = NULL; |
| cpA->callbackHandlerE = NULL; |
| cpA->userPtrE = NULL; |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /* ========================================================================= */ |
| /* */ |
| /* ---- \ghd{ operators } -------------------------------------------------- */ |
| /* */ |
| /* ========================================================================= */ |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| void bbs_Context_copy( struct bbs_Context* cpA, const struct bbs_Context* srcPtrA ) |
| { |
| bbs_ERROR0( "void bbs_Context_copy( struct bbs_Context* cpA, const struct bbs_Context* srcPtrA ):\n" |
| "A comtext object cannot be copied" ); |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /* ========================================================================= */ |
| /* */ |
| /* ---- \ghd{ query functions } -------------------------------------------- */ |
| /* */ |
| /* ========================================================================= */ |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /* ========================================================================= */ |
| /* */ |
| /* ---- \ghd{ modify functions } ------------------------------------------- */ |
| /* */ |
| /* ========================================================================= */ |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| struct bbs_Error bbs_Error_create( uint32 errorA, |
| uint32 lineA, |
| const char* fileA, |
| const char* textA, |
| ... ) |
| { |
| struct bbs_Error errorL; |
| errorL.errorE = errorA; |
| errorL.lineE = lineA; |
| |
| if( fileA != NULL ) |
| { |
| uint32 lenL = bbs_strlen( fileA ); |
| uint32 ofsL = ( lenL + 1 > bbs_ERROR_MAX_FILE_CHARS ) ? lenL + 1 - bbs_ERROR_MAX_FILE_CHARS : 0; |
| bbs_strcpy( errorL.fileE, fileA + ofsL ); |
| } |
| else |
| { |
| errorL.fileE[ 0 ] = 0; |
| } |
| |
| if( textA != NULL ) |
| { |
| va_list argsL; |
| va_start( argsL, textA ); |
| bbs_vsnprintf( errorL.textE, bbs_ERROR_MAX_TEXT_CHARS, textA, argsL ); |
| va_end( argsL ); |
| } |
| else |
| { |
| errorL.textE[ 0 ] = 0; |
| } |
| |
| return errorL; |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /* ========================================================================= */ |
| /* */ |
| /* ---- \ghd{ I/O } -------------------------------------------------------- */ |
| /* */ |
| /* ========================================================================= */ |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /* ========================================================================= */ |
| /* */ |
| /* ---- \ghd{ exec functions } --------------------------------------------- */ |
| /* */ |
| /* ========================================================================= */ |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| flag bbs_Context_pushError( struct bbs_Context* cpA, struct bbs_Error errorA ) |
| { |
| flag returnL = FALSE; |
| if( cpA->errIndexE < bbs_CONTEXT_MAX_ERRORS ) |
| { |
| cpA->errStackE[ cpA->errIndexE++ ] = errorA; |
| returnL = TRUE; |
| } |
| |
| if( cpA->errorHandlerE != NULL ) |
| { |
| cpA->errorHandlerE( cpA ); |
| } |
| |
| return returnL; |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| struct bbs_Error bbs_Context_popError( struct bbs_Context* cpA ) |
| { |
| if( cpA->errIndexE > 0 ) |
| { |
| return cpA->errStackE[ --( cpA->errIndexE ) ]; |
| } |
| else |
| { |
| return cpA->errStackE[ 0 ]; |
| } |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| struct bbs_Error bbs_Context_peekError( struct bbs_Context* cpA ) |
| { |
| if( cpA->errIndexE > 0 ) |
| { |
| return cpA->errStackE[ cpA->errIndexE - 1 ]; |
| } |
| else |
| { |
| return cpA->errStackE[ 0 ]; |
| } |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| flag bbs_Context_error( struct bbs_Context* cpA ) |
| { |
| return cpA->errIndexE > 0; |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| bbs_errorFPtr bbs_Context_setErrorHandler( struct bbs_Context* cpA, |
| bbs_errorFPtr errorHandlerA ) |
| { |
| bbs_errorFPtr oldErrorHandlerL = cpA->errorHandlerE; |
| cpA->errorHandlerE = errorHandlerA; |
| return oldErrorHandlerL; |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| void bbs_Context_doCallback( struct bbs_Context* cpA ) |
| { |
| if( cpA->callbackHandlerE != NULL ) |
| { |
| uint32 errorL = ( *cpA->callbackHandlerE )( cpA ); |
| if( errorL != bbs_ERR_OK ) |
| { |
| bbs_Context_pushError( cpA, bbs_Error_create( errorL, 0, NULL, NULL ) ); |
| } |
| } |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| bbs_callbackFPtr bbs_Context_setCallbackHandler( struct bbs_Context* cpA, |
| bbs_callbackFPtr callbackHandlerA ) |
| { |
| bbs_callbackFPtr oldCallbackHandlerL = cpA->callbackHandlerE; |
| cpA->callbackHandlerE = callbackHandlerA; |
| return oldCallbackHandlerL; |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /** adds a static memory segment to memory table of context */ |
| void bbs_Context_addStaticSeg( struct bbs_Context* cpA, |
| uint16* memPtrA, /* pointer to memory */ |
| uint32 sizeA, /* size of memory segment in 16 bit units */ |
| flag sharedA, /* Indicates that this segment is to be shared among multiple objects */ |
| uint32 idA ) /* ID of segment, id=0: unspecified */ |
| { |
| struct bbs_MemSeg memSegL; |
| bbs_DEF_fNameL( "void bbs_Context_addStaticSeg(....)" ) |
| |
| |
| /* checks */ |
| if( sharedA && cpA->memTblE.ssSizeE == bbs_MAX_MEM_SEGS ) |
| { |
| bbs_ERROR1( "%s:\nShared Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL ); |
| return; |
| } |
| if( sharedA && cpA->memTblE.esSizeE == bbs_MAX_MEM_SEGS ) |
| { |
| bbs_ERROR1( "%s:\nExclusive Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL ); |
| return; |
| } |
| |
| |
| bbs_MemSeg_init( cpA, &memSegL ); |
| memSegL.memPtrE = memPtrA; |
| memSegL.sizeE = sizeA; |
| memSegL.allocIndexE = 0; |
| memSegL.sharedE = sharedA; |
| memSegL.idE = idA; |
| memSegL.dynMemManagerPtrE = NULL; |
| |
| if( sharedA ) |
| { |
| cpA->memTblE.ssArrE[ cpA->memTblE.ssSizeE++ ] = memSegL; |
| } |
| else |
| { |
| cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ] = memSegL; |
| cpA->memTblE.espArrE[ cpA->memTblE.esSizeE ] = &cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ]; |
| cpA->memTblE.esSizeE++; |
| } |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /* adds a dynamic memory segment to memory table of context |
| * Upon destruction of the context object any residual will be freed automatically |
| */ |
| void bbs_Context_addDynamicSeg( struct bbs_Context* cpA, |
| bbs_mallocFPtr mallocFPtrA, /* function pointer to external mem alloc function (s. comment of type declaration)*/ |
| bbs_freeFPtr freeFPtrA, /* function pointer to external mem free function */ |
| flag sharedA, /* Indicates that this segment is to be shared among multiple objects */ |
| uint32 idA ) /* ID of segment, id=0: unspecified */ |
| { |
| struct bbs_DynMemManager memManagerL; |
| struct bbs_MemSeg memSegL; |
| bbs_DEF_fNameL( "void bbs_Context_addDynamicSeg(....)" ) |
| |
| |
| /* checks */ |
| if( cpA->dynMemManagerArrSizeE == bbs_CONTEXT_MAX_MEM_MANAGERS ) |
| { |
| bbs_ERROR1( "%s:\nMemory Manager Table is full! Increase bbs_CONTEXT_MAX_MEM_MANAGERS", fNameL ); |
| return; |
| } |
| if( sharedA && cpA->memTblE.ssSizeE == bbs_MAX_MEM_SEGS ) |
| { |
| bbs_ERROR1( "%s:\nShared Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL ); |
| return; |
| } |
| if( sharedA && cpA->memTblE.esSizeE == bbs_MAX_MEM_SEGS ) |
| { |
| bbs_ERROR1( "%s:\nExclusive Memory Table is full! Increase bbs_MAX_MEM_SEGS", fNameL ); |
| return; |
| } |
| |
| bbs_DynMemManager_init( cpA, &memManagerL ); |
| memManagerL.mallocFPtrE = mallocFPtrA; |
| memManagerL.freeFPtrE = freeFPtrA; |
| memManagerL.memPtrE = NULL; |
| cpA->dynMemManagerArrE[ cpA->dynMemManagerArrSizeE++ ] = memManagerL; |
| |
| bbs_MemSeg_init( cpA, &memSegL ); |
| memSegL.memPtrE = NULL; |
| memSegL.sizeE = 0; |
| memSegL.allocIndexE = 0; |
| memSegL.sharedE = sharedA; |
| memSegL.idE = idA; |
| memSegL.dynMemManagerPtrE = &cpA->dynMemManagerArrE[ cpA->dynMemManagerArrSizeE - 1 ]; |
| |
| if( sharedA ) |
| { |
| cpA->memTblE.ssArrE[ cpA->memTblE.ssSizeE++ ] = memSegL; |
| } |
| else |
| { |
| cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ] = memSegL; |
| cpA->memTblE.espArrE[ cpA->memTblE.esSizeE ] = &cpA->memTblE.esArrE[ cpA->memTblE.esSizeE ]; |
| cpA->memTblE.esSizeE++; |
| } |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| uint32 bbs_Context_exclAllocSize( struct bbs_Context* cpA, uint32 segIndexA ) |
| { |
| return bbs_MemSeg_allocatedSize( cpA, &cpA->memTblE.esArrE[ segIndexA ] ); |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| uint32 bbs_Context_shrdAllocSize( struct bbs_Context* cpA, uint32 segIndexA ) |
| { |
| return bbs_MemSeg_allocatedSize( cpA, &cpA->memTblE.ssArrE[ segIndexA ] ); |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| void bbs_Context_quickInit( struct bbs_Context* cpA, |
| bbs_mallocFPtr mallocFPtrA, /* function pointer to external mem alloc function (s. comment of type declaration)*/ |
| bbs_freeFPtr freeFPtrA, |
| bbs_errorFPtr errorHandlerA ) |
| { |
| bbs_Context_init( cpA ); |
| bbs_Context_addDynamicSeg( cpA, mallocFPtrA, freeFPtrA, FALSE, 0 ); |
| bbs_Context_addDynamicSeg( cpA, mallocFPtrA, freeFPtrA, TRUE, 0 ); |
| bbs_Context_setErrorHandler( cpA, errorHandlerA ); |
| } |
| |
| /* ------------------------------------------------------------------------- */ |
| |
| /* ========================================================================= */ |
| |
| |