From: Panu Matilainen Date: Wed, 25 Mar 2009 11:08:09 +0000 (+0200) Subject: Add a type + basic api for bundle of digests (on same data) X-Git-Tag: tznext/4.11.0.1.tizen20130304~3059 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c9146aa580ab87b93ba5d68cde5b606652c93cd8;p=tools%2Flibrpm-tizen.git Add a type + basic api for bundle of digests (on same data) - in various places we need to calculate different digests of the same data, having them stored in a single container makes managing easier - can hold as many digest types as we support - remembers how much input data it has handled --- diff --git a/rpmio/digest.c b/rpmio/digest.c index 09002d8..707d6e0 100644 --- a/rpmio/digest.c +++ b/rpmio/digest.c @@ -24,6 +24,91 @@ struct DIGEST_CTX_s { pgpHashAlgo algo; /*!< Used hash algorithm */ }; +#define DIGESTS_MAX 11 +struct rpmDigestBundle_s { + int index_min; /*!< Smallest index of active digest */ + int index_max; /*!< Largest index of active digest */ + off_t nbytes; /*!< Length of total input data */ + DIGEST_CTX digests[DIGESTS_MAX]; /*!< Digest contexts indexed by algo */ +}; + +rpmDigestBundle rpmDigestBundleNew(void) +{ + rpmDigestBundle bundle = xcalloc(1, sizeof(*bundle)); + return bundle; +} + +rpmDigestBundle rpmDigestBundleFree(rpmDigestBundle bundle) +{ + if (bundle) { + for (int i = bundle->index_min; i <= bundle->index_max ; i++) { + if (bundle->digests[i] == NULL) + continue; + rpmDigestFinal(bundle->digests[i], NULL, NULL, 0); + bundle->digests[i] = NULL; + } + memset(bundle, 0, sizeof(*bundle)); + free(bundle); + } + return NULL; +} + +int rpmDigestBundleAdd(rpmDigestBundle bundle, pgpHashAlgo algo, + rpmDigestFlags flags) +{ + DIGEST_CTX ctx = NULL; + if (bundle && algo > 0 && algo < DIGESTS_MAX) { + if (bundle->digests[algo] == NULL) { + ctx = rpmDigestInit(algo, flags); + if (ctx) { + bundle->digests[algo] = ctx; + if (algo < bundle->index_min) { + bundle->index_min = algo; + } + if (algo > bundle->index_max) { + bundle->index_max = algo; + } + } + } + } + return (ctx != NULL); +} + +int rpmDigestBundleUpdate(rpmDigestBundle bundle, const void *data, size_t len) +{ + int rc = 0; + if (bundle && data && len > 0) { + for (int i = bundle->index_min; i <= bundle->index_max; i++) { + DIGEST_CTX ctx = bundle->digests[i]; + if (ctx == NULL) + continue; + rc += rpmDigestUpdate(ctx, data, len); + } + bundle->nbytes += len; + } + return rc; +} + +int rpmDigestBundleFinal(rpmDigestBundle bundle, + pgpHashAlgo algo, void ** datap, size_t * lenp, int asAscii) +{ + int rc = 0; + if (bundle && algo >= bundle->index_min && algo <= bundle->index_max) { + rc = rpmDigestFinal(bundle->digests[algo], datap, lenp, asAscii); + bundle->digests[algo] = NULL; + } + return rc; +} + +DIGEST_CTX rpmDigestBundleDupCtx(rpmDigestBundle bundle, pgpHashAlgo algo) +{ + DIGEST_CTX dup = NULL; + if (bundle && algo >= bundle->index_min && algo <= bundle->index_max) { + dup = rpmDigestDup(bundle->digests[algo]); + } + return dup; +} + DIGEST_CTX rpmDigestDup(DIGEST_CTX octx) { diff --git a/rpmio/rpmpgp.h b/rpmio/rpmpgp.h index bdc883b..c3d6097 100644 --- a/rpmio/rpmpgp.h +++ b/rpmio/rpmpgp.h @@ -23,6 +23,7 @@ extern "C" { /** \ingroup rpmpgp */ typedef struct DIGEST_CTX_s * DIGEST_CTX; +typedef struct rpmDigestBundle_s * rpmDigestBundle; /** \ingroup rpmpgp */ @@ -1100,6 +1101,59 @@ int rpmDigestFinal(DIGEST_CTX ctx, void ** datap, size_t * lenp, int asAscii); +/** \ingroup rpmpgp + * Create a new digest bundle. + * @return New digest bundle + */ +rpmDigestBundle rpmDigestBundleNew(void); + +/** \ingroup rpmpgp + * Free a digest bundle and all contained digest contexts. + * @param bundle digest bundle + * @return NULL always + */ +rpmDigestBundle rpmDigestBundleFree(rpmDigestBundle bundle); + +/** \ingroup rpmpgp + * Add a new type of digest to a bundle. + * @param bundle digest bundle + * @param algo type of digest + * @param flags bit(s) to control digest operation + * @return 0 on success + */ +int rpmDigestBundleAdd(rpmDigestBundle bundle, pgpHashAlgo algo, + rpmDigestFlags flags); + +/** \ingroup rpmpgp + * Update contexts within bundle with next plain text buffer. + * @param bundle digest bundle + * @param data next data buffer + * @param len no. bytes of data + * @return 0 on success + */ +int rpmDigestBundleUpdate(rpmDigestBundle bundle, const void *data, size_t len); + +/** \ingroup rpmpgp + * Return digest from a bundle and destroy context, see rpmDigestFinal(). + * + * @param bundle digest bundle + * @param algo type of digest to return + * @retval datap address of returned digest + * @retval lenp address of digest length + * @param asAscii return digest as ascii string? + * @return 0 on success + */ +int rpmDigestBundleFinal(rpmDigestBundle bundle, + pgpHashAlgo algo, void ** datap, size_t * lenp, int asAscii); + +/** \ingroup rpmpgp + * Duplicate a digest context from a bundle. + * @param bundle digest bundle + * @param algo type of digest to dup + * @return duplicated digest context + */ +DIGEST_CTX rpmDigestBundleDupCtx(rpmDigestBundle bundle, pgpHashAlgo algo); + #ifdef __cplusplus } #endif