IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Opened 21 years ago

Closed 20 years ago

Last modified 20 years ago

#579 closed enhancement (fixed)

New function: psMetadataCopy

Reported by: Paul Price Owned by: David.Robbins@…
Priority: high Milestone:
Component: types Version: unspecified
Severity: minor Keywords:
Cc: robert.desonia@…, rhl@…

Description

Adding a new function, at RHL's request. I could put together a prototype, if
desired, but I think it's fairly straightforward.

There will be occasions when we want to perform a deep copy of a
\code{psMetadata}, for example, to generate a new and independent FITS
header.
\begin{prototype}
psMetadata *psMetadataCopy(psMetadata *out, const psMetadata *in);
\end{prototype}
\code{psMetadataCopy} shall create a new copy of all
\code{psMetadataItem}s in the \code{in} metadata, and place them in
the \code{out} metadata, or a new \code{psMetadata} if \code{out} is
\code{NULL}. Now, it is not feasible (at this time) to be able to
copy every type that we might put on a \code{psMetadata}. Therefore,
\code{psMetadataCopy} shall copy only the numerical types and strings.
Other pointer types may simply have the pointer copied (with the
reference counter incremented appropriately), with the total number of
such copies (if positive) reported in a warning at the end of the
function.

Change History (10)

comment:1 by robert.desonia@…, 21 years ago

Status: newassigned

comment:2 by robert.desonia@…, 21 years ago

Cc: robert.desonia@… added
Owner: changed from robert.desonia@… to David.Robbins@…
Status: assignednew

comment:3 by David.Robbins@…, 21 years ago

Resolution: fixed
Status: newclosed

Done.

comment:4 by Paul Price, 21 years ago

Resolution: fixed
Status: closedreopened

The implementation in 0.9.0 simply puts the psMetadataItems that are on one
psMetadata onto a new psMetadata. What we really want is a new copy of the data
that is on the psMetadata, so that we can change it without changing the
original. One example is FITS headers --- we might read in an image with the
header, manipulate the image, and want to write it out with an altered header
without altering the original header.

Here's an implementation that's more in keeping with what I had in mind (also in
psAdditionals.c in psModule branch pap_branch_051214):

psMetadata *pap_psMetadataCopy(psMetadata *out,

const psMetadata *in)

{

PS_ASSERT_PTR_NON_NULL(in,NULL);
if (out == NULL) {

out = psMetadataAlloc();

}
psMetadataItem *inItem = NULL;
psMetadataIterator *iter = psMetadataIteratorAlloc(*(psMetadata)&in,

PS_LIST_HEAD, NULL);

unsigned long numPointers = 0; Number of pointers we were forced to copy
while ((inItem = psMetadataGetAndIncrement(iter))) {

Need to look for MULTI, which won't be picked up using the iterator.
psMetadataItem *multiCheckItem = psMetadataLookup(in, inItem->name);
unsigned int flag = PS_META_REPLACE;
Flag to indicate MULTI;

otherwise, replace

if (multiCheckItem->type == PS_DATA_METADATA_MULTI) {

psTrace(func, 10, "MULTI: %s (%s)\n", inItem->name,

inItem->comment);

flag = PS_DATA_METADATA_MULTI;

}

psTrace(func, 5, "Copying %s (%s)...\n", inItem->name, inItem->comment);

#define PS_METADATA_COPY_CASE(NAME,TYPE) \

case PS_TYPE_##NAME: \

if (! psMetadataAdd(out, PS_LIST_TAIL, inItem->name, PS_TYPE_##NAME

| flag, inItem->comment, \

inItem->data.TYPE)) { \

psErrorStackPrint(stderr, "Error copying %s (%s) in the

metadata\n", inItem->name, \

inItem->comment); \

} \
break;

switch (inItem->type) {

Numerical types
PS_METADATA_COPY_CASE(BOOL,B);
PS_METADATA_COPY_CASE(S8,S8);
PS_METADATA_COPY_CASE(S16,S16);
PS_METADATA_COPY_CASE(S32,S32);
PS_METADATA_COPY_CASE(U8,U8);
PS_METADATA_COPY_CASE(U16,U16);
PS_METADATA_COPY_CASE(U32,U32);
PS_METADATA_COPY_CASE(F32,F32);
PS_METADATA_COPY_CASE(F64,F64);

String: relying on the fact that this will copy the string, not

point at it.

case PS_DATA_STRING:

psMetadataAdd(out, PS_LIST_TAIL, inItem->name, PS_DATA_STRING |

flag, inItem->comment,

inItem->data.V);

break;

Metadata: copy the next level and stuff that in too

case PS_DATA_METADATA:

{

psMetadata *metadata = pap_psMetadataCopy(NULL, inItem->data.md);
psMetadataAdd(out, PS_LIST_TAIL, inItem->name, PS_DATA_METADATA

| flag, inItem->comment,

metadata);

break;

}
Other kinds of pointers

default:

numPointers++;
psTrace(func, 10, "Copying a pointer in the metadata: %x\n",

inItem->type);

psMetadataAdd(out, PS_LIST_TAIL, inItem->name, inItem->type | flag,

inItem->comment,

inItem->data.V);

break;

}

}
psFree(iter);

if (numPointers > 0) {

psLogMsg(func, PS_LOG_WARN, "Forced to copy %d pointers when copying

metadata. Updating the "

"copied psMetadata will affect the original!\n", numPointers);

}

return out;

}

comment:5 by David.Robbins@…, 20 years ago

Resolution: fixed
Status: reopenedclosed

Ok, I see your point. I've incorporated your changes into psMetadataCopy.
However, I've expanded the cases to include vectors and times. This will create
new copies of those vectors and times as desired. I've also commented out the
cases S8, S16, U8, U16, U32 because these types currently are not present in
psDataType.

comment:6 by Paul Price, 20 years ago

S8, S16, U8, U16, U32 are included in psMetadata.data, so we should include them
in psMetadataCopy. We should upgrade psDataType to match the current range of
psMetadata.data:

typedef enum { /< type of item.data is:

PS_TYPE_S8 = PS_TYPE_S8, /< psS8
PS_TYPE_S16 = PS_TYPE_S16,
/< psS16
PS_DATA_S32 = PS_TYPE_S32, /< psS32
PS_TYPE_U8 = PS_TYPE_U8,
/< psU8
PS_TYPE_U16 = PS_TYPE_U16, /< psU16
PS_TYPE_U32 = PS_TYPE_U32,
/< psU32
PS_DATA_F32 = PS_TYPE_F32, /< psF32
PS_DATA_F64 = PS_TYPE_F64,
/< psF64
PS_DATA_BOOL = PS_TYPE_BOOL, /< psBool
PS_DATA_STRING = 0x10000,
/< String (char *)

....
} psDataType;

comment:7 by David.Robbins@…, 20 years ago

ok, updated psDataType. Also updated Metadata to use these types. What about
S64, U64, C32, and C64? If you want these too, please let me know.

comment:8 by Paul Price, 20 years ago

I don't think we're supporting those in psMetadata.... or at least, not yet. We
may in the future, but not now.

comment:9 by Paul Price, 20 years ago

Keywords: VERIFIED added

Bug has been resolved.... closing.

comment:10 by Paul Price, 20 years ago

Keywords: VERIFIED removed

Bugs have been fixed... closing.

Note: See TracTickets for help on using tickets.