Matrix r4655
Loading...
Searching...
No Matches
utils.c
Go to the documentation of this file.
1#include <stdio.h> /* vsnprintf */
2#include "Mdefines.h"
3#include "utils.h"
4
5/* memset() but passing length and size rather than their product
6 which can overflow size_t ... hence _safer_ than Memzero()
7*/
8void *Matrix_memset(void *dest, int ch, R_xlen_t length, size_t size)
9{
10 if (dest && length > 0 && size > 0) {
11
12 char *dest_ = (char *) dest;
13 size_t N = SIZE_MAX / size;
14
15#if (SIZE_MAX < R_XLEN_T_MAX)
16 R_xlen_t S_M = (R_xlen_t) SIZE_MAX;
17 if (length <= S_M) {
18#endif
19
20 /* 'length' is representable as size_t : */
21
22 size_t n = (size_t) length;
23 if (n <= N)
24 memset(dest_, ch, n * size);
25 else {
26 size_t d = N * size;
27 while (n > N) {
28 memset(dest_, ch, d);
29 dest_ += d;
30 n -= d;
31 }
32 memset(dest_, ch, n * size);
33 }
34
35#if (SIZE_MAX < R_XLEN_T_MAX)
36 } else {
37
38 /* 'length' would overflow size_t : */
39
40 size_t n, d = N * size;
41 while (length > S_M) {
42 n = SIZE_MAX;
43 while (n > N) {
44 memset(dest_, ch, d);
45 dest_ += d;
46 n -= d;
47 }
48 memset(dest_, ch, n * size);
49 length -= S_M;
50 }
51 n = (size_t) length;
52 while (n > N) {
53 memset(dest_, ch, d);
54 dest_ += d;
55 n -= d;
56 }
57 memset(dest_, ch, n * size);
58
59 }
60#endif
61
62 }
63
64 return dest;
65}
66
67/* memcpy() but passing length and size rather than their product
68 which can overflow size_t ... hence _safer_ than Memcpy()
69*/
70void *Matrix_memcpy(void *dest, const void *src, R_xlen_t length, size_t size)
71{
72 if (dest && src && length > 0 && size > 0) {
73
74 char *dest_ = (char *) dest;
75 const char *src_ = (const char *) src;
76
77 size_t N = SIZE_MAX / size;
78
79#if (SIZE_MAX < R_XLEN_T_MAX)
80 R_xlen_t S_M = (R_xlen_t) SIZE_MAX;
81 if (length <= S_M) {
82#endif
83
84 /* 'length' is representable as size_t : */
85
86 size_t n = (size_t) length;
87 if (n <= N)
88 memcpy(dest_, src_, n * size);
89 else {
90 size_t d = N * size;
91 while (n > N) {
92 memcpy(dest_, src_, d);
93 dest_ += d;
94 src_ += d;
95 n -= d;
96 }
97 memcpy(dest_, src_, n * size);
98 }
99
100#if (SIZE_MAX < R_XLEN_T_MAX)
101 } else {
102
103 /* 'length' would overflow size_t : */
104
105 size_t n, d = N * size;
106 while (length > S_M) {
107 n = SIZE_MAX;
108 while (n > N) {
109 memcpy(dest_, src_, d);
110 dest_ += d;
111 src_ += d;
112 n -= d;
113 }
114 memcpy(dest_, src_, n * size);
115 length -= S_M;
116 }
117 n = (size_t) length;
118 while (n > N) {
119 memcpy(dest_, src_, d);
120 dest_ += d;
121 n -= d;
122 }
123 memcpy(dest_, src_, n * size);
124
125 }
126#endif
127
128 }
129
130 return dest;
131}
132
133char *Matrix_sprintf(const char *format, ...)
134{
135 char *buf = R_alloc(Matrix_ErrorBufferSize, sizeof(char));
136 va_list args;
137 va_start(args, format);
138 vsnprintf(buf, Matrix_ErrorBufferSize, format, args);
139 va_end(args);
140 return buf;
141}
142
143int equal_character_vectors(SEXP s1, SEXP s2, int n)
144{
145 /* FIXME? not distinguishing between NA_STRING and "NA" */
146 for (int i = 0; i < n; ++i)
147 if (strcmp(CHAR(STRING_ELT(s1, i)), CHAR(STRING_ELT(s2, i))) != 0)
148 return 0;
149 return 1;
150}
151
152void conjugate(SEXP x)
153{
154 Rcomplex *px = COMPLEX(x);
155 R_xlen_t nx = XLENGTH(x);
156 while (nx--) {
157 (*px).i = -(*px).i;
158 ++px;
159 }
160 return;
161}
162
163void zeroRe(SEXP x)
164{
165 Rcomplex *px = COMPLEX(x);
166 R_xlen_t nx = XLENGTH(x);
167 while (nx--) {
168 (*px).r = 0.0;
169 ++px;
170 }
171 return;
172}
173
174void zeroIm(SEXP x)
175{
176 Rcomplex *px = COMPLEX(x);
177 R_xlen_t nx = XLENGTH(x);
178 while (nx--) {
179 (*px).i = 0.0;
180 ++px;
181 }
182 return;
183}
184
185void naToOne(SEXP x)
186{
187 R_xlen_t i, n = XLENGTH(x);
188 switch (TYPEOF(x)) {
189 case LGLSXP:
190 {
191 int *px = LOGICAL(x);
192 for (i = 0; i < n; ++i, ++px)
193 if (*px == NA_LOGICAL)
194 *px = 1;
195 break;
196 }
197 case INTSXP:
198 {
199 int *px = INTEGER(x);
200 for (i = 0; i < n; ++i, ++px)
201 if (*px == NA_INTEGER)
202 *px = 1;
203 break;
204 }
205 case REALSXP:
206 {
207 double *px = REAL(x);
208 for (i = 0; i < n; ++i, ++px)
209 if (ISNAN(*px))
210 *px = 1.0;
211 break;
212 }
213 case CPLXSXP:
214 {
215 Rcomplex *px = COMPLEX(x);
216 for (i = 0; i < n; ++i, ++px)
217 if (ISNAN((*px).r) || ISNAN((*px).i))
218 *px = Matrix_zone;
219 break;
220 }
221 default:
222 ERROR_INVALID_TYPE(x, __func__);
223 break;
224 }
225 return;
226}
#define Matrix_ErrorBufferSize
Definition Mdefines.h:8
#define ERROR_INVALID_TYPE(_X_, _FUNC_)
Definition Mdefines.h:204
Rcomplex Matrix_zone
Definition init.c:26
void naToOne(SEXP x)
Definition utils.c:185
void * Matrix_memset(void *dest, int ch, R_xlen_t length, size_t size)
Definition utils.c:8
void zeroIm(SEXP x)
Definition utils.c:174
void conjugate(SEXP x)
Definition utils.c:152
int equal_character_vectors(SEXP s1, SEXP s2, int n)
Definition utils.c:143
void * Matrix_memcpy(void *dest, const void *src, R_xlen_t length, size_t size)
Definition utils.c:70
void zeroRe(SEXP x)
Definition utils.c:163
char * Matrix_sprintf(const char *format,...)
Definition utils.c:133