Exemple #1
0
void print_f64(cbuf_t* in, int n)
{
    int i;
    for (i = 0; i < n; i++) {
	double val;
	get_float64(in, &val);
	printf("%f ", val);
    }
    printf("\n");
}
/* given a return value in OCaml land, translate it to 
   the return_val_t C structure
*/ 
return_val_t translate_return_value(value ocaml_result) {
  CAMLparam1(ocaml_result);
  CAMLlocal5(ocaml_shape, ocaml_strides, ocaml_data, ocaml_cur, ocaml_type);
  CAMLlocal1(v);
  
  return_val_t ret;
  
  if (Is_long(ocaml_result)) {
    // In this case, we know that the return code must have been Pass,
    // since the other two return codes have data.
    ret.return_code = RET_PASS;
    ret.results_len = 0;
  } else if (Tag_val(ocaml_result) == RET_FAIL) {
    ret.return_code = RET_FAIL;
    ret.results_len = caml_string_length(Field(ocaml_result, 0));
    ret.error_msg = malloc(ret.results_len + 1);
    strcpy(ret.error_msg, String_val(Field(ocaml_result, 0)));
  } else if (Tag_val(ocaml_result) == RET_SUCCESS) {
    
    ocaml_cur = Field(ocaml_result, 0);
    ret.return_code = RET_SUCCESS;
    ret.results_len = ocaml_list_length(ocaml_cur);
    ret.results = (ret_t*)malloc(sizeof(ret_t) * ret.results_len);
    
    int i, j;
    host_val h; 
    for (i = 0; i < ret.results_len; ++i) {
      v = Field(ocaml_cur, 0);
      h = create_host_val(v);  
      ocaml_cur = Field(ocaml_cur, 1);
      // returning a scalar
      if (value_is_scalar(h)) {

        ret.results[i].is_scalar = 1;
        ocaml_type = (scalar_type)value_type_of(h);
        ret.results[i].data.scalar.ret_type =
            get_scalar_element_type(ocaml_type);

        // WARNING:
        // Tiny Memory Leak Ahead
        // -----------------------
        // When scalar data is returned to the host language
        // on the heap, it should be manually deleted by the
        // host frontend

        if (type_is_bool(ocaml_type)) {
          ret.results[i].data.scalar.ret_scalar_value.boolean = get_bool(h);
        } else if (type_is_int32(ocaml_type)) {
          ret.results[i].data.scalar.ret_scalar_value.int32 = get_int32(h);
        } else if (type_is_int64(ocaml_type)) {
          ret.results[i].data.scalar.ret_scalar_value.int64 = get_int64(h);
        } else if (type_is_float32(ocaml_type)) { 
          ret.results[i].data.scalar.ret_scalar_value.float32 = get_float64(h);
        } else if (type_is_float64(ocaml_type)) {
          ret.results[i].data.scalar.ret_scalar_value.float64 = get_float64(h);
        } else {
          caml_failwith("Unable to return scalar of this type\n");
        }
      } else {
        // Pass the type
        ret.results[i].is_scalar = 0;
        ret.results[i].data.array.ret_type = array_type_of(h);

        // Pass the data
        ret.results[i].data.array.data = get_array_data(h);

        // Build the shape array
        ocaml_shape = value_get_shape(h);
        int shape_len = Wosize_val(ocaml_shape);

        ret.results[i].data.array.shape =
            (int*)malloc(shape_len * sizeof(int));
        ret.results[i].data.array.shape_len = shape_len;
        for (j = 0; j < shape_len; ++j) {
          ret.results[i].data.array.shape[j] = Int_val(Field(ocaml_shape, j));
        }

        // Build the strides array
        ocaml_strides = value_get_strides(h);
        int strides_len = Wosize_val(ocaml_strides);

        ret.results[i].data.array.strides_len = strides_len;
        ret.results[i].data.array.strides =
            (int*)malloc(strides_len * sizeof(int));
        for (j = 0; j < strides_len; ++j) {
          ret.results[i].data.array.strides[j] =
              Int_val(Field(ocaml_strides, j));
        }
      }
    }
  }
  CAMLreturnT(return_val_t, ret);
	
}
Exemple #3
0
static int
decode_data(double **data, const xmlChar * input, dataFormat data_format,
            codingTypes coding, byteOrder byte_order, int max_input_len)
{
    GArray *data_stream, *debase64_buf, *decoded_data;
    char *p, *end_ptr;
    unsigned int i;
    double val;
    int data_count = 0;

    gwy_debug("start.");

    if (input == NULL) {
        g_warning("SPML: decode_data(): NULL input");
        *data = NULL;
        return 0;
    }
    switch (coding) {
        case ZLIB_COMPR_BASE64:
            /*/ XXX: strlen() may not be nice there */
            if (decode_b64((char *)input, &debase64_buf, strlen(input)) != 0) {
                if (debase64_buf != NULL) {
                    g_array_free(debase64_buf, TRUE);
                }
                g_warning("Cannot decode data in BASE64 code.");
                *data = NULL;
                return 0;
            }
            if (inflate_dynamic_array(debase64_buf, &data_stream) != 0) {
                g_warning("Cannot inflate compressed data.");
                g_array_free(debase64_buf, TRUE);
                if (data_stream != NULL) {
                    g_array_free(data_stream, TRUE);
                }
                *data = NULL;
                return 0;
            }
            g_array_free(debase64_buf, TRUE);
            break;
        case BASE64:
            /*/ XXX: strlen() may not be nice there */
            if (decode_b64((char *)input, &data_stream, strlen(input)) != 0) {
                g_warning("Cannot decode data in BASE64 code.");
                if (data_stream != NULL) {
                    g_array_free(data_stream, TRUE);
                }
                *data = NULL;
                return 0;
            }
            break;
        case ASCII:
            p = (char *)input;
            data_stream = g_array_new(FALSE, FALSE, sizeof(double));
            while (p != NULL) {
                double num;

                if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t') {
                    p++;
                    continue;
                }
                num = g_ascii_strtod(p, &end_ptr);
                if (num == 0 && end_ptr == p) {
                    g_warning("SPML: decode_data(): No conversion performed "
                              "from ASCII string.");
                    break;
                }
                g_array_append_val(data_stream, num);
                p = end_ptr;
                data_count++;
            }

            break;
            /*/ TODO: */
        case HEX:
        case BINARY:
            g_warning("SPML: decode_data(): Data coding 'HEX' and 'BINARY' "
                      "not supported.");
            break;
        case UNKNOWN_CODING:
            break;
    }
    if (coding == ASCII) {
        /* we have already decoded data */
        if (max_input_len != -1 && data_count != max_input_len) {
            /* not enough input data to fill array defined by length
             * max_input_len */
            g_warning("SPML: decode_data():\n"
                      "Input has not the same length as declared in "
                        "dimensions\n"
                      "(max:%d vs read:%d). Has the channel attribute\n"
                      "'channelReadMethodName'? The channel may be  one\n"
                      "dimensional data used for axis values but not as\n"
                      "a source of data for Gwyddion.",
                      max_input_len, data_count);
            g_array_free(data_stream, TRUE);
            *data = NULL;
            return 0;
        }
        else {
            *data = (double *)data_stream->data;
            /* we can free dynamic array, but not */
            g_array_free(data_stream, FALSE);
            /* containing data. */
            gwy_debug("Datacount: %d", data_count);
            return data_count;
        }
    }
    decoded_data = g_array_new(FALSE, FALSE, sizeof(double));
    p = data_stream->data;
    i = 0;
    switch (data_format) {
        case FLOAT32:
            while (i < data_stream->len) {
                val = get_float32(&p, byte_order);
                g_array_append_val(decoded_data, val);
                data_count++;
                i += sizeof(float);
            }
            break;
        case FLOAT64:
            while (i < data_stream->len) {
                val = get_float64(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(double);
            }
            break;
        case INT8:
            while (i < data_stream->len) {
                val = get_int8(&p);
                g_array_append_val(decoded_data, val);
                i += sizeof(gint8);
            }
            break;
        case INT16:
            while (i < data_stream->len) {
                val = get_int16(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(gint16);
            }
            break;
        case INT32:
            while (i < data_stream->len) {
                val = get_int32(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(gint32);
            }
            break;
        case UINT32:
            while (i < data_stream->len) {
                val = get_uint32(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(guint32);
            }
            break;
        case UINT8:
            while (i < data_stream->len) {
                val = get_uint8(&p);
                g_array_append_val(decoded_data, val);
                i += sizeof(guint8);
            }
            break;
        case UINT16:
            while (i < data_stream->len) {
                val = get_uint16(&p, byte_order);
                g_array_append_val(decoded_data, val);
                i += sizeof(guint16);
            }
            break;
        case STRING:
            g_warning
                ("SPML: decode_data(): Data format 'String' not supported.");
            break;
        case UNKNOWN_DATAFORMAT:
            g_warning("SPML: decode_data(): Unknown dataformat.");
            break;
    }
    g_array_free(data_stream, TRUE);
    data_count = decoded_data->len;
    if (max_input_len != -1 && data_count != max_input_len) {
        g_warning("SPML: decode_data():\n"
                  "Input has not the same length as declared in dimensions\n"
                  "(max:%d vs read:%d). Has the channel attribute\n"
                  "'channelReadMethodName'? The channel may be  one\n"
                  "dimensional data used for axis values but not as\n"
                  "a source of data for Gwyddion.", max_input_len, data_count);
        g_array_free(decoded_data, TRUE);
        *data = NULL;
        return 0;
    }
    *data = (double *)decoded_data->data;
    g_array_free(decoded_data, FALSE);  /* we can free dynamic array, but not */
    /* containing data. */
    gwy_debug("Datacount: %d", data_count);
    return data_count;

}