- implementation of attribute type handling functions
authorAleš Křenek <ljocha@ics.muni.cz>
Tue, 16 Aug 2005 13:52:05 +0000 (13:52 +0000)
committerAleš Křenek <ljocha@ics.muni.cz>
Tue, 16 Aug 2005 13:52:05 +0000 (13:52 +0000)
- fallback "plugin" for handling attributes of unknown namespace

org.glite.jp.common/interface/attr.h
org.glite.jp.common/interface/strmd5.h
org.glite.jp.common/interface/type_plugin.h
org.glite.jp.common/src/attr.c
org.glite.jp.common/src/strmd5.c

index 2e0ec31..0856963 100644 (file)
@@ -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);
 
index c5d76b6..4ca27a2 100755 (executable)
@@ -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 */
index c901a32..8630be3 100644 (file)
@@ -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);
index e94b965..a745fdc 100644 (file)
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <errno.h>
 
+#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);
+}
index 87fd400..7a35fb1 100755 (executable)
@@ -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;