funkalicious 0.1

binary_data_common.c

Go to the documentation of this file.
00001 /*
00002 ** binary_data_common.c
00003 ** 
00004 
00005 Copyright (C) 2009 Joseph Pingenot
00006 
00007 This program is free software: you can redistribute it and/or modify
00008 it under the terms of the GNU Affero General Public License as published by
00009 the Free Software Foundation, either version 3 of the License, or
00010 (at your option) any later version.
00011 
00012 This program is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU Affero General Public License for more details.
00016 
00017 You should have received a copy of the GNU Affero General Public License
00018 along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 
00020 ** Made by (Johnny Q. Hacker)
00021 ** Login   <solarion@nathan>
00022 ** 
00023 ** Started on  Tue Nov 24 21:39:39 2009 Johnny Q. Hacker
00024 ** Last update Sun May 12 01:17:25 2002 Speed Blue
00025 */
00026 
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <glib-2.0/glib.h>
00030 #include <stdio.h>
00031 #include "binary_data_common.h"
00032 
00033 #define DOTCODE_BINARY_DATA_COMMON_GERROR_DOMAN 43712
00034 
00035 enum dotcode_type dotcode_type_from_string(const char* s) {
00036   if(!g_ascii_strncasecmp(s, "float8", strlen("float8"))){
00037     return DOTCODE_FLOAT8;
00038   }else if(!g_ascii_strncasecmp(s, "float4", strlen("float4"))){
00039     return DOTCODE_FLOAT4;
00040   }else if(!g_ascii_strncasecmp(s, "int", strlen("int"))){
00041     return DOTCODE_INT;
00042   }else if(!g_ascii_strncasecmp(s, "int4", strlen("int4"))){
00043     return DOTCODE_INT;
00044   }else if(!g_ascii_strncasecmp(s, "Vector", strlen("Vector"))){
00045     return DOTCODE_VECTOR;
00046   }else if(!g_ascii_strncasecmp(s, "Array", strlen("Array"))){
00047     return DOTCODE_ARRAY;
00048   }else if(!g_ascii_strncasecmp(s, "Tensor", strlen("Tensor"))){
00049     return DOTCODE_TENSOR;
00050   }else if(!g_ascii_strncasecmp(s, "Grid", strlen("Grid"))){
00051     return DOTCODE_GRID;
00052   }else if(!g_ascii_strncasecmp(s, "SString", strlen("SString"))){
00053     return DOTCODE_SSTRING;
00054   }
00055   return DOTCODE_INVALID_TYPE;
00056 }
00057 
00058 char* dotcode_string_from_type(enum dotcode_type t) {
00059   const char* s = dotcode_string_from_type2(t);
00060   if(s == NULL) return NULL;
00061   return g_strdup(s);
00062 }
00063 
00064 const char* dotcode_string_from_type2(enum dotcode_type t) {
00065   switch(t) {
00066   case DOTCODE_FLOAT8:
00067     return g_strdup("float8");
00068   case DOTCODE_FLOAT4:
00069     return g_strdup("float4");
00070   case DOTCODE_INT:
00071     return g_strdup("int4");
00072   case DOTCODE_VECTOR:
00073     return g_strdup("Vector");
00074   case DOTCODE_ARRAY:
00075     return g_strdup("Array");
00076   case DOTCODE_TENSOR:
00077     return g_strdup("Tensor");
00078   case DOTCODE_GRID:
00079     return g_strdup("Grid");
00080   case DOTCODE_SSTRING:
00081     return g_strdup("SString");
00082   case DOTCODE_INVALID_TYPE:
00083     return g_strdup("INVALID TYPE");
00084   default:
00085     return NULL;
00086   }
00087   return NULL;
00088 }
00089 
00090 void flip_endian(char* buffer, int num_bytes) {
00091   int i, j;
00092   char c;
00093   int max = num_bytes >> 1;
00094   for(i=0, j=(num_bytes-1); i<max; ++i, --j) {
00095     c=buffer[i];
00096     buffer[i]=buffer[j];
00097     buffer[j]=c;
00098   }
00099 }
00100 
00101 /*It is assumed that ptr points to a buffer of count objects.*/
00102 void dotcode_free_type(enum dotcode_type t, void* ptr, long unsigned int count, GError **err, gboolean free_struct) {
00103   GError *e = NULL;
00104   /*If we have a buffer of a simple type, just free it.*/
00105   switch(t) {
00106   case DOTCODE_FLOAT8:
00107   case DOTCODE_FLOAT4:
00108   case DOTCODE_INT:
00109   case DOTCODE_SSTRING:
00110     free(ptr);
00111     return;
00112   default:
00113     break;
00114   }
00115   long unsigned int size = 1;
00116   for(long unsigned int i=0; i<count; i++) {
00117     /*Since these are freeing an array of actual structures (as
00118       opposed to an array of pointers to structures) we don't need to
00119       free the struct at the end.*/
00120     switch(t) {
00121     case DOTCODE_VECTOR:
00122       dotcode_free_type(((struct dotcode_vector*)ptr)->t, 
00123       ((struct dotcode_vector*)ptr)->data,
00124       3,
00125       &e,
00126       FALSE);
00127       break;
00128     case DOTCODE_ARRAY:
00129       dotcode_free_type(((struct dotcode_array*)ptr)->t, 
00130       ((struct dotcode_array*)ptr)->storage,
00131       (((struct dotcode_array*)ptr)->imax - ((struct dotcode_array*)ptr)->imax +1),
00132       &e,
00133       FALSE);
00134       break;
00135     case DOTCODE_TENSOR:
00136       /*need to know how many items there are, for the derived types
00137   (irrelevant for float, int)*/
00138       size = 1;
00139       for(long unsigned int j=0; j<((struct dotcode_tensor*)ptr)->Nd; j++) 
00140        size*=((((struct dotcode_tensor*)ptr)->indices)[2*j+1]-(((struct dotcode_tensor*)ptr)->indices)[2*j]+1);
00141       /*need to know how many items there are*/
00142       dotcode_free_type(((struct dotcode_tensor*)ptr)->t, 
00143       ((struct dotcode_tensor*)ptr)->data,
00144       size,
00145       &e,
00146       FALSE);
00147       free(((struct dotcode_tensor*)ptr)->indices);
00148       free(((struct dotcode_tensor*)ptr)->metadata);
00149       break;
00150     case DOTCODE_GRID:
00151       for(int i=0; i<3; i++) {
00152   dotcode_free_type(DOTCODE_ARRAY,
00153       ((struct dotcode_grid*)ptr)->gridsites[i],
00154       1,
00155       &e,
00156       TRUE);
00157       }
00158       dotcode_free_type(DOTCODE_TENSOR,
00159       ((struct dotcode_grid*)ptr)->data,
00160       1,
00161       &e,
00162       TRUE);
00163       break;
00164     default:
00165       *err = g_error_new(DOTCODE_BINARY_DATA_COMMON_GERROR_DOMAN, 1, "dotcode::binary_data_common::dotcode_free_type: Invalid type %d (%s)", t, dotcode_string_from_type2(t));
00166       return;
00167     }
00168     if(e != NULL) {
00169       g_propagate_prefixed_error(err, e, "dotcode::binary_data_common::dotcode_free_type: Failure when freeing type %d (%s)", t, dotcode_string_from_type2(t));
00170       return;
00171     }
00172   }
00173   if(free_struct) {
00174     switch(t) {
00175     case DOTCODE_VECTOR:
00176       free((struct dotcode_vector*)ptr);
00177       break;
00178     case DOTCODE_ARRAY:
00179       free((struct dotcode_array*)ptr);
00180       break;
00181     case DOTCODE_TENSOR:
00182       free((struct dotcode_tensor*)ptr);
00183       break;
00184     case DOTCODE_GRID:
00185       free((struct dotcode_grid*)ptr);
00186       break;
00187     default:
00188       break;
00189     }
00190   }
00191 }
00192 
00193 /**Determines a type from a type string.
00194  *\param t1 is the first item in the char** returned from g_strsplit(str, "<", 1)
00195  *\param t2 is the second string in the char**
00196  *\param tlist a pointer to an *existing* NULL GList*.
00197  *Types may be nested, hence the need for a GList of types.
00198  *The data in the GList is enum dotcode_type.
00199  *NOTE that the tlist MUST be initialized to NULL before calling this 
00200  *  function, as it's recursive.
00201  */
00202 static void determine_templated_type_(char* t1, char*t2 , GList** tlist, GError **err) {
00203   if(t1 == NULL) return;
00204   enum dotcode_type *t = (enum dotcode_type*)malloc(sizeof(enum dotcode_type));
00205   if(t == NULL) {
00206     *err = g_error_new(DOTCODE_BINARY_DATA_COMMON_GERROR_DOMAN, 180, "dotcode::read_binary_data::read_vector: ERROR failed to allocate storage for a new vector.");
00207   }
00208   *t = dotcode_type_from_string(t1);
00209   if(t2 != NULL) {
00210     /*Here's the recursive step.*/
00211     char** sstr = g_strsplit(t2, "<", 2);
00212     determine_templated_type_(sstr[0], sstr[1], tlist, err);
00213     g_strfreev(sstr);
00214   }
00215   *tlist = g_list_prepend(*tlist, t);
00216 }
00217 
00218 /**This is the front-end to the determine_templated_type_ function.
00219  *\param str is the list
00220  *\param tlist a pointer to an *existing* GList*, which will be set to NULL.
00221  *\param err is a pointer to an existing NULL GError*
00222  *\note the tlist is a GList of pointers to dotcode_types, in order of occurrance.
00223  *   Thus, a GList of a, b, c means a templated with b, which is in turn
00224  *   templated with c.
00225  */
00226 void dotcode_determine_templated_type(const char* str, GList** tlist, GError **err) {
00227   *tlist = NULL;
00228   /*Remove invalid chars; valid are alphanumeric, underscoe, and >; this will
00229     remove '>', but that's fine; we don't really want it.
00230    */
00231   char* dstr = g_strdup(str);
00232   g_strcanon(dstr, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_<", ' ');
00233   g_strchug(dstr);
00234   char** sstr = g_strsplit(dstr, "<", 2);
00235   determine_templated_type_(sstr[0], sstr[1], tlist, err);
00236   g_free(dstr);
00237   g_strfreev(sstr);
00238 }
00239 
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines