Пример #1
0
Файл: typemgr.c Проект: xyuan/ug
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;
}
Пример #2
0
Файл: typemgr.c Проект: xyuan/ug
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;
}
Пример #3
0
Файл: pack.c Проект: rolk/ug
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);
}