/* 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); }
/* fut_copy_chan makes a copy of an existing fut_chan_t structure. */ fut_chan_p fut_copy_chan (fut_chan_p chan) { fut_chan_p new_chan; KpInt32_t i; KpHandle_t h; if ( ! IS_CHAN(chan) ) { return (FUT_NULL_CHAN); } new_chan = fut_alloc_chan (); if ( new_chan == FUT_NULL_CHAN ) { return (FUT_NULL_CHAN); } /* save handle before copying over old fut */ h = new_chan->handle; /* copy over to new structure */ *new_chan = *chan; /* move handle back to new structure */ new_chan->handle = h; /* copy itbls * if an itbl is shared, share it with the itbl in the new fut */ for ( i=0; i<FUT_NICHAN; i++ ) { new_chan->itbl[i] = (IS_SHARED (chan->itbl[i])) ? fut_share_itbl (chan->itbl[i]) : fut_copy_itbl (chan->itbl[i]); new_chan->itblHandle[i] = getHandleFromPtr((KpGenericPtr_t)new_chan->itbl[i]); } /* copy gtbl */ new_chan->gtbl = fut_copy_gtbl (chan->gtbl); new_chan->gtblHandle = getHandleFromPtr((KpGenericPtr_t)new_chan->gtbl); /* copy otbl */ new_chan->otbl = (IS_SHARED(chan->otbl)) ? fut_share_otbl (chan->otbl) : fut_copy_otbl (chan->otbl); new_chan->otblHandle = getHandleFromPtr((KpGenericPtr_t)new_chan->otbl); /* check for successful copies */ for ( i=0; i<FUT_NICHAN; i++ ) { if ( new_chan->itbl[i] == 0 && chan->itbl[i] != 0 ) { goto ErrOut; } } if ( (new_chan->otbl == 0 && chan->otbl != 0) || (new_chan->gtbl == 0 && chan->gtbl != 0) ) { goto ErrOut; } return (new_chan); ErrOut: fut_free_chan (new_chan); return (FUT_NULL_CHAN); }