Thread: [q-lang-cvs] q/modules/clib clib.c,1.83,1.84 clib.q,1.34,1.35
Brought to you by:
agraef
From: Albert G. <ag...@us...> - 2008-01-22 12:00:52
|
Update of /cvsroot/q-lang/q/modules/clib In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv22789 Modified Files: clib.c clib.q Log Message: add support for reading and writing slices of byte strings Index: clib.q =================================================================== RCS file: /cvsroot/q-lang/q/modules/clib/clib.q,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** clib.q 18 Jan 2008 11:20:42 -0000 1.34 --- clib.q 22 Jan 2008 12:00:46 -0000 1.35 *************** *** 260,267 **** you to treat byte strings as mutable C vectors of signed/unsigned 8/16/32 bit integers or single/double precision floating point numbers. The ! following functions provide read/write access to the elements of such C ! vectors. Note that the given index argument I is interpreted relative to ! the corresponding element type. Thus, e.g., get_int32 B I returns the Ith ! 32 bit integer rather than the integer at byte offset I. */ /* NOTE: Integer arguments must fit into machine integers, otherwise these --- 260,276 ---- you to treat byte strings as mutable C vectors of signed/unsigned 8/16/32 bit integers or single/double precision floating point numbers. The ! following functions provide read/write access to elements and slices of ! such C vectors. Note that the given index argument I is interpreted ! relative to the corresponding element type. Thus, e.g., get_int32 B I ! returns the Ith 32 bit integer rather than the integer at byte offset I. ! ! For the get_xxx functions, the index parameter may also be a pair (I,J) to ! return a slice of the given byte string instead of a single element ! (similar to sub/bsub, but interpreting indices relative to the element ! type). The put_xxx functions also accept a byte string instead of an ! element as input, and will then overwrite the corresponding slice of the ! target byte string with the given source. Similar to sub/bsub, these ! variations of get_xxx/put_xxx are "safe" in that they automatically adjust ! the given indices to fit within the bounds of the target byte string. */ /* NOTE: Integer arguments must fit into machine integers, otherwise these Index: clib.c =================================================================== RCS file: /cvsroot/q-lang/q/modules/clib/clib.c,v retrieving revision 1.83 retrieving revision 1.84 diff -C2 -d -r1.83 -r1.84 *** clib.c 18 Jan 2008 10:06:04 -0000 1.83 --- clib.c 22 Jan 2008 12:00:46 -0000 1.84 *************** *** 4040,4051 **** } FUNCTION(clib,get_int8,argc,argv) { bstr_t *m; ! long i; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && i >= 0 && i < m->size) ! return mkint((signed char)m->v[i]); ! else return __FAIL; } --- 4040,4092 ---- } + static inline long get_clamp(long *i, long *j, long m) + { + if (*i < 0) *i = 0; + if (*j < *i) *j = *i-1; + if (*j >= m) { + *j = m-1; + if (*i > *j) *i = *j+1; + } + return *j-*i+1; + } + + static inline long put_clamp(long *i, long *j, long k, long m) + { + long l = k; + if (k < 0) l = k = 0; + if (*i < 0) { k += *i; *j -= *i; *i = 0; } + if (*i > m) *i = m; + if (k > m-*i) k = m-*i; + if (k < 0) k = 0; + if (*j < 0) *j = 0; + if (*j > l) *j = l; + return k; + } + FUNCTION(clib,get_int8,argc,argv) { bstr_t *m; ! expr *xv; ! int n; ! long i, j; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m)) { ! signed char *u = m->v; ! if (isint(argv[1], &i) && i >= 0 && i < m->size) ! return mkint(u[i]); ! else if (istuple(argv[1], &n, &xv) && n==2 && ! isint(xv[0], &i) && isint(xv[1], &j)) { ! long k = get_clamp(&i, &j, m->size); ! if (k > INT_MAX) ! return __ERROR; ! else if (k > 0) { ! signed char *v = (signed char*)malloc(k); ! if (!v) return __ERROR; ! memcpy(v, u+i, k); ! return mkbstr(k, v); ! } else ! return mkbstr(0, NULL); ! } else ! return __FAIL; ! } else return __FAIL; } *************** *** 4053,4062 **** FUNCTION(clib,put_int8,argc,argv) { ! bstr_t *m; long i, x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && isint(argv[2], &x) && i >= 0 && i < m->size) { ! m->v[i] = (signed char)x; ! return mkvoid; } else return __FAIL; --- 4094,4112 ---- FUNCTION(clib,put_int8,argc,argv) { ! bstr_t *m, *m1; long i, x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i)) { ! signed char *u = m->v; ! if (isint(argv[2], &x) && i >= 0 && i < m->size) { ! u[i] = (signed char)x; ! return mkvoid; ! } else if (isobj(argv[2], type(ByteStr), (void**)&m1)) { ! signed char *v = m1->v; ! long j = 0, k = put_clamp(&i, &j, m1->size, m->size); ! if (k > 0) memcpy(u+i, v+j, k); ! return mkvoid; ! } else ! return __FAIL; } else return __FAIL; *************** *** 4066,4074 **** { bstr_t *m; ! long i; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && i >= 0 && i < (m->size >> 1)) { ! short *v = (short*)m->v; ! return mkint(v[i]); } else return __FAIL; --- 4116,4141 ---- { bstr_t *m; ! expr *xv; ! int n; ! long i, j; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m)) { ! long N = m->size/sizeof(short); ! short *u = (short*)m->v; ! if (isint(argv[1], &i) && i >= 0 && i < N) ! return mkint(u[i]); ! else if (istuple(argv[1], &n, &xv) && n==2 && ! isint(xv[0], &i) && isint(xv[1], &j)) { ! long k = get_clamp(&i, &j, N); ! if (k > INT_MAX) ! return __ERROR; ! else if (k > 0) { ! short *v = (short*)malloc(k*sizeof(short)); ! if (!v) return __ERROR; ! memcpy(v, u+i, k*sizeof(short)); ! return mkbstr(k*sizeof(short), v); ! } else ! return mkbstr(0, NULL); ! } else ! return __FAIL; } else return __FAIL; *************** *** 4077,4088 **** FUNCTION(clib,put_int16,argc,argv) { ! bstr_t *m; long i, x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && isint(argv[2], &x) && ! i >= 0 && i < (m->size >> 1)) { ! short *v = (short*)m->v; ! v[i] = (short)x; ! return mkvoid; } else return __FAIL; --- 4144,4164 ---- FUNCTION(clib,put_int16,argc,argv) { ! bstr_t *m, *m1; long i, x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i)) { ! long N = m->size/sizeof(short); ! short *u = (short*)m->v; ! if (isint(argv[2], &x) && i >= 0 && i < N) { ! u[i] = (short)x; ! return mkvoid; ! } else if (isobj(argv[2], type(ByteStr), (void**)&m1)) { ! long M = m1->size/sizeof(short); ! short *v = (short*)m1->v; ! long j = 0, k = put_clamp(&i, &j, M, N); ! if (k > 0) memcpy(u+i, v+j, k*sizeof(short)); ! return mkvoid; ! } else ! return __FAIL; } else return __FAIL; *************** *** 4092,4100 **** { bstr_t *m; ! long i; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && i >= 0 && i < (m->size >> 2)) { ! long *v = (long*)m->v; ! return mkint(v[i]); } else return __FAIL; --- 4168,4193 ---- { bstr_t *m; ! expr *xv; ! int n; ! long i, j; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m)) { ! long N = m->size/sizeof(long); ! long *u = (long*)m->v; ! if (isint(argv[1], &i) && i >= 0 && i < N) ! return mkint(u[i]); ! else if (istuple(argv[1], &n, &xv) && n==2 && ! isint(xv[0], &i) && isint(xv[1], &j)) { ! long k = get_clamp(&i, &j, N); ! if (k > INT_MAX) ! return __ERROR; ! else if (k > 0) { ! long *v = (long*)malloc(k*sizeof(long)); ! if (!v) return __ERROR; ! memcpy(v, u+i, k*sizeof(long)); ! return mkbstr(k*sizeof(long), v); ! } else ! return mkbstr(0, NULL); ! } else ! return __FAIL; } else return __FAIL; *************** *** 4103,4114 **** FUNCTION(clib,put_int32,argc,argv) { ! bstr_t *m; long i, x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && isint(argv[2], &x) && ! i >= 0 && i < (m->size >> 2)) { ! long *v = (long*)m->v; ! v[i] = (long)x; ! return mkvoid; } else return __FAIL; --- 4196,4216 ---- FUNCTION(clib,put_int32,argc,argv) { ! bstr_t *m, *m1; long i, x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i)) { ! long N = m->size/sizeof(long); ! long *u = (long*)m->v; ! if (isint(argv[2], &x) && i >= 0 && i < N) { ! u[i] = (long)x; ! return mkvoid; ! } else if (isobj(argv[2], type(ByteStr), (void**)&m1)) { ! long M = m1->size/sizeof(long); ! long *v = (long*)m1->v; ! long j = 0, k = put_clamp(&i, &j, M, N); ! if (k > 0) memcpy(u+i, v+j, k*sizeof(long)); ! return mkvoid; ! } else ! return __FAIL; } else return __FAIL; *************** *** 4118,4126 **** { bstr_t *m; ! long i; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && i >= 0 && i < m->size) ! return mkuint((unsigned char)m->v[i]); ! else return __FAIL; } --- 4220,4245 ---- { bstr_t *m; ! expr *xv; ! int n; ! long i, j; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m)) { ! unsigned char *u = m->v; ! if (isint(argv[1], &i) && i >= 0 && i < m->size) ! return mkuint(u[i]); ! else if (istuple(argv[1], &n, &xv) && n==2 && ! isint(xv[0], &i) && isint(xv[1], &j)) { ! long k = get_clamp(&i, &j, m->size); ! if (k > INT_MAX) ! return __ERROR; ! else if (k > 0) { ! unsigned char *v = (unsigned char*)malloc(k); ! if (!v) return __ERROR; ! memcpy(v, u+i, k); ! return mkbstr(k, v); ! } else ! return mkbstr(0, NULL); ! } else ! return __FAIL; ! } else return __FAIL; } *************** *** 4128,4138 **** FUNCTION(clib,put_uint8,argc,argv) { ! bstr_t *m; long i; unsigned long x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && isuint(argv[2], &x) && i >= 0 && i < m->size) { ! m->v[i] = (unsigned char)x; ! return mkvoid; } else return __FAIL; --- 4247,4266 ---- FUNCTION(clib,put_uint8,argc,argv) { ! bstr_t *m, *m1; long i; unsigned long x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i)) { ! unsigned char *u = m->v; ! if (isuint(argv[2], &x) && i >= 0 && i < m->size) { ! u[i] = (unsigned char)x; ! return mkvoid; ! } else if (isobj(argv[2], type(ByteStr), (void**)&m1)) { ! unsigned char *v = m1->v; ! long j = 0, k = put_clamp(&i, &j, m1->size, m->size); ! if (k > 0) memcpy(u+i, v+j, k); ! return mkvoid; ! } else ! return __FAIL; } else return __FAIL; *************** *** 4142,4150 **** { bstr_t *m; ! long i; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && i >= 0 && i < (m->size >> 1)) { ! unsigned short *v = (unsigned short*)m->v; ! return mkuint(v[i]); } else return __FAIL; --- 4270,4295 ---- { bstr_t *m; ! expr *xv; ! int n; ! long i, j; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m)) { ! long N = m->size/sizeof(unsigned short); ! unsigned short *u = (unsigned short*)m->v; ! if (isint(argv[1], &i) && i >= 0 && i < N) ! return mkuint(u[i]); ! else if (istuple(argv[1], &n, &xv) && n==2 && ! isint(xv[0], &i) && isint(xv[1], &j)) { ! long k = get_clamp(&i, &j, N); ! if (k > INT_MAX) ! return __ERROR; ! else if (k > 0) { ! unsigned short *v = (unsigned short*)malloc(k*sizeof(unsigned short)); ! if (!v) return __ERROR; ! memcpy(v, u+i, k*sizeof(unsigned short)); ! return mkbstr(k*sizeof(unsigned short), v); ! } else ! return mkbstr(0, NULL); ! } else ! return __FAIL; } else return __FAIL; *************** *** 4153,4165 **** FUNCTION(clib,put_uint16,argc,argv) { ! bstr_t *m; long i; unsigned long x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && isuint(argv[2], &x) && ! i >= 0 && i < (m->size >> 1)) { ! short *v = (short*)m->v; ! v[i] = (short)x; ! return mkvoid; } else return __FAIL; --- 4298,4319 ---- FUNCTION(clib,put_uint16,argc,argv) { ! bstr_t *m, *m1; long i; unsigned long x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i)) { ! long N = m->size/sizeof(unsigned short); ! unsigned short *u = (unsigned short*)m->v; ! if (isuint(argv[2], &x) && i >= 0 && i < N) { ! u[i] = (unsigned short)x; ! return mkvoid; ! } else if (isobj(argv[2], type(ByteStr), (void**)&m1)) { ! long M = m1->size/sizeof(unsigned short); ! unsigned short *v = (unsigned short*)m1->v; ! long j = 0, k = put_clamp(&i, &j, M, N); ! if (k > 0) memcpy(u+i, v+j, k*sizeof(unsigned short)); ! return mkvoid; ! } else ! return __FAIL; } else return __FAIL; *************** *** 4169,4177 **** { bstr_t *m; ! long i; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && i >= 0 && i < (m->size >> 2)) { ! unsigned long *v = (unsigned long*)m->v; ! return mkuint(v[i]); } else return __FAIL; --- 4323,4348 ---- { bstr_t *m; ! expr *xv; ! int n; ! long i, j; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m)) { ! long N = m->size/sizeof(unsigned long); ! unsigned long *u = (unsigned long*)m->v; ! if (isint(argv[1], &i) && i >= 0 && i < N) ! return mkuint(u[i]); ! else if (istuple(argv[1], &n, &xv) && n==2 && ! isint(xv[0], &i) && isint(xv[1], &j)) { ! long k = get_clamp(&i, &j, N); ! if (k > INT_MAX) ! return __ERROR; ! else if (k > 0) { ! unsigned long *v = (unsigned long*)malloc(k*sizeof(unsigned long)); ! if (!v) return __ERROR; ! memcpy(v, u+i, k*sizeof(unsigned long)); ! return mkbstr(k*sizeof(unsigned long), v); ! } else ! return mkbstr(0, NULL); ! } else ! return __FAIL; } else return __FAIL; *************** *** 4180,4192 **** FUNCTION(clib,put_uint32,argc,argv) { ! bstr_t *m; long i; unsigned long x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && isuint(argv[2], &x) && ! i >= 0 && i < (m->size >> 2)) { ! unsigned long *v = (unsigned long*)m->v; ! v[i] = (unsigned long)x; ! return mkvoid; } else return __FAIL; --- 4351,4372 ---- FUNCTION(clib,put_uint32,argc,argv) { ! bstr_t *m, *m1; long i; unsigned long x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i)) { ! long N = m->size/sizeof(unsigned long); ! unsigned long *u = (unsigned long*)m->v; ! if (isuint(argv[2], &x) && i >= 0 && i < N) { ! u[i] = (unsigned long)x; ! return mkvoid; ! } else if (isobj(argv[2], type(ByteStr), (void**)&m1)) { ! long M = m1->size/sizeof(unsigned long); ! unsigned long *v = (unsigned long*)m1->v; ! long j = 0, k = put_clamp(&i, &j, M, N); ! if (k > 0) memcpy(u+i, v+j, k*sizeof(unsigned long)); ! return mkvoid; ! } else ! return __FAIL; } else return __FAIL; *************** *** 4196,4204 **** { bstr_t *m; ! long i; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && i >= 0 && i < (m->size / sizeof(float))) { ! float *v = (float*)m->v; ! return mkfloat(v[i]); } else return __FAIL; --- 4376,4401 ---- { bstr_t *m; ! expr *xv; ! int n; ! long i, j; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m)) { ! long N = m->size/sizeof(float); ! float *u = (float*)m->v; ! if (isint(argv[1], &i) && i >= 0 && i < N) ! return mkfloat(u[i]); ! else if (istuple(argv[1], &n, &xv) && n==2 && ! isint(xv[0], &i) && isint(xv[1], &j)) { ! long k = get_clamp(&i, &j, N); ! if (k > INT_MAX) ! return __ERROR; ! else if (k > 0) { ! float *v = (float*)malloc(k*sizeof(float)); ! if (!v) return __ERROR; ! memcpy(v, u+i, k*sizeof(float)); ! return mkbstr(k*sizeof(float), v); ! } else ! return mkbstr(0, NULL); ! } else ! return __FAIL; } else return __FAIL; *************** *** 4207,4220 **** FUNCTION(clib,put_float,argc,argv) { ! bstr_t *m; long i; double x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && ! (isfloat(argv[2], &x) || ismpz_float(argv[2], &x)) && ! i >= 0 && i < (m->size / sizeof(float))) { ! float *v = (float*)m->v; ! v[i] = (float)x; ! return mkvoid; } else return __FAIL; --- 4404,4426 ---- FUNCTION(clib,put_float,argc,argv) { ! bstr_t *m, *m1; long i; double x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i)) { ! long N = m->size/sizeof(float); ! float *u = (float*)m->v; ! if ((isfloat(argv[2], &x) || ismpz_float(argv[2], &x)) && ! i >= 0 && i < N) { ! u[i] = (float)x; ! return mkvoid; ! } else if (isobj(argv[2], type(ByteStr), (void**)&m1)) { ! long M = m1->size/sizeof(float); ! float *v = (float*)m1->v; ! long j = 0, k = put_clamp(&i, &j, M, N); ! if (k > 0) memcpy(u+i, v+j, k*sizeof(float)); ! return mkvoid; ! } else ! return __FAIL; } else return __FAIL; *************** *** 4224,4232 **** { bstr_t *m; ! long i; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && i >= 0 && i < (m->size / sizeof(double))) { ! double *v = (double*)m->v; ! return mkfloat(v[i]); } else return __FAIL; --- 4430,4455 ---- { bstr_t *m; ! expr *xv; ! int n; ! long i, j; ! if (argc == 2 && isobj(argv[0], type(ByteStr), (void**)&m)) { ! long N = m->size/sizeof(double); ! double *u = (double*)m->v; ! if (isint(argv[1], &i) && i >= 0 && i < N) ! return mkfloat(u[i]); ! else if (istuple(argv[1], &n, &xv) && n==2 && ! isint(xv[0], &i) && isint(xv[1], &j)) { ! long k = get_clamp(&i, &j, N); ! if (k > INT_MAX) ! return __ERROR; ! else if (k > 0) { ! double *v = (double*)malloc(k*sizeof(double)); ! if (!v) return __ERROR; ! memcpy(v, u+i, k*sizeof(double)); ! return mkbstr(k*sizeof(double), v); ! } else ! return mkbstr(0, NULL); ! } else ! return __FAIL; } else return __FAIL; *************** *** 4235,4248 **** FUNCTION(clib,put_double,argc,argv) { ! bstr_t *m; long i; double x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i) && ! (isfloat(argv[2], &x) || ismpz_float(argv[2], &x)) && ! i >= 0 && i < (m->size / sizeof(double))) { ! double *v = (double*)m->v; ! v[i] = x; ! return mkvoid; } else return __FAIL; --- 4458,4480 ---- FUNCTION(clib,put_double,argc,argv) { ! bstr_t *m, *m1; long i; double x; if (argc == 3 && isobj(argv[0], type(ByteStr), (void**)&m) && ! isint(argv[1], &i)) { ! long N = m->size/sizeof(double); ! double *u = (double*)m->v; ! if ((isfloat(argv[2], &x) || ismpz_float(argv[2], &x)) && ! i >= 0 && i < N) { ! u[i] = (double)x; ! return mkvoid; ! } else if (isobj(argv[2], type(ByteStr), (void**)&m1)) { ! long M = m1->size/sizeof(double); ! double *v = (double*)m1->v; ! long j = 0, k = put_clamp(&i, &j, M, N); ! if (k > 0) memcpy(u+i, v+j, k*sizeof(double)); ! return mkvoid; ! } else ! return __FAIL; } else return __FAIL; |