/* fut_copy_otbl makes an exact copy of an existing fut_otbl_t */ fut_otbl_p fut_copy_otbl (fut_otbl_p otbl) { fut_otbl_p new_otbl; KpHandle_t h; /* check for valid otbl */ if ( ! IS_OTBL(otbl) ) { return (FUT_NULL_OTBL); } /* allocate the new otbl structure */ new_otbl = fut_alloc_otbl (); if ( new_otbl == FUT_NULL_OTBL ) { DIAG("fut_copy_otbl: can't alloc output table struct.\n", 0); return (FUT_NULL_OTBL); } h = new_otbl->handle; /* save handle before copying over old otbl */ *new_otbl = *otbl; /* copy entire struct except reference count */ new_otbl->handle = h; new_otbl->ref = 0; /* first reference */ if (otbl->tbl != NULL) { /* copy fixed otbl data */ new_otbl->tbl = fut_alloc_otbldat (new_otbl); if ( new_otbl->tbl == NULL ) { DIAG("fut_copy_otbl: can't alloc output table array.\n", 0); goto ErrOut; } new_otbl->tblHandle = getHandleFromPtr((KpGenericPtr_t)new_otbl->tbl); /* copy the table entries */ KpMemCpy (new_otbl->tbl, otbl->tbl, FUT_OUTTBL_ENT * sizeof (fut_otbldat_t)); } if (otbl->refTbl != NULL) { /* copy reference otbl data */ new_otbl->refTbl = fut_alloc_omftdat (new_otbl, new_otbl->refTblEntries); if (new_otbl->refTbl == NULL ) { DIAG("fut_copy_otbl: can't alloc output table array.\n", 0); goto ErrOut; } /* copy the table entries */ KpMemCpy (new_otbl->refTbl, otbl->refTbl, new_otbl->refTblEntries * sizeof (mf2_tbldat_t)); } return (new_otbl); ErrOut: fut_free_otbl (new_otbl); return (FUT_NULL_OTBL); }
/* fut_new_otbl creates a new output table for one channel of a fut. * Ofun must be a pointer to a function accepting a fut_gtbldat_t in the * range (0,FUT_GRD_MAXVAL) and returning a fut_otbldat_t in the same * interval. A pointer to the newly allocated table is returned. * (If ofun is NULL, table is not intialized!). */ fut_otbl_p fut_new_otblEx ( PTTableType_t tableType, PTDataClass_t oClass, fut_ofunc_t ofun, fut_calcData_p data) { fut_otbl_p otbl; /* allocate output table structure */ otbl = fut_alloc_otbl(); if ( otbl == FUT_NULL_OTBL ) { DIAG("fut_new_otbl: can't alloc output table struct.\n", 0); return (FUT_NULL_OTBL); } otbl->dataClass = oClass; /* allocate the table */ if (tableType == KCP_PT_TABLES) { otbl->tbl = fut_alloc_otbldat (otbl); if ( otbl->tbl == NULL ) { DIAG("fut_new_otbl: can't alloc output table array.\n", 0); fut_free_otbl (otbl); return (FUT_NULL_OTBL); } } else { otbl->refTbl = fut_alloc_omftdat (otbl, FUT_OUTTBL_ENT); if ( otbl->refTbl == NULL ) { DIAG("fut_new_otbl: can't alloc output table array.\n", 0); fut_free_otbl (otbl); return (FUT_NULL_OTBL); } } /* compute the output table entries */ if ( ! fut_calc_otblEx (otbl, ofun, data) ) { fut_free_otbl (otbl); return (FUT_NULL_OTBL); } return (otbl); }
/* fut_new_chan allocates and initializes a fut_chan_t data structure. * If a required input table is missing, a ramp of the proper grid size * will be created. If a supplied itbl is not required, it will not be * inserted into the channel's private itbl list. All tables which are * actually used are copied and so the caller is responsible for * freeing the passed tables if necessary. * * If VARARGS is used, the list of input tables may be relaced by a * single array of fut_itbl_t pointers. This array must then be followed * by a fut_gtbl_p and a fut_otbl_p. */ fut_chan_p fut_new_chan ( KpInt32_t iomask, fut_itbl_p FAR* itbls, fut_gtbl_p gtbl, fut_otbl_p otbl) { fut_itbl_p itbl[FUT_NCHAN]; fut_chan_p chan; KpInt32_t imask, i, tIndex; /* get input mask */ imask = (KpInt32_t)FUT_IMASK(iomask); /* get args specified by imask */ for ( i=0, tIndex = 0; i<FUT_NCHAN; i++ ) { itbl[i] = ((imask & FUT_BIT(i)) && (itbls != NULL)) ? itbls[tIndex++] : NULL; } /* allocate and clear the fut_chan_t structure */ chan = fut_alloc_chan (); if ( ! IS_CHAN(chan)) { return (NULL); } /* check for valid grid and output tables */ if (( ! IS_GTBL(gtbl)) || ((otbl != NULL) && ( ! IS_OTBL(otbl))) ) { DIAG("fut_new_chan: invalid grid or output table.\n", 0); fut_free_chan (chan); return (NULL); } /* get required input channels from gtbl */ chan->imask = fut_gtbl_imask(gtbl); /* insert the required input tables */ for ( i=0; i<FUT_NICHAN; i++ ) { if ( (chan->imask & FUT_BIT(i)) == 0 ) continue; if ( itbl[i] == FUT_NULL_ITBL ) { chan->itbl[i] = fut_new_itblEx (KCP_REF_TABLES, KCP_FIXED_RANGE, gtbl->size[i], fut_irampEx, NULL); if ( chan->itbl[i] == NULL) { DIAG("fut_new_chan: can't create itbl.\n",0); fut_free_chan (chan); return (NULL); } chan->itblHandle[i] = chan->itbl[i]->handle; } else { if ( ! IS_ITBL (itbl[i])) { DIAG("fut_new_chan: invalid input table.\n", 0); fut_free_chan (chan); return (NULL); } else { if ( itbl[i]->size != gtbl->size[i] ) { DIAG("fut_new_chan: gtbl-itbl size mismatch.\n", 0); fut_free_chan (chan); return (NULL); } else { chan->itbl[i] = fut_share_itbl(itbl[i]); /* share the input table */ chan->itblHandle[i] = chan->itbl[i]->handle; } } } } /* insert grid and output tables */ chan->gtbl = fut_share_gtbl (gtbl); chan->gtblHandle = (IS_GTBL(chan->gtbl)) ? chan->gtbl->handle : FUT_NULL_HANDLE; if (IS_OTBL(otbl)) { chan->otbl = fut_share_otbl (otbl); } else { chan->otbl = fut_alloc_otbl(); } chan->otblHandle = (IS_OTBL(chan->otbl)) ? chan->otbl->handle : FUT_NULL_HANDLE; return (chan); }