1 /*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
4 for INTEL64(R), AMD64(R)
6 Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
17 THIS SOFTWARE IS PROVIDED BY Koine Yuusuke(koinec) ``AS IS'' AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL Koine Yuusuke(koinec) OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 OF THE POSSIBILITY OF SUCH DAMAGE.
29 DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
31 /* File Info -----------------------------------------------------------
35 ----------------------------------------------------------------------*/
37 #define DRD64_SRC_LIBGOBLIN_OBJINFO
38 #include"drd64_libgoblin.h"
40 #define LOCATION(n) DRD64_ERR_LOCATION( \
41 DRD64_ERROR_MODULE_LIBGOBLIN, DRD64_ERROR_ARCH_NODEPEND, \
42 DRD64_SRCID_LIBGOBLIN_OBJINFO, (n))
45 /*----------------------------------------------------------------------
46 ----------------------------------------------------------------------*/
47 #define FUNCID_LibGoblin_ObjectInfo_GetObjectInfo 0x14
48 LIBGOBLIN_OBJINFO_EXTERN
49 LibGoblin_ObjectInfo *
50 ObjectInfo_GetObjectInfo(
51 LibGoblin_ProgramInfo *p_pginfo,
54 assert( NULL != p_pginfo );
56 if(( p_pginfo->objinfo.i_alloced <= i_oid ) || ( 0 > i_oid )) {
60 return OBJINFO(p_pginfo, i_oid);
64 /*----------------------------------------------------------------------
65 ----------------------------------------------------------------------*/
66 #define FUNCID_LibGoblin_ObjectInfo_GetGroupChildTop 0x31
67 LIBGOBLIN_OBJINFO_EXTERN
68 LibGoblin_ObjectInfo *
69 ObjectInfo_GetGroupChildTop(
70 LibGoblin_ProgramInfo *p_pginfo,
71 LibGoblin_ObjectInfo *p_objinfo )
73 LibGoblin_ObjectInfo *pobj_ret = NULL;
75 assert( NULL != p_pginfo );
76 assert( NULL != p_objinfo );
78 if( NO_OBJ != p_objinfo->grplink.i_child_topid ) {
79 pobj_ret = OBJINFO( p_pginfo, p_objinfo->grplink.i_child_topid );
80 assert( p_objinfo->i_id == pobj_ret->grplink.i_parent_id );
87 /*----------------------------------------------------------------------
88 ----------------------------------------------------------------------*/
89 #define FUNCID_LibGoblin_ObjectInfo_GetGroupNext 0x32
90 LIBGOBLIN_OBJINFO_EXTERN
91 LibGoblin_ObjectInfo *
92 ObjectInfo_GetGroupNext(
93 LibGoblin_ProgramInfo *p_pginfo,
94 LibGoblin_ObjectInfo *p_objinfo )
96 LibGoblin_ObjectInfo *pobj_ret = NULL;
98 assert( NULL != p_pginfo );
99 assert( NULL != p_objinfo );
101 if( NO_OBJ != p_objinfo->grplink.i_next_id )
102 { pobj_ret = OBJINFO( p_pginfo, p_objinfo->grplink.i_next_id ); }
108 /*----------------------------------------------------------------------
109 ----------------------------------------------------------------------*/
110 #define FUNCID_LibGoblin_ObjectInfo_ClearObjectInfo 0x13
112 ObjectInfo_ClearObjectInfo(
113 LibGoblin_ObjectInfo *p_objinfo )
117 assert( NULL != p_objinfo );
119 i_id = p_objinfo->i_id;
120 memset( p_objinfo, 0x00, sizeof( LibGoblin_ObjectInfo ) );
122 p_objinfo->i_id = i_id;
123 p_objinfo->dw_status = OBJINFO_STATUS_INVALID; // Clear dw_status
125 p_objinfo->addrlink.i_next_id = NO_OBJ;
126 p_objinfo->addrlink.i_prev_id = NO_OBJ;
128 p_objinfo->grplink.i_parent_id = NO_OBJ;
129 p_objinfo->grplink.i_child_topid = NO_OBJ;
130 p_objinfo->grplink.i_next_id = NO_OBJ;
131 p_objinfo->grplink.i_prev_id = NO_OBJ;
133 p_objinfo->typelink.i_prev_id = NO_OBJ;
134 p_objinfo->typelink.i_next_id = NO_OBJ;
140 /*----------------------------------------------------------------------
141 ----------------------------------------------------------------------*/
142 #define FUNCID_LibGoblin_ObjectInfo_AllocObjectInfo 0x11
143 LIBGOBLIN_OBJINFO_EXTERN
144 LibGoblin_ObjectInfo *
145 ObjectInfo_AllocObjectInfo(
146 LibGoblin_ProgramInfo *p_pginfo )
151 LibGoblin_ObjectInfo *p_objbase;
152 LibGoblin_ObjectInfo *p_objinfo;
153 LibGoblin_ObjectInfo *p_objtemp;
155 assert( NULL != p_pginfo );
160 // Expand ObjectInfo Memory when Empty ObjectInfo isn't exist. ---
161 if( NO_OBJ == p_pginfo->objinfo.i_empty ) {
162 assert( p_pginfo->objinfo.i_used == p_pginfo->objinfo.i_alloced );
164 i_items = p_pginfo->objinfo.i_alloced + LIBGOBLIN_OBJINFO_UNITS;
165 p_objbase = realloc( p_pginfo->objinfo.p_objinfo,
166 sizeof( LibGoblin_ObjectInfo ) * i_items);
167 if( NULL == p_objbase ) {
171 // Set Alloced ObjectInfo for Empty-Chain ---
172 for( i_cnt = (i_items - 1); i_cnt >= p_pginfo->objinfo.i_alloced; i_cnt-- ) {
173 p_objtemp = p_objbase + i_cnt;
174 ObjectInfo_ClearObjectInfo( p_objtemp );
176 p_objtemp->i_id = i_cnt;
177 p_objtemp->grplink.i_next_id = ((i_cnt < (i_items - 1)) ? (i_cnt + 1): NO_OBJ);
180 p_pginfo->objinfo.p_objinfo = p_objbase;
181 p_pginfo->objinfo.i_alloced += LIBGOBLIN_OBJINFO_UNITS;
182 p_pginfo->objinfo.i_empty = p_objtemp->i_id;
186 assert( NO_OBJ != p_pginfo->objinfo.i_empty );
188 i_id = p_pginfo->objinfo.i_empty;
189 p_objinfo = OBJINFO( p_pginfo, i_id );
190 p_pginfo->objinfo.i_empty = p_objinfo->grplink.i_next_id;
191 ObjectInfo_ClearObjectInfo( p_objinfo );
193 p_objinfo->dw_status |= OBJINFO_STATUS_VALID;
194 p_pginfo->objinfo.i_used++;
200 /*----------------------------------------------------------------------
201 ----------------------------------------------------------------------*/
202 #define FUNCID_LibGoblin_ObjectInfo_CreateMasterObject 0x51
204 ObjectInfo_CreateMasterObject(
205 LibGoblin_ProgramInfo *p_pginfo )
207 LibGoblin_ObjectInfo *p_objinfo;
209 if( NO_OBJ != p_pginfo->objinfo.i_topid ) {
213 p_objinfo = ObjectInfo_AllocObjectInfo( p_pginfo );
214 if( NULL == p_objinfo ) {
218 assert( 0 == p_objinfo->i_id );
220 p_objinfo->addr.ptr_addr.value = 0x0000000000000000;
221 p_objinfo->addr.qw_size = 0xffffffffffffffff;
222 p_objinfo->b_type = OBJINFO_TYPE_MASTER;
224 p_pginfo->objinfo.i_topid = p_objinfo->i_id;
230 /*----------------------------------------------------------------------
231 ----------------------------------------------------------------------*/
232 #define FUNCID_LibGoblin_ObjectInfo_AdoptObjectInfo 0x23
234 ObjectInfo_AdoptObjectInfo(
235 LibGoblin_ProgramInfo *p_pginfo,
236 LibGoblin_ObjectInfo *p_parent,
237 LibGoblin_ObjectInfo *p_child )
241 LibGoblin_ObjectInfo *p_objnext;
242 LibGoblin_ObjectInfo *p_objprev = NULL;
243 LibGoblin_ObjectInfo *p_tempnext;
244 LibGoblin_ObjectInfo *p_tempprev;
245 LibGoblin_ObjectInfo *p_tempparent;
247 assert( NULL != p_parent );
248 assert( NULL != p_child );
250 ptr_value = p_child->addr.ptr_addr.value;
251 qw_size = p_child->addr.qw_size;
253 // Search Insert Location in p_parent's childs. ---
254 p_objnext = (( NO_OBJ != p_parent->grplink.i_child_topid )
255 ? OBJINFO( p_pginfo, p_parent->grplink.i_child_topid ) : NULL );
256 while( NULL != p_objnext ) {
257 if( ptr_value == p_objnext->addr.ptr_addr.value ) {
258 if( qw_size > p_objnext->addr.qw_size ) { break; }
260 else if( ptr_value < p_objnext->addr.ptr_addr.value ) { break; }
262 p_objprev = p_objnext;
263 p_objnext = (( NO_OBJ != p_objnext->grplink.i_next_id )
264 ? OBJINFO( p_pginfo, p_objnext->grplink.i_next_id ) : NULL );
268 // p_child : Unlink GroupLink *********************************************
269 // prev(old)->next = child -> next(old)
270 p_tempprev = ((NO_OBJ != p_child->grplink.i_prev_id)
271 ? OBJINFO(p_pginfo, p_child->grplink.i_prev_id) : NULL );
272 if( NULL != p_tempprev ) {
273 assert( p_tempprev->grplink.i_next_id == p_child->i_id );
274 p_tempprev->grplink.i_next_id = p_child->grplink.i_next_id;
276 // next(old)->prev = child -> prev(old)
277 p_tempnext = ((NO_OBJ != p_child->grplink.i_next_id)
278 ? OBJINFO(p_pginfo, p_child->grplink.i_next_id) : NULL );
279 if( NULL != p_tempnext ) {
280 assert( p_tempnext->grplink.i_prev_id == p_child->i_id );
281 p_tempnext->grplink.i_prev_id = p_child->grplink.i_prev_id;
284 // parent(old)->child(top) = next(old) (If parent(old)->child(top) is child)
285 p_tempparent = OBJINFO(p_pginfo, p_child->grplink.i_parent_id);
286 assert( NULL != p_tempparent );
287 if( p_tempparent->grplink.i_child_topid == p_child->i_id ) {
288 assert( NO_OBJ == p_child->grplink.i_prev_id );
289 p_tempparent->grplink.i_child_topid = p_child->grplink.i_next_id;
292 // child->prev = prev(old) -> NO_OBJ
293 p_child->grplink.i_prev_id = NO_OBJ;
295 // child->next = next(old) -> NO_OBJ
296 p_child->grplink.i_next_id = NO_OBJ;
298 // child->parent = parent(old) -> NO_OBJ
299 p_child->grplink.i_parent_id = NO_OBJ;
302 // p_child : Set New GroupLink ********************************************
303 // child->prev = prev
304 p_child->grplink.i_prev_id = (( NULL != p_objprev ) ? p_objprev->i_id : NO_OBJ );
306 // child->next = next
307 p_child->grplink.i_next_id = (( NULL != p_objnext ) ? p_objnext->i_id : NO_OBJ );
309 // child->parent = parent
310 p_child->grplink.i_parent_id = p_parent->i_id;
312 // prev->next = child
313 if( NULL != p_objprev ) {
314 assert( p_objprev->grplink.i_next_id == ((NULL != p_objnext) ? p_objnext->i_id : NO_OBJ ));
315 p_objprev->grplink.i_next_id = p_child->i_id;
318 // next->prev = child
319 if( NULL != p_objnext ) {
320 assert( p_objnext->grplink.i_prev_id == ((NULL != p_objprev) ? p_objprev->i_id : NO_OBJ ));
321 p_objnext->grplink.i_prev_id = p_child->i_id;
324 // parent->child = child (If parent->child is NO_OBJ)
325 if(( NO_OBJ == p_parent->grplink.i_child_topid )
326 || ( NO_OBJ == p_child->grplink.i_prev_id ))
327 { p_parent->grplink.i_child_topid = p_child->i_id; }
333 /*----------------------------------------------------------------------
334 ----------------------------------------------------------------------*/
335 #define FUNCID_LibGoblin_ObjectInfo_InsetObjectInfo 0x21
336 LIBGOBLIN_OBJINFO_EXTERN
337 LibGoblin_ObjectInfo *
338 ObjectInfo_InsetObject(
339 LibGoblin_ProgramInfo *p_pginfo,
342 LibGoblin_ObjectInfo *p_parent,
347 LibGoblin_ObjectInfo *p_objinfo = NULL;
348 LibGoblin_ObjectInfo *p_objnow;
349 LibGoblin_ObjectInfo *p_objprev;
350 LibGoblin_ObjectInfo *p_objover;
351 LibGoblin_ObjectInfo *p_objnext;
353 // Inset Master ObjectInfo when don't exist Master ObjectInfo.
354 if( NO_OBJ == p_pginfo->objinfo.i_topid ) {
355 i_result = ObjectInfo_CreateMasterObject( p_pginfo );
356 if( 0x00 != i_result ) {
357 goto goto_ObjectInfo_InsetObject_post;
361 // If p_parent pram. don't indicate the parent ObjectInfo,
362 // set p_parent = Master ObjectInfo.
363 if( NULL == p_parent )
364 { p_parent = OBJINFO( p_pginfo, p_pginfo->objinfo.i_topid ); }
365 assert( NULL != p_parent );
367 // Alloc ObjectInfo ---
368 p_objinfo = ObjectInfo_AllocObjectInfo( p_pginfo );
369 if( NULL == p_objinfo ) {
371 goto goto_ObjectInfo_InsetObject_post;
374 p_objinfo->addr.ptr_addr.value = ptr_value;
375 p_objinfo->addr.qw_size = qw_size;
376 p_objinfo->b_type = b_type;
378 // Search ObjectInfo Inset Location. (Address Order)*****************
379 p_objnow = OBJINFO( p_pginfo, p_pginfo->objinfo.i_topid );
380 assert( NULL != p_objnow );
382 p_objover = p_objnow;
386 if(( p_objnow->addr.ptr_addr.value <= ptr_value )
387 && ( (ptr_value + qw_size) <= (p_objnow->addr.ptr_addr.value + p_objnow->addr.qw_size)
388 && ( ptr_value < (p_objnow->addr.ptr_addr.value + p_objnow->addr.qw_size)) )) {
390 if(( ptr_value == p_objnow->addr.ptr_addr.value )
391 && ( qw_size <= p_objnow->addr.qw_size )) {
392 if( b_type >= p_objnow->b_type ) {
393 if( p_objnow->addr.qw_size <= p_objover->addr.qw_size )
394 { p_objover = p_objnow; }
398 if( p_objnow->addr.qw_size <= p_objover->addr.qw_size )
399 { p_objover = p_objnow; }
403 if( ptr_value == p_objnow->addr.ptr_addr.value ) {
404 if( qw_size > p_objnow->addr.qw_size )
406 else if( qw_size <= p_objnow->addr.qw_size ) {
407 if( b_type < p_objnow->b_type ) { break; }
410 else if( ptr_value < p_objnow->addr.ptr_addr.value ) { break; }
412 p_objprev = p_objnow;
413 p_objnow = ((NO_OBJ != p_objnow->addrlink.i_next_id)
414 ? OBJINFO( p_pginfo, p_objnow->addrlink.i_next_id ) : NULL );
415 }while( (NULL != p_objnow) && (p_objnow != p_objprev) );
417 // Set Address Order Link Info.--------------------------------------
418 p_objinfo->addrlink.i_next_id = ((NULL != p_objnow) ? p_objnow->i_id : NO_OBJ);
419 p_objinfo->addrlink.i_prev_id = ((NULL != p_objprev) ? p_objprev->i_id : NO_OBJ);
421 if( NULL != p_objprev ) { p_objprev->addrlink.i_next_id = p_objinfo->i_id; }
422 if( NULL != p_objnow ) { p_objnow->addrlink.i_prev_id = p_objinfo->i_id; }
426 // Search ObjectInfo Inset Location. (Group Order) *****************
427 // Set Group Order Link Info. --------------------------------------
428 if( OBJINFO_INSETMODE_INSET == ( OBJINFO_INSETMODE_INSET & b_mode )) {
429 if( NULL != p_objover ) { p_parent = p_objover; }
432 if( NO_OBJ == p_parent->grplink.i_child_topid ) {
433 p_parent->grplink.i_child_topid = p_objinfo->i_id;
434 p_objinfo->grplink.i_parent_id = p_parent->i_id;
435 goto goto_ObjectInfo_InsetObject_post;
438 assert( NO_OBJ != p_parent->grplink.i_child_topid );
439 p_objnow = OBJINFO( p_pginfo, p_parent->grplink.i_child_topid );
442 if( ptr_value == p_objnow->addr.ptr_addr.value ) {
443 if( qw_size > p_objnow->addr.qw_size )
445 else if( qw_size <= p_objnow->addr.qw_size ) {
446 if( b_type < p_objnow->b_type ) { break; }
449 else if( ptr_value < p_objnow->addr.ptr_addr.value ) { break; }
451 p_objprev = p_objnow;
452 p_objnow = ((NO_OBJ != p_objnow->grplink.i_next_id)
453 ? OBJINFO( p_pginfo, p_objnow->grplink.i_next_id ) : NULL );
454 }while( NULL != p_objnow );
456 p_objinfo->grplink.i_next_id = ((NULL != p_objnow) ? p_objnow->i_id : NO_OBJ);
457 p_objinfo->grplink.i_prev_id = ((NULL != p_objprev) ? p_objprev->i_id : NO_OBJ);
458 p_objinfo->grplink.i_parent_id = p_parent->i_id;
460 if( NULL != p_objprev ) { p_objprev->grplink.i_next_id = p_objinfo->i_id; }
461 else { p_parent->grplink.i_child_topid = p_objinfo->i_id; }
463 if( NULL != p_objnow ) { p_objnow->grplink.i_prev_id = p_objinfo->i_id; }
466 // Check & Slaving ObjectInfo **************************************
467 if( OBJINFO_INSETMODE_ADOPT != ( OBJINFO_INSETMODE_ADOPT & b_mode ))
468 { goto goto_ObjectInfo_InsetObject_post; }
470 p_objnow = ((NO_OBJ != p_objinfo->grplink.i_next_id )
471 ? OBJINFO( p_pginfo, p_objinfo->grplink.i_next_id ) : NULL );
472 while( NULL != p_objnow ) {
473 p_objnext = ((NO_OBJ != p_objnow->grplink.i_next_id )
474 ? OBJINFO( p_pginfo, p_objnow->grplink.i_next_id ) : NULL );
476 if(( ptr_value <= p_objnow->addr.ptr_addr.value )
477 && ( (p_objnow->addr.ptr_addr.value + p_objnow->addr.qw_size) <= (ptr_value + qw_size))
478 && ( p_objnow->addr.ptr_addr.value < (ptr_value + qw_size)))
479 { ObjectInfo_AdoptObjectInfo( p_pginfo, p_objinfo, p_objnow ); }
481 p_objnow = p_objnext;
485 goto_ObjectInfo_InsetObject_post:
490 /*----------------------------------------------------------------------
491 ----------------------------------------------------------------------*/
492 #define FUNCID_LibGoblin_ObjectInfo_SearchAddressSize 0x41
493 LIBGOBLIN_OBJINFO_EXTERN
494 LibGoblin_ObjectInfo *
495 ObjectInfo_SearchAddressSize(
496 LibGoblin_ProgramInfo *p_pginfo,
500 LibGoblin_ObjectInfo *p_objnow;
501 LibGoblin_ObjectInfo *p_objret = NULL;
503 // Check exist MasterObject ---
504 if( NO_OBJ == p_pginfo->objinfo.i_topid )
505 { goto goto_ObjectInfo_SearchObjectInfo_post; }
508 // Search ObjectInfo Inset Location. (Address Order)---
509 p_objnow = OBJINFO( p_pginfo, p_pginfo->objinfo.i_topid );
510 assert( NULL != p_objnow );
513 if( p_objnow->addr.ptr_addr.value > ptr_value )
515 else if( p_objnow->addr.ptr_addr.value == ptr_value ) {
517 || (( 0 < qw_size ) && ( p_objnow->addr.qw_size == qw_size ))) {
523 p_objnow = ((NO_OBJ != p_objnow->addrlink.i_next_id)
524 ? OBJINFO( p_pginfo, p_objnow->addrlink.i_next_id ) : NULL );
525 }while( NULL != p_objnow );
527 goto_ObjectInfo_SearchObjectInfo_post:
532 /*----------------------------------------------------------------------
533 ----------------------------------------------------------------------*/
534 #define FUNCID_LibGoblin_ObjectInfo_SearchDynamicSymbol 0x42
535 LIBGOBLIN_OBJINFO_EXTERN
536 LibGoblin_ObjectInfo *
537 ObjectInfo_SearchDynamicSymbol(
538 LibGoblin_ProgramInfo *p_pginfo,
543 LibGoblin_ObjectInfo *p_objnow;
544 LibGoblin_ObjectInfo *p_objret = NULL;
547 // Check exist MasterObject ---
548 if( NO_OBJ == p_pginfo->objinfo.i_topid )
549 { goto goto_ObjectInfo_SearchDynamicSymbol_post; }
552 // Search ObjectInfo Inset Location. (Address Order)---
553 p_objnow = OBJINFO( p_pginfo, p_pginfo->objinfo.i_topid );
554 assert( NULL != p_objnow );
556 dw_hash = Common_CalcDJBhash( pstr_symname );
559 if( p_objnow->addr.ptr_addr.value > ptr_value )
561 else if( p_objnow->addr.ptr_addr.value == ptr_value ) {
562 if( dw_hash == p_objnow->dw_hash ) {
563 if(( 0x00 == dw_status ) || ( p_objnow->dw_status & dw_status )) {
564 if( !strncmp( pstr_symname, p_objnow->pstr_name, 256 ) ) {
572 p_objnow = ((NO_OBJ != p_objnow->addrlink.i_next_id)
573 ? OBJINFO( p_pginfo, p_objnow->addrlink.i_next_id ) : NULL );
574 }while( NULL != p_objnow );
576 goto_ObjectInfo_SearchDynamicSymbol_post:
581 /*----------------------------------------------------------------------
582 ----------------------------------------------------------------------*/
583 #define FUNCID_LibGoblin_ObjectInfo_FreeObjectInfo 0x12
584 LIBGOBLIN_OBJINFO_EXTERN
586 ObjectInfo_FreeObjectInfo(
587 LibGoblin_ProgramInfo *p_pginfo,
588 LibGoblin_ObjectInfo *p_objinfo )
592 assert( NULL != p_pginfo );
594 if( NULL == p_objinfo ) {
598 if( OBJINFO_STATUS_INVALID & p_objinfo->dw_status ) {
602 i_objid = p_objinfo->i_id;
603 ObjectInfo_ClearObjectInfo( p_objinfo );
604 p_objinfo->grplink.i_next_id = p_pginfo->objinfo.i_empty;
605 p_pginfo->objinfo.i_empty = p_objinfo->i_id;
607 p_pginfo->objinfo.i_used--;
613 /*----------------------------------------------------------------------
614 ----------------------------------------------------------------------*/
615 #define FUNCID_LibGoblin_ObjectInfo_DeleteObjectInfo 0x22
616 LIBGOBLIN_OBJINFO_EXTERN
618 ObjectInfo_DeleteObjectInfo(
619 LibGoblin_ProgramInfo *p_pginfo,
620 LibGoblin_ObjectInfo *p_objinfo )
623 LibGoblin_ObjectInfo *p_next;
624 LibGoblin_ObjectInfo *p_prev;
625 LibGoblin_ObjectInfo *p_parent;
626 LibGoblin_ObjectInfo *p_child;
627 LibGoblin_ObjectInfo *p_objnow;
629 // Check p_objinfo is Master ObjectInfo?
630 if(( 0 == p_objinfo->i_id ) && ( 1 < p_pginfo->objinfo.i_used )) {
634 // UnLink Group Order Link ---
635 while( NO_OBJ != p_objinfo->grplink.i_child_topid ) {
636 p_child = ((NO_OBJ != p_objinfo->grplink.i_child_topid)
637 ? OBJINFO(p_pginfo, p_objinfo->grplink.i_child_topid) : NULL );
638 i_result = ObjectInfo_DeleteObjectInfo( p_pginfo, p_child );
641 p_parent = ((NO_OBJ != p_objinfo->grplink.i_parent_id)
642 ? OBJINFO(p_pginfo, p_objinfo->grplink.i_parent_id) : NULL );
643 p_next = ((NO_OBJ != p_objinfo->grplink.i_next_id)
644 ? OBJINFO(p_pginfo, p_objinfo->grplink.i_next_id) : NULL );
645 p_prev = ((NO_OBJ != p_objinfo->grplink.i_prev_id)
646 ? OBJINFO(p_pginfo, p_objinfo->grplink.i_prev_id) : NULL );
647 p_child = ((NO_OBJ != p_objinfo->grplink.i_child_topid)
648 ? OBJINFO(p_pginfo, p_objinfo->grplink.i_child_topid) : NULL );
650 if( NULL != p_child ) { // (0x00 == b_mode ) is Self-Evident.
653 p_objnow->grplink.i_parent_id = p_objinfo->grplink.i_parent_id;
654 p_objnow = ((NO_OBJ != p_objnow->grplink.i_next_id)
655 ? OBJINFO( p_pginfo, p_objnow->grplink.i_next_id ) : NULL );
656 }while( NULL != p_objnow );
659 if( NULL != p_prev ) { p_prev->grplink.i_next_id = p_objinfo->grplink.i_next_id; }
660 if( NULL != p_next ) { p_next->grplink.i_prev_id = p_objinfo->grplink.i_prev_id; }
662 if( NULL != p_parent ) {
663 if( p_parent->grplink.i_child_topid == p_objinfo->i_id )
664 { p_parent->grplink.i_child_topid = p_objinfo->grplink.i_next_id; }
667 // Unlink Address Order Link ---
668 p_next = ((NO_OBJ != p_objinfo->addrlink.i_next_id)
669 ? OBJINFO(p_pginfo, p_objinfo->addrlink.i_next_id) : NULL );
670 p_prev = ((NO_OBJ != p_objinfo->addrlink.i_prev_id)
671 ? OBJINFO(p_pginfo, p_objinfo->addrlink.i_prev_id) : NULL );
673 if( NULL != p_prev ) { p_prev->addrlink.i_next_id = p_objinfo->addrlink.i_next_id; }
674 if( NULL != p_next ) { p_next->addrlink.i_prev_id = p_objinfo->addrlink.i_prev_id; }
676 if( p_pginfo->objinfo.i_topid == p_objinfo->i_id ) {
677 if( NO_OBJ != p_objinfo->addrlink.i_next_id ) {
678 p_next = OBJINFO(p_pginfo, p_objinfo->addrlink.i_next_id);
679 p_pginfo->objinfo.i_topid = p_next->i_id;
682 { p_pginfo->objinfo.i_topid = NO_OBJ; }
685 // Free ObjectInfo ---
686 ObjectInfo_FreeObjectInfo( p_pginfo, p_objinfo );
692 /*----------------------------------------------------------------------
693 ----------------------------------------------------------------------*/
694 #define FUNCID_LibGoblin_ObjectInfo_Init 0x01
695 LIBGOBLIN_OBJINFO_EXTERN
698 LibGoblin_ProgramInfo *p_pginfo,
703 LibGoblin_ObjectInfo *p_objinfo;
705 assert( NULL != p_pginfo );
707 if( 0 == i_init_objnums )
708 { i_items = LIBGOBLIN_OBJINFO_UNITS * LIBGOBLIN_OBJINFO_INITALLOCRATE; }
710 { i_items = (( i_init_objnums / LIBGOBLIN_OBJINFO_UNITS ) + 2) * LIBGOBLIN_OBJINFO_UNITS; }
712 p_pginfo->objinfo.p_objinfo = malloc( sizeof( LibGoblin_ObjectInfo ) * i_items );
713 if( NULL == p_pginfo->objinfo.p_objinfo ) {
717 for( i_cnt = (i_items - 1); 0 <= i_cnt; i_cnt-- ) {
718 p_objinfo = OBJINFO(p_pginfo, i_cnt);
719 ObjectInfo_ClearObjectInfo( p_objinfo );
721 p_objinfo->i_id = i_cnt;
722 p_objinfo->grplink.i_next_id = ((i_cnt < (i_items - 1)) ? (i_cnt + 1) : NO_OBJ);
725 p_pginfo->objinfo.i_alloced = i_items;
726 p_pginfo->objinfo.i_used = 0;
727 p_pginfo->objinfo.i_topid = NO_OBJ;
728 p_pginfo->objinfo.i_empty = 0;
734 /*----------------------------------------------------------------------
735 ----------------------------------------------------------------------*/
736 #define FUNCID_LibGoblin_ObjectInfo_Term 0x02
737 LIBGOBLIN_OBJINFO_EXTERN
740 LibGoblin_ProgramInfo *p_pginfo )
742 LibGoblin_ObjectInfo *p_objinfo;
744 assert( NULL != p_pginfo );
746 if( 0 < p_pginfo->objinfo.i_used ) {
747 for( ; p_pginfo->objinfo.i_used >= 0; p_pginfo->objinfo.i_used-- ) {
748 p_objinfo = OBJINFO(p_pginfo, p_pginfo->objinfo.i_used);
749 ObjectInfo_FreeObjectInfo( p_pginfo, p_objinfo );
753 free( p_pginfo->objinfo.p_objinfo );
755 p_pginfo->objinfo.p_objinfo = NULL;
756 p_pginfo->objinfo.i_alloced = 0;
757 p_pginfo->objinfo.i_used = 0;
758 p_pginfo->objinfo.i_topid = NO_OBJ;
759 p_pginfo->objinfo.i_empty = NO_OBJ;
765 /* EOF of drd64_.c ----------------------------------- */