1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 ss_pers_t *
 ss_pers_refer(ss_scope_t *scope,              /* The scope to which PERSOBJ belongs. */
               ss_persobj_t *persobj,          /* The object to which the new link will point. */
               ss_pers_t *pers                 /* Optional memory for the link. */
               )
 {
     SS_ENTER(ss_pers_refer, ss_pers_tP);
     unsigned            tableidx;
     ss_pers_t           *pers_in=pers;
     ss_pers_class_t     *pc=NULL;
     ss_table_t          *table=NULL;
     ss_gfile_t          *gfile=NULL;

     SS_ASSERT_MEM(scope, ss_scope_t);
     SS_ASSERT_CLASS(persobj, ss_persobj_t);
     tableidx = SS_MAGIC_SEQUENCE(SS_MAGIC_OF(persobj));
     pc = SS_PERS_CLASS(tableidx);
     SS_ASSERT(pc);
     gfile = SS_GFILE_LINK(scope);
     SS_ASSERT(gfile);

     /* Create and/or initialize the link */
     pers=(ss_pers_t*)ss_obj_new((ss_obj_t*)pers, SS_MAGIC_CONS(SS_MAGIC(ss_pers_t), tableidx), sizeof(ss_pers_t), NULL);
     if (!pers) SS_ERROR(FAILED);

     /* The PERS object must be in the same file as the SCOPE -- in fact, in the specified scope */
     if (NULL==(table = ss_scope_table(scope, SS_MAGIC_OF(pers), NULL))) SS_ERROR(FAILED);
     if (ss_table_owns(table, persobj)<=0) SS_ERROR(NOTFOUND);

     /* Initialize the link */
     ss_pers_link_setobjptr(pers, persobj);
     ss_pers_link_setobjidx(pers, persobj->mapidx);
     ss_pers_link_setopenserial(pers, gfile->open_serial);
     ss_pers_link_setscopeidx(pers, SS_SCOPE(scope)->m.pers.mapidx);
     ss_pers_link_setgfileidx(pers, ss_pers_link_gfileidx(scope));
     ss_pers_link_setstate(pers, SS_PERS_LINK_MEMORY);

  SS_CLEANUP:
     if (pers && !pers_in) {
         SS_OBJ_DEST(pers);
         SS_FREE(pers);
     }
     SS_LEAVE(pers);
 }