static int NormalizeDesc (TYPE_DESC *desc) { ELEM_DESC *elems = desc->element; /* sort element array by offset */ qsort(elems, desc->nElements, sizeof(ELEM_DESC), sort_el_offset); /* check for overlapping elements */ if (! CheckOverlapEls(desc)) return FALSE; # ifndef DebugNoStructCompress { /* compile this only if Debug-flag not set */ int i; /* compress element description */ for(i=0; i<desc->nElements-1; i++) { size_t realsize; /* 1) type must be equal */ if (elems[i].type != elems[i+1].type) continue; /* 2) nothing can melt into DDD_HEADER */ if (desc->hasHeader && elems[i+1].offset==desc->offsetHeader) continue; /* 3) gap between elements is allowed only for EL_LDATA */ if ((elems[i].offset+elems[i].size != elems[i+1].offset) && (elems[i].type!=EL_LDATA) ) continue; /* 4) EL_OBJPTRs with different reftypes can't be compressed */ if (elems[i].type==EL_OBJPTR && ((EDESC_REFTYPE(elems+i)!= EDESC_REFTYPE(elems+(i+1))) || (EDESC_REFTYPE(elems+i)==DDD_TYPE_BY_HANDLER)) ) continue; /* 5) EL_GBITS cant be compressed */ if (elems[i].type == EL_GBITS) continue; /* all conditions fit: compress elements */ realsize = elems[i+1].offset - elems[i].offset; elems[i].size = realsize + elems[i+1].size; desc->nElements--; DeleteFirstEl(&elems[i+1], desc->nElements - i); i--; /* skip one element back and try again */ } } # endif return TRUE; }
static int RecursiveRegister (TYPE_DESC *desc, int i, DDD_TYPE typ, int offs, int argno) { TYPE_DESC *d2 = &(theTypeDefs[typ]); int j; char *errtxt; /* inherit elements of other ddd-type */ for(j=0; j<d2->nElements && i<MAX_ELEMDESC; j++, i++) { ConstructEl(&desc->element[i], d2->element[j].type, d2->element[j].offset + offs, d2->element[j].size, EDESC_REFTYPE(&(d2->element[j]))); if (CheckBounds(desc, &desc->element[i], argno) == ERROR) return(ERROR); } /* inherit other properties */ desc->nPointers += d2->nPointers; if (d2->hasHeader) { if (!desc->hasHeader) { desc->hasHeader = TRUE; desc->offsetHeader = d2->offsetHeader + offs; } else { if (desc->offsetHeader == d2->offsetHeader+offs) { errtxt=RegisterError(desc,argno, "two DDD_HDRs, same offset"); DDD_PrintError('W', 2408, errtxt); } else { errtxt=RegisterError(desc,argno, "only one DDD_HDR allowed"); DDD_PrintError('E', 2409, errtxt); return(ERROR); } } } return i; }
static int BuildSymTab (TYPE_DESC *desc, DDD_OBJ obj, char *copy, SYMTAB_ENTRY *theSymTab) { ELEM_DESC *theElem; int e, actSym; /*STAT_RESET4;*/ /* reset local portion of SymTab */ actSym = 0; /* prepare map of structure elements */ theElem = desc->element; /* loop over all pointers inside of object obj */ for(e=0; e<desc->nElements; e++, theElem++) { if (theElem->type==EL_OBJPTR) { TYPE_DESC *refdesc; int l; int rt_on_the_fly = (EDESC_REFTYPE(theElem)==DDD_TYPE_BY_HANDLER); /* determine reftype of this elem */ if (! rt_on_the_fly) { /* we know the reftype of this element in advance */ refdesc = &theTypeDefs[EDESC_REFTYPE(theElem)]; } /* else: determine reftype on the fly by calling handler */ /* loop over single pointer array */ #if defined(C_FRONTEND) || defined(CPP_FRONTEND) for(l=0; l<theElem->size; l+=sizeof(void *)) { /* get address of outside reference */ DDD_OBJ *ref = (DDD_OBJ *)(copy+theElem->offset+l); #else for(l=0; l<theElem->size; l+=sizeof(DDD_OBJ)) { /* F77TODO: DDD_OBJ* must be replaced by local objindex */ /* get the index of the referenced object */ DDD_OBJ *ref = (DDD_OBJ *)(copy+theElem->msgoffset); #endif /* create symbol table entry */ if (*ref!=NULL) { DDD_HDR refhdr; if (rt_on_the_fly) { DDD_TYPE rt; /* determine reftype on the fly by calling handler */ assert(obj!=NULL); /* we need a real object here */ rt = theElem->reftypeHandler(obj, *ref); if (rt>=MAX_TYPEDESC) { DDD_PrintError('E', 6520, "invalid referenced DDD_TYPE " "returned by handler"); HARD_EXIT; } refdesc = &theTypeDefs[rt]; } /* get header of referenced object */ refhdr = OBJ2HDR(*ref,refdesc); /* remember the GID of the referenced object */ theSymTab[actSym].gid = OBJ_GID(refhdr); /* remember the address of the reference (in obj-copy) */ theSymTab[actSym].adr.ref = ref; actSym++; } } } } /*STAT_INCTIMER4(33);*/ /* return SymTab increment */ return(actSym); } /****************************************************************************/ /* */ /* Function: GetDepData */ /* */ /* Purpose: fill object-dependent data into message. an appl. routine */ /* will be called to fill in the data actually. pointers are */ /* localized and the message SymTab is actualized. */ /* */ /* Input: data: portion of message buffer reserved for dependent data */ /* desc: descriptor of object */ /* obj: current ddd-object */ /* theSymTab: actual portion of message SymTab */ /* xi: single xferinfo for current ddd-object */ /* */ /* Output: number of new entries into SymTab */ /* */ /****************************************************************************/ static int GetDepData (char *data, TYPE_DESC *desc, DDD_OBJ obj, SYMTAB_ENTRY *theSymTab, XICopyObj *xi) { XFERADDDATA *xa; TYPE_DESC *descDep; char *chunk, *adr, **table1, *next_chunk; int chunks, i, actSym, *table2; if (xi->addLen==0) return(0); chunks = 0; actSym = 0; /* first entry will be number of dependency chunks */ chunk = data + CEIL(sizeof(int)); /* loop through whole dependency data descriptor */ for(xa=xi->add; xa!=NULL; xa=xa->next) { /* first entries of chunk are addCnt and addTyp */ ((int *)chunk)[0] = xa->addCnt; ((DDD_TYPE *)chunk)[1] = xa->addTyp; if (xa->sizes==NULL) { chunk += CEIL(sizeof(int)+sizeof(DDD_TYPE)); /* then all records should be gathered via handler */ if (desc->handlerXFERGATHER) { #if defined(C_FRONTEND) || defined(F_FRONTEND) desc->handlerXFERGATHER(_FADR obj, _FADR xa->addCnt, _FADR xa->addTyp, (void *)chunk); #endif #ifdef CPP_FRONTEND CallHandler(desc,XFERGATHER) (HParam(obj) xa->addCnt, xa->addTyp, (void *)chunk); #endif } if (xa->addTyp<DDD_USER_DATA || xa->addTyp>DDD_USER_DATA_MAX) { /* insert pointers into symtab */ descDep = &theTypeDefs[xa->addTyp]; for(i=0; i<xa->addCnt; i++) { actSym += BuildSymTab(descDep, NULL, chunk, &(theSymTab[actSym])); chunk += CEIL(descDep->size); } } else { /* no regular type -> send byte stream with length addCnt */ chunk += CEIL(xa->addCnt); } } else { /* var-sized AddData items */ ((int *)chunk)[0] *= -1; chunk += CEIL(sizeof(int)+sizeof(DDD_TYPE)); /* create pointer array inside message */ table1 = (char **)chunk; chunk += CEIL(sizeof(int)*xa->addCnt); for(i=0, adr=chunk; i<xa->addCnt; i++) { table1[i] = adr; adr += CEIL(xa->sizes[i]); } next_chunk = adr; /* then all records should be gathered via handler */ if (desc->handlerXFERGATHERX) { #if defined(C_FRONTEND) || defined(F_FRONTEND) desc->handlerXFERGATHERX(_FADR obj, _FADR xa->addCnt, _FADR xa->addTyp, table1); #endif #ifdef CPP_FRONTEND CallHandler(desc,XFERGATHERX) (HParam(obj) xa->addCnt, xa->addTyp, table1); #endif } /* convert pointer table into offset table */ table2 = (int *)table1; descDep = &theTypeDefs[xa->addTyp]; adr = chunk; for(i=0; i<xa->addCnt; i++) { /* insert pointers into symtab */ if (xa->addTyp<DDD_USER_DATA || xa->addTyp>DDD_USER_DATA_MAX) { actSym += BuildSymTab(descDep, NULL, table1[i], &(theSymTab[actSym])); } table2[i] = (int)(table1[i]-adr); } chunk = next_chunk; } /* count chunks */ chunks++; } /* remember number of chunks at the beginning of the deplist */ ((int *)data)[0] = chunks; return(actSym); }