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);
}