/* fut_copy copies an existing fut. */ fut_p fut_copy (fut_p fut) { fut_p new_fut; KpInt32_t i; KpHandle_t h; if ( ! IS_FUT(fut)) { return (0); } /* allocate basic fut_structure */ new_fut = fut_alloc_fut (); if ( new_fut == FUT_NULL ) { return (FUT_NULL); } /* save handle before copying over old fut */ h = new_fut->handle; /* copy over all data (including pointers */ *new_fut = *fut; /* now copy back handle */ new_fut->handle = h; /* copy id string */ new_fut->idstr = 0; /* (void) fut_set_idstr (new_fut, fut->idstr); */ /* copy input tables */ for ( i=0; i<FUT_NICHAN; i++ ) { new_fut->itbl[i] = (IS_SHARED (fut->itbl[i])) ? fut_share_itbl (fut->itbl[i]) : fut_copy_itbl (fut->itbl[i]); new_fut->itblHandle[i] = getHandleFromPtr((KpGenericPtr_t)new_fut->itbl[i]); } /* copy output channels */ for ( i=0; i<FUT_NOCHAN; i++ ) { new_fut->chan[i] = fut_copy_chan (fut->chan[i]); new_fut->chanHandle[i] = getHandleFromPtr((KpGenericPtr_t)new_fut->chan[i]); } /* now check that all copies were succesful */ if ( new_fut->idstr == 0 && fut->idstr != 0 ) { goto ErrOut; } for ( i=0; i<FUT_NICHAN; i++ ) { if ( new_fut->itbl[i] == 0 && fut->itbl[i] != 0) { goto ErrOut; } } for ( i=0; i<FUT_NOCHAN; i++ ) { if ( new_fut->chan[i] == 0 && fut->chan[i] != 0) { goto ErrOut; } } for ( i=0; i<FUT_NMCHAN; i++ ) { /* free extra reference tables */ if (NULL != fut->mabInRefTblHandles[i]) { new_fut->mabInTblEntries[i] = fut->mabInTblEntries[i]; new_fut->mabInRefTbl[i] = (mf2_tbldat_p) allocBufferPtr (new_fut->mabInTblEntries[i] * sizeof (mf2_tbldat_t)); KpMemCpy (new_fut->mabInRefTbl[i], fut->mabInRefTbl[i], new_fut->mabInTblEntries[i] * sizeof (mf2_tbldat_t)); new_fut->mabInRefTblHandles[i] = getHandleFromPtr ((KpGenericPtr_t)new_fut->mabInRefTbl[i]); } if (NULL != fut->mabOutRefTblHandles[i]) { new_fut->mabOutTblEntries[i] = fut->mabOutTblEntries[i]; new_fut->mabOutRefTbl[i] = (mf2_tbldat_p) allocBufferPtr (new_fut->mabOutTblEntries[i] * sizeof (mf2_tbldat_t)); KpMemCpy (new_fut->mabOutRefTbl[i], fut->mabOutRefTbl[i], new_fut->mabOutTblEntries[i] * sizeof (mf2_tbldat_t)); new_fut->mabOutRefTblHandles[i] = getHandleFromPtr ((KpGenericPtr_t)new_fut->mabOutRefTbl[i]); } } return (new_fut); ErrOut: fut_free (new_fut); return (FUT_NULL); }
fut_p fut_resize ( fut_p fut, KpInt32_p sizeArray) { fut_p reSizedGtblFut = NULL, gtblFut = NULL, reSizedFut = NULL, identityFut = NULL; KpInt32_t i1, i2, iomask, iiomask, imask, omask, sameDims; fut_chan_p chan; fut_itbl_p itbl, itbls[FUT_NICHAN]; fut_gtbl_p gtbls[FUT_NOCHAN]; fut_otbl_p otbls[FUT_NOCHAN]; #if defined KCP_DIAG_LOG kcpDiagLog ("fut_resize\n"); #endif if ( ! IS_FUT(fut)) { return NULL; } for (i1 = 0; i1 < FUT_NICHAN; i1++) { itbls[i1] = FUT_NULL_ITBL; /* init to null for freeing on error */ } /* collect the gtbls from the source fut */ /* make sure that all the gtbls use the same itbls */ omask = 0; for (i1 = 0, sameDims = 1; i1 < FUT_NOCHAN; i1++) { chan = fut->chan[i1]; if (IS_CHAN(chan)) { for (i2 = 0; i2 < FUT_NICHAN; i2++) { itbl = fut->itbl[i2]; if (chan->itbl[i2] != itbl) { /* must be shared */ goto GetOut; } if (IS_ITBL(itbl)) { if (itbl->size != sizeArray [i2]) { sameDims = 0; /* not the same */ } } } omask |= FUT_BIT(i1); /* resize this chan */ gtbls[i1] = chan->gtbl; /* collect gtbls */ } else { gtbls[i1] = NULL; } } if (sameDims == 1) { return fut; /* already the right size! */ } imask = fut->iomask.in; iomask = FUT_OUT(omask) | FUT_IN(imask); /* make a new fut with these gtbls and identity itbls and otbls */ gtblFut = fut_new (iomask, NULL, gtbls, NULL); if (gtblFut != NULL) { /* make an identity fut with itbls that have the specified sizes */ iiomask = FUT_OUT(imask) | FUT_IN(imask); identityFut = constructfut (iiomask, sizeArray, NULL, NULL, NULL, NULL, KCP_FIXED_RANGE, KCP_FIXED_RANGE); if (identityFut != NULL) { /* compose the new size fut with the gtbl fut */ reSizedGtblFut = fut_comp (gtblFut, identityFut, 0); if (reSizedGtblFut != NULL) { /* make a new fut with original itbls, ... */ for (i1 = 0; i1 < FUT_NICHAN; i1++) { if ((imask & FUT_BIT(i1)) != 0) { itbls[i1] = fut_copy_itbl (fut->itbl[i1]); /* copy (do not share!) original itbls */ if (itbls[i1] == NULL) { goto GetOut; } makeMftiTblDat (itbls[i1]); /* convert to mft to remove grid size dependancy */ itbls[i1]->size = reSizedGtblFut->itbl[i1]->size; /* set new grid size */ fut_free_itbldat (itbls[i1], freeData); /* free fixed table, it has incorrect grid indices */ } } /* ... resized gtbls, and original otbls */ for (i1 = 0; i1 < FUT_NOCHAN; i1++) { if ((omask & FUT_BIT(i1)) != 0) { gtbls[i1] = reSizedGtblFut->chan[i1]->gtbl; /* collect resized gtbls */ otbls[i1] = fut->chan[i1]->otbl; /* and original otbls */ } else { gtbls[i1] = NULL; otbls[i1] = NULL; } } reSizedFut = fut_new (iomask, itbls, gtbls, otbls); } } } GetOut: fut_free (reSizedGtblFut); /* free the intermediate futs */ fut_free (gtblFut); fut_free (identityFut); fut_free_tbls (FUT_NICHAN, (void **)itbls); return (reSizedFut); }
/* 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); }