OSDN Git Service

(LibGoblin)
[drdeamon64/drdeamon64.git] / libgoblin / drd64_libgoblin_objinfo.c
1 /*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
2
3                          D r . D e a m o n  6 4
4                         for INTEL64(R), AMD64(R)
5         
6    Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10
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.
16
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.
28
29 DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
30
31 /* File Info -----------------------------------------------------------
32 File: drd64_.c
33 Function: 
34 Comment: 
35 ----------------------------------------------------------------------*/
36
37 #define DRD64_SRC_LIBGOBLIN_OBJINFO
38 #include"drd64_libgoblin.h"
39
40 #define LOCATION(n) DRD64_ERR_LOCATION( \
41                                                 DRD64_ERROR_MODULE_LIBGOBLIN, DRD64_ERROR_ARCH_NODEPEND, \
42                                                 DRD64_SRCID_LIBGOBLIN_OBJINFO, (n))
43
44
45 /*----------------------------------------------------------------------
46 ----------------------------------------------------------------------*/
47 #define FUNCID_LibGoblin_ObjectInfo_GetObjectInfo       0x14
48 LIBGOBLIN_OBJINFO_EXTERN
49 LibGoblin_ObjectInfo *
50         ObjectInfo_GetObjectInfo(
51                 LibGoblin_ProgramInfo   *p_pginfo,
52                 int     i_oid  )
53 {
54         assert( NULL != p_pginfo );
55
56         if(( p_pginfo->objinfo.i_alloced <= i_oid ) || ( 0 > i_oid ))   {
57                 return NULL;
58         }
59         
60         return OBJINFO(p_pginfo, i_oid);
61 }
62
63
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 )
72 {
73         LibGoblin_ObjectInfo    *pobj_ret       = NULL;
74
75         assert( NULL != p_pginfo );
76         assert( NULL != p_objinfo );
77
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 );
81         }
82         
83         return pobj_ret;
84 }
85
86
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 )
95 {
96         LibGoblin_ObjectInfo    *pobj_ret       = NULL;
97
98         assert( NULL != p_pginfo );
99         assert( NULL != p_objinfo );
100
101         if( NO_OBJ != p_objinfo->grplink.i_next_id )
102                 { pobj_ret      = OBJINFO( p_pginfo, p_objinfo->grplink.i_next_id ); }
103         
104         return pobj_ret;
105 }
106
107
108 /*----------------------------------------------------------------------
109 ----------------------------------------------------------------------*/
110 #define FUNCID_LibGoblin_ObjectInfo_ClearObjectInfo     0x13
111 void
112         ObjectInfo_ClearObjectInfo(
113                         LibGoblin_ObjectInfo    *p_objinfo )
114 {
115         int             i_id;
116
117         assert( NULL != p_objinfo );
118
119         i_id    = p_objinfo->i_id;
120         memset( p_objinfo, 0x00, sizeof( LibGoblin_ObjectInfo ) );
121
122         p_objinfo->i_id                 = i_id;
123         p_objinfo->dw_status    = OBJINFO_STATUS_INVALID;       // Clear dw_status
124
125         p_objinfo->addrlink.i_next_id           = NO_OBJ;
126         p_objinfo->addrlink.i_prev_id           = NO_OBJ;
127
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;
132
133         p_objinfo->typelink.i_prev_id           = NO_OBJ;
134         p_objinfo->typelink.i_next_id           = NO_OBJ;
135
136         return;
137 }
138
139
140 /*----------------------------------------------------------------------
141 ----------------------------------------------------------------------*/
142 #define FUNCID_LibGoblin_ObjectInfo_AllocObjectInfo     0x11
143 LIBGOBLIN_OBJINFO_EXTERN
144 LibGoblin_ObjectInfo *
145         ObjectInfo_AllocObjectInfo(
146                         LibGoblin_ProgramInfo   *p_pginfo )
147 {
148         int             i_cnt;
149         int             i_id;
150         int             i_items;
151         LibGoblin_ObjectInfo *p_objbase;
152         LibGoblin_ObjectInfo *p_objinfo;
153         LibGoblin_ObjectInfo *p_objtemp;
154
155         assert( NULL != p_pginfo );
156         
157         p_objinfo       = NULL;
158         i_id    = -1;
159         
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 );
163
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 ) {
168                         return NULL;
169                 }
170
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 );
175
176                         p_objtemp->i_id                                 = i_cnt;
177                         p_objtemp->grplink.i_next_id    = ((i_cnt < (i_items - 1)) ? (i_cnt + 1): NO_OBJ);
178                 }
179                 
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;      
183         }
184
185
186         assert( NO_OBJ != p_pginfo->objinfo.i_empty );
187
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 );
192
193         p_objinfo->dw_status            |= OBJINFO_STATUS_VALID;
194         p_pginfo->objinfo.i_used++;
195
196         return p_objinfo;
197 }
198
199
200 /*----------------------------------------------------------------------
201 ----------------------------------------------------------------------*/
202 #define FUNCID_LibGoblin_ObjectInfo_CreateMasterObject  0x51
203 int
204         ObjectInfo_CreateMasterObject(
205                         LibGoblin_ProgramInfo   *p_pginfo )
206 {
207         LibGoblin_ObjectInfo    *p_objinfo;
208
209         if( NO_OBJ != p_pginfo->objinfo.i_topid )       {
210                 return 0x00;
211         }
212
213         p_objinfo       = ObjectInfo_AllocObjectInfo( p_pginfo );
214         if( NULL == p_objinfo ) {
215                 return 0x01;
216         }
217
218         assert( 0 == p_objinfo->i_id );
219
220         p_objinfo->addr.ptr_addr.value  = 0x0000000000000000;
221         p_objinfo->addr.qw_size                 = 0xffffffffffffffff;
222         p_objinfo->b_type                               = OBJINFO_TYPE_MASTER;
223
224         p_pginfo->objinfo.i_topid       = p_objinfo->i_id;
225
226         return 0x00;
227 }
228
229
230 /*----------------------------------------------------------------------
231 ----------------------------------------------------------------------*/
232 #define FUNCID_LibGoblin_ObjectInfo_AdoptObjectInfo     0x23
233 int
234         ObjectInfo_AdoptObjectInfo(
235                         LibGoblin_ProgramInfo   *p_pginfo,
236                         LibGoblin_ObjectInfo    *p_parent,
237                         LibGoblin_ObjectInfo    *p_child )
238 {
239         QWord           qw_size;
240         PtrValue        ptr_value;
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;
246         
247         assert( NULL != p_parent );
248         assert( NULL != p_child );
249
250         ptr_value       = p_child->addr.ptr_addr.value;
251         qw_size         = p_child->addr.qw_size;
252
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; }
259                 }
260                 else if( ptr_value < p_objnext->addr.ptr_addr.value )   { break; }
261
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 );
265         }
266
267         
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;
275         }
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;
282         }
283
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;
290         }
291
292         // child->prev = prev(old) -> NO_OBJ
293         p_child->grplink.i_prev_id      = NO_OBJ;
294
295         // child->next = next(old) -> NO_OBJ
296         p_child->grplink.i_next_id      = NO_OBJ;
297
298         // child->parent = parent(old) -> NO_OBJ
299         p_child->grplink.i_parent_id    = NO_OBJ;
300
301
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 );
305
306         // child->next = next
307         p_child->grplink.i_next_id      = (( NULL != p_objnext ) ? p_objnext->i_id : NO_OBJ );
308
309         // child->parent = parent
310         p_child->grplink.i_parent_id    = p_parent->i_id;
311
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;
316         }
317
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;
322         }
323
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; }
328
329         return 0x00;
330 }
331
332
333 /*----------------------------------------------------------------------
334 ----------------------------------------------------------------------*/
335 #define FUNCID_LibGoblin_ObjectInfo_InsetObjectInfo     0x21
336 LIBGOBLIN_OBJINFO_EXTERN
337 LibGoblin_ObjectInfo *
338         ObjectInfo_InsetObject(
339                         LibGoblin_ProgramInfo   *p_pginfo,
340                         PtrValue                                ptr_value,
341                         QWord                                   qw_size,
342                         LibGoblin_ObjectInfo    *p_parent,
343                         Byte                                    b_mode,
344                         Byte                                    b_type )
345 {
346         int                                             i_result        = 0x00;
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;
352
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;
358                 }
359         }
360
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 );
366         
367         // Alloc ObjectInfo ---
368         p_objinfo       = ObjectInfo_AllocObjectInfo( p_pginfo );
369         if( NULL == p_objinfo ) {
370                 i_result        = -0x01;
371                 goto    goto_ObjectInfo_InsetObject_post;
372         }
373
374         p_objinfo->addr.ptr_addr.value  = ptr_value;
375         p_objinfo->addr.qw_size                 = qw_size;
376         p_objinfo->b_type                               = b_type;
377
378         // Search ObjectInfo Inset Location. (Address Order)*****************
379         p_objnow        = OBJINFO( p_pginfo, p_pginfo->objinfo.i_topid );
380         assert( NULL != p_objnow );
381
382         p_objover       = p_objnow;
383         p_objprev       = NULL;
384         do      {
385
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)) ))   {
389
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; }
395                                 }
396                         }
397                         else {
398                                 if( p_objnow->addr.qw_size <= p_objover->addr.qw_size )
399                                         { p_objover     = p_objnow; }
400                         }
401                 }
402
403                 if( ptr_value == p_objnow->addr.ptr_addr.value )        {
404                         if( qw_size > p_objnow->addr.qw_size )
405                                 { break; }
406                         else if( qw_size <= p_objnow->addr.qw_size )    {
407                                 if( b_type < p_objnow->b_type )         { break; }
408                         }
409                 }
410                 else if( ptr_value < p_objnow->addr.ptr_addr.value )    { break; }
411                 
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) );
416
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);
420
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; }
423
424
425
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; }
430         }
431
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;
436         }
437
438         assert( NO_OBJ != p_parent->grplink.i_child_topid );
439         p_objnow        = OBJINFO( p_pginfo, p_parent->grplink.i_child_topid );
440         p_objprev       = NULL;
441         do      {
442                 if( ptr_value == p_objnow->addr.ptr_addr.value )        {
443                         if( qw_size > p_objnow->addr.qw_size )
444                                 { break; }
445                         else if( qw_size <= p_objnow->addr.qw_size )    {
446                                 if( b_type < p_objnow->b_type )         { break; }
447                         }
448                 }
449                 else if( ptr_value < p_objnow->addr.ptr_addr.value )    { break; }
450                 
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 );
455
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;
459
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; }
462
463         if( NULL != p_objnow )  { p_objnow->grplink.i_prev_id   = p_objinfo->i_id; }
464
465
466         // Check & Slaving ObjectInfo **************************************
467         if( OBJINFO_INSETMODE_ADOPT != ( OBJINFO_INSETMODE_ADOPT & b_mode ))
468                 { goto  goto_ObjectInfo_InsetObject_post; }
469
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 );
475
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 ); }
480
481                 p_objnow        = p_objnext;
482         }
483
484
485 goto_ObjectInfo_InsetObject_post:
486         return p_objinfo;
487 }
488
489
490 /*----------------------------------------------------------------------
491 ----------------------------------------------------------------------*/
492 #define FUNCID_LibGoblin_ObjectInfo_SearchAddressSize   0x41
493 LIBGOBLIN_OBJINFO_EXTERN
494 LibGoblin_ObjectInfo *
495         ObjectInfo_SearchAddressSize(
496                         LibGoblin_ProgramInfo   *p_pginfo,
497                         PtrValue                                ptr_value,
498                         QWord                                   qw_size )
499 {
500         LibGoblin_ObjectInfo    *p_objnow;
501         LibGoblin_ObjectInfo    *p_objret       = NULL;
502
503         // Check exist MasterObject ---
504         if( NO_OBJ == p_pginfo->objinfo.i_topid )
505                 { goto  goto_ObjectInfo_SearchObjectInfo_post; }
506
507
508         // Search ObjectInfo Inset Location. (Address Order)---
509         p_objnow        = OBJINFO( p_pginfo, p_pginfo->objinfo.i_topid );
510         assert( NULL != p_objnow );
511
512         do      {
513                 if( p_objnow->addr.ptr_addr.value > ptr_value )
514                         { break; }
515                 else if( p_objnow->addr.ptr_addr.value == ptr_value )   {
516                         if(( 0 == qw_size )
517                                         || (( 0 < qw_size ) && ( p_objnow->addr.qw_size == qw_size )))  {
518                                 p_objret        = p_objnow;
519                                 break;
520                         }
521                 }
522                 
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 );
526
527         goto_ObjectInfo_SearchObjectInfo_post:
528         return p_objret;
529 }
530
531
532 /*----------------------------------------------------------------------
533 ----------------------------------------------------------------------*/
534 #define FUNCID_LibGoblin_ObjectInfo_SearchDynamicSymbol 0x42
535 LIBGOBLIN_OBJINFO_EXTERN
536 LibGoblin_ObjectInfo *
537         ObjectInfo_SearchDynamicSymbol(
538                         LibGoblin_ProgramInfo   *p_pginfo,
539                         PtrValue                                ptr_value,
540                         char                                    *pstr_symname,
541                         DWord                                   dw_status )
542 {
543         LibGoblin_ObjectInfo    *p_objnow;
544         LibGoblin_ObjectInfo    *p_objret       = NULL;
545         DWord                                   dw_hash;
546
547         // Check exist MasterObject ---
548         if( NO_OBJ == p_pginfo->objinfo.i_topid )
549                 { goto  goto_ObjectInfo_SearchDynamicSymbol_post; }
550
551
552         // Search ObjectInfo Inset Location. (Address Order)---
553         p_objnow        = OBJINFO( p_pginfo, p_pginfo->objinfo.i_topid );
554         assert( NULL != p_objnow );
555
556         dw_hash = Common_CalcDJBhash( pstr_symname );
557
558         do      {
559                 if( p_objnow->addr.ptr_addr.value > ptr_value )
560                         { break; }
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 ) )        {
565                                                 p_objret        = p_objnow;
566                                                 break;
567                                         }
568                                 }
569                         }
570                 }
571                 
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 );
575
576 goto_ObjectInfo_SearchDynamicSymbol_post:
577         return p_objret;
578 }
579
580
581 /*----------------------------------------------------------------------
582 ----------------------------------------------------------------------*/
583 #define FUNCID_LibGoblin_ObjectInfo_FreeObjectInfo      0x12
584 LIBGOBLIN_OBJINFO_EXTERN
585 int
586         ObjectInfo_FreeObjectInfo(
587                 LibGoblin_ProgramInfo   *p_pginfo,
588                 LibGoblin_ObjectInfo *p_objinfo )
589 {
590         int             i_objid;        
591
592         assert( NULL != p_pginfo );
593
594         if( NULL == p_objinfo ) {
595                 return 0x01;
596         }
597
598         if( OBJINFO_STATUS_INVALID & p_objinfo->dw_status )     {
599                 return 0x02;
600         }
601
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;
606
607         p_pginfo->objinfo.i_used--;
608         
609         return 0x00;
610 }
611
612
613 /*----------------------------------------------------------------------
614 ----------------------------------------------------------------------*/
615 #define FUNCID_LibGoblin_ObjectInfo_DeleteObjectInfo    0x22
616 LIBGOBLIN_OBJINFO_EXTERN
617 int
618         ObjectInfo_DeleteObjectInfo(
619                 LibGoblin_ProgramInfo   *p_pginfo,
620                 LibGoblin_ObjectInfo    *p_objinfo )
621 {
622         int             i_result;
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;
628
629         // Check p_objinfo is Master ObjectInfo?
630         if(( 0 == p_objinfo->i_id ) && ( 1 < p_pginfo->objinfo.i_used ))        {
631                 return -0x01;
632         }
633
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 );
639         }
640
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 );
649
650         if( NULL != p_child )   {       // (0x00 == b_mode ) is Self-Evident.
651                 p_objnow        = p_child;
652                 do      {
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 );
657         }
658
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; }
661
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; }
665         }
666         
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 );
672
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; }
675
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;
680                 }
681                 else
682                         { p_pginfo->objinfo.i_topid     = NO_OBJ; }
683         }
684
685         // Free ObjectInfo ---
686         ObjectInfo_FreeObjectInfo( p_pginfo, p_objinfo );
687
688         return 0x00;
689 }
690
691
692 /*----------------------------------------------------------------------
693 ----------------------------------------------------------------------*/
694 #define FUNCID_LibGoblin_ObjectInfo_Init        0x01
695 LIBGOBLIN_OBJINFO_EXTERN
696 int
697         ObjectInfo_Init(
698                 LibGoblin_ProgramInfo   *p_pginfo,
699                 int             i_init_objnums )
700 {
701         int             i_cnt;
702         int             i_items;
703         LibGoblin_ObjectInfo    *p_objinfo;
704
705         assert( NULL != p_pginfo );
706
707         if( 0 == i_init_objnums )
708                 { i_items       = LIBGOBLIN_OBJINFO_UNITS * LIBGOBLIN_OBJINFO_INITALLOCRATE; }
709         else
710                 { i_items = (( i_init_objnums / LIBGOBLIN_OBJINFO_UNITS ) + 2) * LIBGOBLIN_OBJINFO_UNITS; }
711
712         p_pginfo->objinfo.p_objinfo     = malloc( sizeof( LibGoblin_ObjectInfo ) * i_items );
713         if( NULL == p_pginfo->objinfo.p_objinfo )       {
714                 return -0x02;
715         }
716
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 );
720
721                 p_objinfo->i_id                                 = i_cnt;
722                 p_objinfo->grplink.i_next_id    = ((i_cnt < (i_items - 1)) ? (i_cnt + 1) : NO_OBJ);
723         }
724
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;
729
730         return 0x00;
731 }
732
733
734 /*----------------------------------------------------------------------
735 ----------------------------------------------------------------------*/
736 #define FUNCID_LibGoblin_ObjectInfo_Term        0x02
737 LIBGOBLIN_OBJINFO_EXTERN
738 int
739         ObjectInfo_Term(
740                 LibGoblin_ProgramInfo   *p_pginfo )
741 {
742         LibGoblin_ObjectInfo    *p_objinfo;
743
744         assert( NULL != p_pginfo );
745
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 );
750                 }
751         }
752         
753         free( p_pginfo->objinfo.p_objinfo );
754         
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;
760
761         return 0x00;
762 }
763
764
765 /* EOF of drd64_.c ----------------------------------- */