From 1d0f79aa83f2ab0580e1cba0f49a496f21437b88 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ale=C5=A1=20K=C5=99enek?= Date: Tue, 16 Aug 2005 13:52:05 +0000 Subject: [PATCH] - implementation of attribute type handling functions - fallback "plugin" for handling attributes of unknown namespace --- org.glite.jp.common/interface/attr.h | 2 +- org.glite.jp.common/interface/strmd5.h | 4 + org.glite.jp.common/interface/type_plugin.h | 7 +- org.glite.jp.common/src/attr.c | 137 +++++++++++++++++++++------- org.glite.jp.common/src/strmd5.c | 44 ++++++++- 5 files changed, 159 insertions(+), 35 deletions(-) diff --git a/org.glite.jp.common/interface/attr.h b/org.glite.jp.common/interface/attr.h index 2e0ec31..0856963 100644 --- a/org.glite.jp.common/interface/attr.h +++ b/org.glite.jp.common/interface/attr.h @@ -15,7 +15,7 @@ int glite_jp_attrval_cmp(glite_jp_context_t ctx,const glite_jp_attrval_t *a,cons char *glite_jp_attrval_to_db_full(glite_jp_context_t ctx,const glite_jp_attrval_t *attr); char *glite_jp_attrval_to_db_index(glite_jp_context_t ctx,const glite_jp_attrval_t *attr,int len); -int *glite_jp_attrval_from_db(glite_jp_context_t ctx,const char *str,glite_jp_attrval_t *attr); +int glite_jp_attrval_from_db(glite_jp_context_t ctx,const char *str,glite_jp_attrval_t *attr); const char *glite_jp_attrval_db_type_full(glite_jp_context_t ctx,const char *attr); const char *glite_jp_attrval_db_type_index(glite_jp_context_t ctx,const char *attr,int len); diff --git a/org.glite.jp.common/interface/strmd5.h b/org.glite.jp.common/interface/strmd5.h index c5d76b6..4ca27a2 100755 --- a/org.glite.jp.common/interface/strmd5.h +++ b/org.glite.jp.common/interface/strmd5.h @@ -25,4 +25,8 @@ char *str2md5(const char *src); */ char *str2md5base64(const char *src); +int base64_encode(const void *enc, int enc_size, char *out, int out_max_size); +int base64_decode(const char *enc,char *out,int out_size); + + #endif /* _GLITE_STRMD5_H */ diff --git a/org.glite.jp.common/interface/type_plugin.h b/org.glite.jp.common/interface/type_plugin.h index c901a32..8630be3 100644 --- a/org.glite.jp.common/interface/type_plugin.h +++ b/org.glite.jp.common/interface/type_plugin.h @@ -42,12 +42,17 @@ typedef struct _glite_jp_tplug_data_t { */ char * (*to_db_index)(void *ctx,const glite_jp_attrval_t *attr,int len); -/** Convert from +/** Convert from the database format. + * \param[in] str the string value + * \param[inout] attr name contains the name of the attribute to be converted + * the rest of attr is filled in. + */ int (*from_db)(void *ctx,const char *str,glite_jp_attrval_t *attr); /** Query for database types suitable to store values returned by * to_db_full() and to_db_index(). * Useful for db column dynamic creation etc. + * Return pointer to internal static data, non-reentrant. */ const char * (*db_type_full)(void *ctx,const char *attr); const char * (*db_type_index)(void *ctx,const char *attr,int len); diff --git a/org.glite.jp.common/src/attr.c b/org.glite.jp.common/src/attr.c index e94b965..a745fdc 100644 --- a/org.glite.jp.common/src/attr.c +++ b/org.glite.jp.common/src/attr.c @@ -4,6 +4,7 @@ #include #include +#include "strmd5.h" #include "types.h" #include "attr.h" #include "type_plugin.h" @@ -16,14 +17,97 @@ void glite_jp_attrval_free(glite_jp_attrval_t *a,int f) if (f) free(a); } -static glite_jp_tplug_data_t *get_plugin(glite_jp_context_t ctx,const glite_jp_attrval_t *a) +#define min(x,y) ((x) > (y) ? (y) : (x)) + +static int fb_cmp(void *ctx,const glite_jp_attrval_t *a,const glite_jp_attrval_t *b,int *result) +{ + if (a->binary != b->binary) return EINVAL; + if (a->binary) { + *result = memcmp(a->value,b->value,min(a->size,b->size)); + if (!*result && a->size != b->size) + *result = a->size > b->size ? 1 : -1; + } + else *result = strcmp(a->value,b->value); + return 0; +} + +static char * fb_to_db_full(void *ctx,const glite_jp_attrval_t *attr) +{ + char *db; + if (attr->binary) { + int osize = attr->size * 4/3 + 6; + db = malloc(osize); + db[0] = 'B'; db[1] = ':'; + osize = base64_encode(attr->value,attr->size,db+2,osize-3); + assert(osize >= 0); + db[osize] = 0; + } + else { + db = malloc(strlen(attr->value)+3); + db[0] = 'S'; db[1] = ':'; + strcpy(db+2,attr->value); + } +} + +static char * fb_to_db_index(void *ctx,const glite_jp_attrval_t *attr,int len) +{ + char *db = fb_to_db_full(ctx,attr); + if (len < strlen(db)) db[len] = 0; + return db; +} + +int fb_from_db(void *ctx,const char *str,glite_jp_attrval_t *attr) +{ + int osize; + switch (str[0]) { + case 'B': + attr->value = malloc(osize = strlen(str) * 3/4 + 4); + attr->size = base64_decode(str,attr->value+2,osize); + assert(attr->size >= 0); + attr->binary = 1; + break; + case 'S': + attr->value = strdup(attr->value + 2); + attr->size = 0; + attr->binary = 0; + break; + default: return EINVAL; + } +} + +static const char * fb_type_full(void *ctx,const char *attr) +{ + return "mediumblob"; +} + +static const char * fb_type_index(void *ctx,const char *attr,int len) +{ + static char tbuf[100]; + sprintf(tbuf,"varchar(%d)",len); + return tbuf; +} + + + +static glite_jp_tplug_data_t fallback_plugin = { + "", + NULL, + fb_cmp, + fb_to_db_full, + fb_to_db_index, + fb_from_db, + fb_type_full, + fb_type_index, +}; + +static glite_jp_tplug_data_t *get_plugin(glite_jp_context_t ctx,const char *aname) { void **cp = ctx->type_plugins; char *colon,*ns; assert(cp); glite_jp_clear_error(ctx); - ns = strdup(a->name); + ns = strdup(aname); colon = strrchr(ns,':'); if (colon) *colon = 0; else *ns = 0; @@ -35,26 +119,13 @@ static glite_jp_tplug_data_t *get_plugin(glite_jp_context_t ctx,const glite_jp_a } } free(ns); - return NULL; + return &fallback_plugin; /* XXX: is it always desirable? */ } -#define check_ap(ap,attr,eret) \ - if (!(ap)) { \ - err.code = ENOENT; \ - snprintf(ebuf,sizeof ebuf - 1, \ - "Can't find type plugin for %s",(attr)->name); \ - ebuf[sizeof ebuf - 1] = 0; \ - err.desc = ebuf; \ - glite_jp_stack_error(ctx,&err); \ - return eret; \ - } - - int glite_jp_attrval_cmp(glite_jp_context_t ctx,const glite_jp_attrval_t *a,const glite_jp_attrval_t *b,int *result) { - glite_jp_tplug_data_t *ap = get_plugin(ctx,a); + glite_jp_tplug_data_t *ap = get_plugin(ctx,a->name); glite_jp_error_t err; - char ebuf[BUFSIZ]; memset(&err,0,sizeof err); err.source = __FUNCTION__; @@ -66,42 +137,46 @@ int glite_jp_attrval_cmp(glite_jp_context_t ctx,const glite_jp_attrval_t *a,cons return glite_jp_stack_error(ctx,&err); } - check_ap(ap,a,err.code); - return ap->cmp(ap->pctx,a,b,result); } char *glite_jp_attrval_to_db_full(glite_jp_context_t ctx,const glite_jp_attrval_t *attr) { - glite_jp_tplug_data_t *ap = get_plugin(ctx,attr); - glite_jp_error_t err; - char ebuf[BUFSIZ]; - int result; + glite_jp_tplug_data_t *ap = get_plugin(ctx,attr->name); - memset(&err,0,sizeof err); - err.source = __FUNCTION__; glite_jp_clear_error(ctx); - - check_ap(ap,attr,NULL); return ap->to_db_full(ap->pctx,attr); } char *glite_jp_attrval_to_db_index(glite_jp_context_t ctx,const glite_jp_attrval_t *attr,int len) { + glite_jp_tplug_data_t *ap = get_plugin(ctx,attr->name); + + glite_jp_clear_error(ctx); + return ap->to_db_index(ap->pctx,attr,len); } -int *glite_jp_attrval_from_db(glite_jp_context_t ctx,const char *str,glite_jp_attrval_t *attr) +int glite_jp_attrval_from_db(glite_jp_context_t ctx,const char *str,glite_jp_attrval_t *attr) { + glite_jp_tplug_data_t *ap = get_plugin(ctx,attr->name); + + glite_jp_clear_error(ctx); + return ap->from_db(ap->pctx,str,attr); } const char *glite_jp_attrval_db_type_full(glite_jp_context_t ctx,const char *attr) { + glite_jp_tplug_data_t *ap = get_plugin(ctx,attr); + + glite_jp_clear_error(ctx); + return ap->db_type_full(ap->pctx,attr); } const char *glite_jp_attrval_db_type_index(glite_jp_context_t ctx,const char *attr,int len) { -} - - + glite_jp_tplug_data_t *ap = get_plugin(ctx,attr); + glite_jp_clear_error(ctx); + return ap->db_type_index(ap->pctx,attr,len); +} diff --git a/org.glite.jp.common/src/strmd5.c b/org.glite.jp.common/src/strmd5.c index 87fd400..7a35fb1 100755 --- a/org.glite.jp.common/src/strmd5.c +++ b/org.glite.jp.common/src/strmd5.c @@ -7,9 +7,12 @@ static char mbuf[33]; -static int base64_encode(const void *enc, int enc_size, char *out, int out_max_size) +static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + +static char *b64r; + +int base64_encode(const void *enc, int enc_size, char *out, int out_max_size) { - static const char* b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; unsigned char* enc_buf = (unsigned char*)enc; int out_size = 0; @@ -50,6 +53,43 @@ static int base64_encode(const void *enc, int enc_size, char *out, int out_max_s return -1; } +int base64_decode(const char *enc,char *out,int max_out_size) +{ + unsigned int bits = 0; + int shift = 0; + int out_size = 0; + + if (!b64r) { + int i; + b64r = calloc(128,1); + + for (i=0; b64[i]; i++) b64r[b64[i]] = i; + } + + while (*enc && *enc != '=') { + bits << 6; + bits |= b64r[*enc++]; + shift += 6; + + while (shift >= 8) { + if (out_size >= max_out_size) return -1; + shift -= 8; + *out++ = (bits >> shift) & 0xff; + out_size++; + } + } + + /* XXX: will it ever happen? */ + if (shift) { + if (out_size >= max_out_size) return -1; + bits <<= 8-shift; + *out = bits & 0xff; + out_size++; + } + + return out_size; +} + char *strmd5(const char *s, unsigned char *digest) { MD5_CTX md5; -- 1.8.2.3