while'd version of u8vector-append replaced back with tail recursion version
[mot-flash.git] / iface_type.c
blob9e6c19e8e6d9101d30a708613e1eb904884ebd9a
1 #include <libguile.h>
2 #include <stdio.h>
3 #include <memory.h>
5 #include "iface_type.h"
7 scm_t_bits flash_iface_tag;
9 static SCM flash_iface_mark(SCM flash_iface_smob)
11 // struct flash_iface *iface = (struct flash_iface*)SCM_SMOB_DATA(flash_iface_snob);
12 struct flash_iface *iface = EXTRACT_IFACE(flash_iface_smob);
15 * stub
18 return SCM_BOOL_F;
21 static size_t flash_iface_free(SCM flash_iface_smob)
23 struct flash_iface *iface = EXTRACT_IFACE(flash_iface_smob);
25 scm_gc_free(iface, sizeof(struct flash_iface), "flash-iface");
27 return 0;
30 static int flash_iface_print(SCM flash_iface_smob, SCM port, scm_print_state *pstate)
32 struct flash_iface *iface = EXTRACT_IFACE(flash_iface_smob);
34 return 1;
37 static SCM close_flash_iface(SCM flash_iface_smob)
39 struct flash_iface *iface;
41 scm_assert_smob_type(flash_iface_tag, flash_iface_smob);
43 iface = EXTRACT_IFACE(flash_iface_smob);
44 if (iface->iface_close != NULL)
45 iface->iface_close(iface->handle);
47 iface->handle = NULL;
48 return SCM_BOOL_T;
51 static scm_t_uint8 *u8vector_to_array(SCM vec, size_t *len)
53 const scm_t_uint8 *raw_vec;
54 scm_t_uint8 *raw_copy;
55 size_t i;
56 ssize_t inc;
57 scm_t_array_handle vec_handle;
59 raw_vec = scm_u8vector_elements(vec, &vec_handle, len, &inc);
60 raw_copy = scm_malloc(sizeof(*raw_vec)*(*len));
62 for (i = 0; i < *len; ++i, raw_vec += inc)
64 raw_copy[i] = *raw_vec;
66 scm_array_handle_release(&vec_handle);
67 return raw_copy;
70 static SCM array_to_u8vector(scm_t_uint8 *arr, size_t len) // copies arr
72 scm_t_uint8 *new_block;
73 size_t block_size = sizeof(*new_block)*len;
75 new_block = scm_malloc(block_size);
76 memcpy(new_block, arr, block_size);
78 return scm_take_u8vector(new_block, len);
81 static SCM throw_io_error(const char *message)
83 SCM sstr_error;
84 sstr_error = scm_from_locale_string(message ? message : "Unknown error");
85 return scm_throw(scm_from_locale_symbol("io-error"), scm_cons(sstr_error, SCM_EOL));
88 static SCM write_flash_iface(SCM flash_iface_smob, SCM vdata)
90 struct flash_iface *iface;
91 size_t data_len;
92 int ret;
93 const char *str_error;
94 scm_t_uint8 *raw_data;
96 scm_assert_smob_type(flash_iface_tag, flash_iface_smob);
97 SCM_ASSERT(scm_is_true(scm_u8vector_p(vdata)), vdata, SCM_ARG2, "write-flash-iface");
99 iface = EXTRACT_IFACE(flash_iface_smob);
101 raw_data = u8vector_to_array(vdata, &data_len);
102 str_error = NULL;
103 ret = iface->iface_write(iface->handle, (uint8_t*)raw_data, (int)data_len, &str_error);
104 free(raw_data);
106 if (ret < 0)
107 return throw_io_error(str_error);
108 else
109 return scm_from_int(ret);
112 static SCM read_flash_iface(SCM flash_iface_smob)
114 #define BUFSIZE 8192 // assume that it is enough, will rewrite later
115 struct flash_iface *iface;
116 int ret;
117 const char *str_error;
118 SCM vec;
119 scm_t_uint8 *buf;
121 scm_assert_smob_type(flash_iface_tag, flash_iface_smob);
123 iface = EXTRACT_IFACE(flash_iface_smob);
125 buf = scm_malloc(sizeof(*buf)*BUFSIZE);
126 ret = iface->iface_read(iface->handle, buf, (int)BUFSIZE, &str_error);
128 if (ret < 0) {
129 free(buf);
130 return throw_io_error(str_error);
132 vec = array_to_u8vector(buf, ret); // XXX: assuming that (size == len) is not is not good idea, hm
133 free(buf);
134 return vec;
137 void init_flash_iface_type(void)
139 flash_iface_tag = scm_make_smob_type("flash-iface", sizeof(struct flash_iface));
140 scm_set_smob_mark(flash_iface_tag, flash_iface_mark);
141 scm_set_smob_free(flash_iface_tag, flash_iface_free);
142 #if 0
143 scm_set_smob_print(flash_iface_tag, flash_iface_print);
144 #endif
145 scm_c_define_gsubr("close-flash-iface", 1, 0, 0, &close_flash_iface);
146 scm_c_define_gsubr("write-flash-iface", 2, 0, 0, &write_flash_iface);
147 scm_c_define_gsubr("read-flash-iface", 1, 0, 0, &read_flash_iface);