1 /*
2  * binary.c - Binary I/O routines
3  *
4  *   Copyright (c) 2004-2020  Shiro Kawai  <shiro@acm.org>
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *   1. Redistributions of source code must retain the above copyright
11  *      notice, this list of conditions and the following disclaimer.
12  *
13  *   2. Redistributions in binary form must reproduce the above copyright
14  *      notice, this list of conditions and the following disclaimer in the
15  *      documentation and/or other materials provided with the distribution.
16  *
17  *   3. Neither the name of the authors nor the names of its contributors
18  *      may be used to endorse or promote products derived from this
19  *      software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27  *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <gauche.h>
35 #include <gauche/extend.h>
36 #include <gauche/priv/bytesP.h>
37 #include "binary.h"
38 
39 #define ENSURE_IPORT(var)  if (!var) var = SCM_CURIN
40 #define ENSURE_OPORT(var)  if (!var) var = SCM_CUROUT
41 
42 #define SWAP_16(e, v) do { if (SWAP_REQUIRED(e)) SWAP_2(v); } while (0)
43 #define SWAP_32(e, v) do { if (SWAP_REQUIRED(e)) SWAP_4(v); } while (0)
44 #define SWAP_64(e, v) do { if (SWAP_REQUIRED(e)) SWAP_8(v); } while (0)
45 
46 #ifdef DOUBLE_ARMENDIAN
47 #define SWAP_D(e, v)                                    \
48     do {                                                \
49         if (SCM_IS_ARM_LE(Scm_NativeEndian())) {        \
50             if (SCM_IS_BE(e)) SWAP_ARM2BE(v);           \
51             else if (SCM_IS_LE(e)) SWAP_ARM2LE(v);      \
52         } else {                                        \
53             if (SCM_IS_ARM_LE(e)) SWAP_ARM2LE(v);       \
54             else if (SCM_IS_BE(e)) SWAP_8(v);           \
55         }                                               \
56     } while (0)
57 #elif WORDS_BIGENDIAN
58 #define SWAP_D(e, v)                                    \
59     do {                                                \
60         if (SCM_IS_LE(e)) SWAP_8(v);                    \
61         else if (SCM_IS_ARM_LE(e)) SWAP_ARM2BE(v);      \
62     } while (0)
63 #else /*!WORDS_BIGENDIAN*/
64 #define SWAP_D(e, v)                                    \
65     do {                                                \
66         if (SCM_IS_BE(e)) SWAP_8(v);                    \
67         else if (SCM_IS_ARM_LE(e)) SWAP_ARM2LE(v);      \
68     } while (0)
69 #endif /*!WORDS_BIGENDIAN*/
70 
71 
72 /*===========================================================
73  * Readers
74  */
75 
76 /* generic routine to handle byte-stream */
getbytes(char * buf,int len,ScmPort * iport)77 static inline int getbytes(char *buf, int len, ScmPort *iport)
78 {
79     int nread = 0;
80     ENSURE_IPORT(iport);
81     while (nread < len) {
82         int r = Scm_Getz(buf, len-nread, iport);
83         if (r <= 0) return EOF;
84         nread += r;
85         buf += r;
86     }
87     return nread;
88 }
89 
Scm_ReadBinaryU8(ScmPort * iport,ScmSymbol * endian)90 ScmObj Scm_ReadBinaryU8(ScmPort *iport, ScmSymbol *endian)
91 {
92     int b;
93     ENSURE_IPORT(iport);
94     SCM_CHECK_ENDIAN(endian);
95     if ((b = Scm_Getb(iport)) == EOF) return SCM_EOF;
96     else return SCM_MAKE_INT(b);
97 }
98 
Scm_ReadBinaryS8(ScmPort * iport,ScmSymbol * endian)99 ScmObj Scm_ReadBinaryS8(ScmPort *iport, ScmSymbol *endian)
100 {
101     int b;
102     ENSURE_IPORT(iport);
103     SCM_CHECK_ENDIAN(endian);
104     if ((b = Scm_Getb(iport)) == EOF) return SCM_EOF;
105     if (b >= 128) b -= 256;
106     return SCM_MAKE_INT(b);
107 }
108 
Scm_ReadBinaryU16(ScmPort * iport,ScmSymbol * endian)109 ScmObj Scm_ReadBinaryU16(ScmPort *iport, ScmSymbol *endian)
110 {
111     swap_u16_t v;
112     SCM_CHECK_ENDIAN(endian);
113     if (getbytes(v.buf, 2, iport) == EOF) return SCM_EOF;
114     SWAP_16(endian, v);
115     return SCM_MAKE_INT(v.val);
116 }
117 
Scm_ReadBinaryS16(ScmPort * iport,ScmSymbol * endian)118 ScmObj Scm_ReadBinaryS16(ScmPort *iport, ScmSymbol *endian)
119 {
120     swap_s16_t v;
121     SCM_CHECK_ENDIAN(endian);
122     if (getbytes(v.buf, 2, iport) == EOF) return SCM_EOF;
123     SWAP_16(endian, v);
124     return SCM_MAKE_INT(v.val);
125 }
126 
Scm_ReadBinaryU32(ScmPort * iport,ScmSymbol * endian)127 ScmObj Scm_ReadBinaryU32(ScmPort *iport, ScmSymbol *endian)
128 {
129     swap_u32_t v;
130     SCM_CHECK_ENDIAN(endian);
131     if (getbytes(v.buf, 4, iport) == EOF) return SCM_EOF;
132     SWAP_32(endian, v);
133     return Scm_MakeIntegerFromUI(v.val);
134 }
135 
Scm_ReadBinaryS32(ScmPort * iport,ScmSymbol * endian)136 ScmObj Scm_ReadBinaryS32(ScmPort *iport, ScmSymbol *endian)
137 {
138     swap_s32_t v;
139     SCM_CHECK_ENDIAN(endian);
140     if (getbytes(v.buf, 4, iport) == EOF) return SCM_EOF;
141     SWAP_32(endian, v);
142     return Scm_MakeInteger(v.val);
143 }
144 
Scm_ReadBinaryU64(ScmPort * iport,ScmSymbol * endian)145 ScmObj Scm_ReadBinaryU64(ScmPort *iport, ScmSymbol *endian)
146 {
147     swap_u64_t v;
148     SCM_CHECK_ENDIAN(endian);
149     if (getbytes(v.buf, 8, iport) == EOF) return SCM_EOF;
150     SWAP_64(endian, v);
151     return Scm_MakeIntegerU64(v.val);
152 }
153 
Scm_ReadBinaryS64(ScmPort * iport,ScmSymbol * endian)154 ScmObj Scm_ReadBinaryS64(ScmPort *iport, ScmSymbol *endian)
155 {
156     swap_s64_t v;
157     SCM_CHECK_ENDIAN(endian);
158     if (getbytes(v.buf, 8, iport) == EOF) return SCM_EOF;
159     SWAP_64(endian, v);
160     return Scm_MakeInteger64(v.val);
161 }
162 
Scm_ReadBinaryF16(ScmPort * iport,ScmSymbol * endian)163 ScmObj Scm_ReadBinaryF16(ScmPort *iport, ScmSymbol *endian)
164 {
165     swap_f16_t v;
166     SCM_CHECK_ENDIAN(endian);
167     if (getbytes(v.buf, 2, iport) == EOF) return SCM_EOF;
168     SWAP_16(endian, v);
169     return Scm_MakeFlonum(Scm_HalfToDouble(v.val));
170 }
171 
Scm_ReadBinaryF32(ScmPort * iport,ScmSymbol * endian)172 ScmObj Scm_ReadBinaryF32(ScmPort *iport, ScmSymbol *endian)
173 {
174     swap_f32_t v;
175     SCM_CHECK_ENDIAN(endian);
176     if (getbytes(v.buf, 4, iport) == EOF) return SCM_EOF;
177     SWAP_32(endian, v);
178     return Scm_MakeFlonum((double)v.val);
179 }
180 
Scm_ReadBinaryF64(ScmPort * iport,ScmSymbol * endian)181 ScmObj Scm_ReadBinaryF64(ScmPort *iport, ScmSymbol *endian)
182 {
183     swap_f64_t v;
184     SCM_CHECK_ENDIAN(endian);
185     if (getbytes(v.buf, 8, iport) == EOF) return SCM_EOF;
186     SWAP_D(endian, v);
187     return Scm_MakeFlonum(v.val);
188 }
189 
190 /*===========================================================
191  * Writers
192  */
193 
Scm_WriteBinaryU8(ScmObj sval,ScmPort * oport,ScmSymbol * endian)194 void Scm_WriteBinaryU8(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
195 {
196     int val = Scm_GetIntegerU8Clamp(sval, SCM_CLAMP_NONE, NULL);
197     SCM_CHECK_ENDIAN(endian);
198     ENSURE_OPORT(oport);
199     Scm_Putb(val, oport);
200 }
201 
Scm_WriteBinaryS8(ScmObj sval,ScmPort * oport,ScmSymbol * endian)202 void Scm_WriteBinaryS8(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
203 {
204     int val = Scm_GetInteger8Clamp(sval, SCM_CLAMP_NONE, NULL);
205     SCM_CHECK_ENDIAN(endian);
206     ENSURE_OPORT(oport);
207     Scm_Putb(val, oport);
208 }
209 
Scm_WriteBinaryU16(ScmObj sval,ScmPort * oport,ScmSymbol * endian)210 void Scm_WriteBinaryU16(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
211 {
212     swap_u16_t v;
213     ENSURE_OPORT(oport);
214     SCM_CHECK_ENDIAN(endian);
215     v.val = Scm_GetIntegerU16Clamp(sval, SCM_CLAMP_NONE, NULL);
216     SWAP_16(endian, v);
217     Scm_Putz(v.buf, 2, oport);
218 }
219 
Scm_WriteBinaryS16(ScmObj sval,ScmPort * oport,ScmSymbol * endian)220 void Scm_WriteBinaryS16(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
221 {
222     swap_s16_t v;
223     ENSURE_OPORT(oport);
224     SCM_CHECK_ENDIAN(endian);
225     v.val = Scm_GetInteger16Clamp(sval, SCM_CLAMP_NONE, NULL);
226     SWAP_16(endian, v);
227     Scm_Putz(v.buf, 2, oport);
228 }
229 
Scm_WriteBinaryU32(ScmObj sval,ScmPort * oport,ScmSymbol * endian)230 void Scm_WriteBinaryU32(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
231 {
232     swap_u32_t v;
233     ENSURE_OPORT(oport);
234     SCM_CHECK_ENDIAN(endian);
235     v.val = Scm_GetIntegerU32Clamp(sval, FALSE, FALSE);
236     SWAP_32(endian, v);
237     Scm_Putz(v.buf, 4, oport);
238 }
239 
Scm_WriteBinaryS32(ScmObj sval,ScmPort * oport,ScmSymbol * endian)240 void Scm_WriteBinaryS32(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
241 {
242     swap_s32_t v;
243     ENSURE_OPORT(oport);
244     SCM_CHECK_ENDIAN(endian);
245     v.val = Scm_GetInteger32Clamp(sval, FALSE, FALSE);
246     SWAP_32(endian, v);
247     Scm_Putz(v.buf, 4, oport);
248 }
249 
Scm_WriteBinaryU64(ScmObj sval,ScmPort * oport,ScmSymbol * endian)250 void Scm_WriteBinaryU64(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
251 {
252     swap_u64_t v;
253     ENSURE_OPORT(oport);
254     SCM_CHECK_ENDIAN(endian);
255     v.val = Scm_GetIntegerU64Clamp(sval, FALSE, FALSE);
256     SWAP_64(endian, v);
257     Scm_Putz(v.buf, 8, oport);
258 }
259 
Scm_WriteBinaryS64(ScmObj sval,ScmPort * oport,ScmSymbol * endian)260 void Scm_WriteBinaryS64(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
261 {
262     swap_s64_t v;
263     ENSURE_OPORT(oport);
264     SCM_CHECK_ENDIAN(endian);
265     v.val = Scm_GetInteger64Clamp(sval, FALSE, FALSE);
266     SWAP_64(endian, v);
267     Scm_Putz(v.buf, 8, oport);
268 }
269 
Scm_WriteBinaryF16(ScmObj sval,ScmPort * oport,ScmSymbol * endian)270 void Scm_WriteBinaryF16(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
271 {
272     swap_f16_t v;
273     ENSURE_OPORT(oport);
274     SCM_CHECK_ENDIAN(endian);
275     v.val = Scm_DoubleToHalf(Scm_GetDouble(sval));
276     SWAP_16(endian, v);
277     Scm_Putz(v.buf, 2, oport);
278 }
279 
Scm_WriteBinaryF32(ScmObj sval,ScmPort * oport,ScmSymbol * endian)280 void Scm_WriteBinaryF32(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
281 {
282     swap_f32_t v;
283     ENSURE_OPORT(oport);
284     SCM_CHECK_ENDIAN(endian);
285     v.val = (float)Scm_GetDouble(sval);
286     SWAP_32(endian, v);
287     Scm_Putz(v.buf, 4, oport);
288 }
289 
Scm_WriteBinaryF64(ScmObj sval,ScmPort * oport,ScmSymbol * endian)290 void Scm_WriteBinaryF64(ScmObj sval, ScmPort *oport, ScmSymbol *endian)
291 {
292     swap_f64_t v;
293     ENSURE_OPORT(oport);
294     SCM_CHECK_ENDIAN(endian);
295     v.val = Scm_GetDouble(sval);
296     SWAP_D(endian, v);
297     Scm_Putz(v.buf, 8, oport);
298 }
299 
300 /*===========================================================
301  * Getters
302  */
303 
extract(ScmUVector * uv,char * buf,int off,int eltsize)304 static void extract(ScmUVector *uv, char *buf, int off, int eltsize)
305 {
306     int size = Scm_UVectorSizeInBytes(uv);
307     unsigned char *b = (unsigned char*)SCM_UVECTOR_ELEMENTS(uv) + off;
308 
309     if (off < 0 || off+eltsize > size) {
310         Scm_Error("offset %d is out of bound of the uvector.", off);
311     }
312     for (int i=0; i<eltsize; i++) {
313         *buf++ = *b++;
314     }
315 }
316 
317 
Scm_GetBinaryU8(ScmUVector * uv,int off,ScmSymbol * endian)318 ScmObj Scm_GetBinaryU8(ScmUVector *uv, int off, ScmSymbol *endian)
319 {
320     unsigned char b;
321     SCM_CHECK_ENDIAN(endian);
322     extract(uv, (char *)&b, off, 1);
323     return SCM_MAKE_INT(b);
324 }
325 
Scm_GetBinaryS8(ScmUVector * uv,int off,ScmSymbol * endian)326 ScmObj Scm_GetBinaryS8(ScmUVector *uv, int off, ScmSymbol *endian)
327 {
328     unsigned char b;
329     SCM_CHECK_ENDIAN(endian);
330     extract(uv, (char *)&b, off, 1);
331     int r = b;
332     if (r >= 128) r -= 256;
333     return SCM_MAKE_INT(r);
334 }
335 
Scm_GetBinaryU16(ScmUVector * uv,int off,ScmSymbol * endian)336 ScmObj Scm_GetBinaryU16(ScmUVector *uv, int off, ScmSymbol *endian)
337 {
338     swap_u16_t v;
339     SCM_CHECK_ENDIAN(endian);
340     extract(uv, v.buf, off, 2);
341     SWAP_16(endian, v);
342     return SCM_MAKE_INT(v.val);
343 }
344 
Scm_GetBinaryS16(ScmUVector * uv,int off,ScmSymbol * endian)345 ScmObj Scm_GetBinaryS16(ScmUVector *uv, int off, ScmSymbol *endian)
346 {
347     swap_s16_t v;
348     SCM_CHECK_ENDIAN(endian);
349     extract(uv, v.buf, off, 2);
350     SWAP_16(endian, v);
351     return SCM_MAKE_INT(v.val);
352 }
353 
Scm_GetBinaryU32(ScmUVector * uv,int off,ScmSymbol * endian)354 ScmObj Scm_GetBinaryU32(ScmUVector *uv, int off, ScmSymbol *endian)
355 {
356     swap_u32_t v;
357     SCM_CHECK_ENDIAN(endian);
358     extract(uv, v.buf, off, 4);
359     SWAP_32(endian, v);
360     return Scm_MakeIntegerFromUI(v.val);
361 }
362 
Scm_GetBinaryS32(ScmUVector * uv,int off,ScmSymbol * endian)363 ScmObj Scm_GetBinaryS32(ScmUVector *uv, int off, ScmSymbol *endian)
364 {
365     swap_s32_t v;
366     SCM_CHECK_ENDIAN(endian);
367     extract(uv, v.buf, off, 4);
368     SWAP_32(endian, v);
369     return Scm_MakeInteger(v.val);
370 }
371 
Scm_GetBinaryU64(ScmUVector * uv,int off,ScmSymbol * endian)372 ScmObj Scm_GetBinaryU64(ScmUVector *uv, int off, ScmSymbol *endian)
373 {
374     swap_u64_t v;
375     SCM_CHECK_ENDIAN(endian);
376     extract(uv, v.buf, off, 8);
377     SWAP_64(endian, v);
378     return Scm_MakeIntegerU64(v.val);
379 }
380 
Scm_GetBinaryS64(ScmUVector * uv,int off,ScmSymbol * endian)381 ScmObj Scm_GetBinaryS64(ScmUVector *uv, int off, ScmSymbol *endian)
382 {
383     swap_s64_t v;
384     SCM_CHECK_ENDIAN(endian);
385     extract(uv, v.buf, off, 8);
386     SWAP_64(endian, v);
387     return Scm_MakeInteger64(v.val);
388 }
389 
Scm_GetBinaryF16(ScmUVector * uv,int off,ScmSymbol * endian)390 ScmObj Scm_GetBinaryF16(ScmUVector *uv, int off, ScmSymbol *endian)
391 {
392     swap_f16_t v;
393     SCM_CHECK_ENDIAN(endian);
394     extract(uv, v.buf, off, 2);
395     SWAP_16(endian, v);
396     return Scm_MakeFlonum(Scm_HalfToDouble(v.val));
397 }
398 
Scm_GetBinaryF32(ScmUVector * uv,int off,ScmSymbol * endian)399 ScmObj Scm_GetBinaryF32(ScmUVector *uv, int off, ScmSymbol *endian)
400 {
401     swap_f32_t v;
402     SCM_CHECK_ENDIAN(endian);
403     extract(uv, v.buf, off, 4);
404     SWAP_32(endian, v);
405     return Scm_MakeFlonum((double)v.val);
406 }
407 
Scm_GetBinaryF64(ScmUVector * uv,int off,ScmSymbol * endian)408 ScmObj Scm_GetBinaryF64(ScmUVector *uv, int off, ScmSymbol *endian)
409 {
410     swap_f64_t v;
411     SCM_CHECK_ENDIAN(endian);
412     extract(uv, v.buf, off, 8);
413     SWAP_D(endian, v);
414     return Scm_MakeFlonum(v.val);
415 }
416 
417 /*===========================================================
418  * Putters
419  */
420 
inject(ScmUVector * uv,char * buf,int off,int eltsize)421 static void inject(ScmUVector *uv, char *buf, int off, int eltsize)
422 {
423     int size = Scm_UVectorSizeInBytes(uv);
424     unsigned char *b = (unsigned char*)SCM_UVECTOR_ELEMENTS(uv) + off;
425 
426     SCM_UVECTOR_CHECK_MUTABLE(SCM_OBJ(uv));
427 
428     if (off < 0 || off+eltsize > size) {
429         Scm_Error("offset %d is out of bound of the uvector.", off);
430     }
431     for (int i=0; i<eltsize; i++) {
432         *b++ = *buf++;
433     }
434 }
435 
Scm_PutBinaryU8(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)436 void Scm_PutBinaryU8(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
437 {
438     u_char v = (u_char)Scm_GetIntegerU8Clamp(val, SCM_CLAMP_NONE, NULL);
439     SCM_CHECK_ENDIAN(e);
440     inject(uv, (char *)&v, off, 1);
441 }
442 
Scm_PutBinaryS8(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)443 void Scm_PutBinaryS8(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
444 {
445     u_char v = (u_char)Scm_GetInteger8Clamp(val, SCM_CLAMP_NONE, NULL);
446     SCM_CHECK_ENDIAN(e);
447     inject(uv, (char *)&v, off, 1);
448 }
449 
Scm_PutBinaryU16(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)450 void Scm_PutBinaryU16(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
451 {
452     swap_u16_t v;
453     SCM_CHECK_ENDIAN(e);
454     v.val = Scm_GetIntegerU16Clamp(val, SCM_CLAMP_NONE, NULL);
455     SWAP_16(e, v);
456     inject(uv, v.buf, off, 2);
457 }
458 
Scm_PutBinaryS16(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)459 void Scm_PutBinaryS16(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
460 {
461     swap_s16_t v;
462     SCM_CHECK_ENDIAN(e);
463     v.val = Scm_GetInteger16Clamp(val, SCM_CLAMP_NONE, NULL);
464     SWAP_16(e, v);
465     inject(uv, v.buf, off, 2);
466 }
467 
Scm_PutBinaryU32(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)468 void Scm_PutBinaryU32(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
469 {
470     swap_u32_t v;
471     SCM_CHECK_ENDIAN(e);
472     v.val = Scm_GetIntegerU32Clamp(val, FALSE, FALSE);
473     SWAP_32(e, v);
474     inject(uv, v.buf, off, 4);
475 }
476 
Scm_PutBinaryS32(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)477 void Scm_PutBinaryS32(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
478 {
479     swap_s32_t v;
480     SCM_CHECK_ENDIAN(e);
481     v.val = Scm_GetInteger32Clamp(val, FALSE, FALSE);
482     SWAP_32(e, v);
483     inject(uv, v.buf, off, 4);
484 }
485 
Scm_PutBinaryU64(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)486 void Scm_PutBinaryU64(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
487 {
488     swap_u64_t v;
489     SCM_CHECK_ENDIAN(e);
490     v.val = Scm_GetIntegerU64Clamp(val, FALSE, FALSE);
491     SWAP_64(e, v);
492     inject(uv, v.buf, off, 8);
493 }
494 
Scm_PutBinaryS64(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)495 void Scm_PutBinaryS64(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
496 {
497     swap_s64_t v;
498     SCM_CHECK_ENDIAN(e);
499     v.val = Scm_GetInteger64Clamp(val, FALSE, FALSE);
500     SWAP_64(e, v);
501     inject(uv, v.buf, off, 8);
502 }
503 
Scm_PutBinaryF16(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)504 void Scm_PutBinaryF16(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
505 {
506     swap_f16_t v;
507     SCM_CHECK_ENDIAN(e);
508     v.val = Scm_DoubleToHalf(Scm_GetDouble(val));
509     SWAP_16(e, v);
510     inject(uv, v.buf, off, 2);
511 }
512 
Scm_PutBinaryF32(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)513 void Scm_PutBinaryF32(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
514 {
515     swap_f32_t v;
516     SCM_CHECK_ENDIAN(e);
517     v.val = (float)Scm_GetDouble(val);
518     SWAP_32(e, v);
519     inject(uv, v.buf, off, 4);
520 }
521 
Scm_PutBinaryF64(ScmUVector * uv,int off,ScmObj val,ScmSymbol * e)522 void Scm_PutBinaryF64(ScmUVector *uv, int off, ScmObj val, ScmSymbol *e)
523 {
524     swap_f64_t v;
525     SCM_CHECK_ENDIAN(e);
526     v.val = Scm_GetDouble(val);
527     SWAP_D(e, v);
528     inject(uv, v.buf, off, 8);
529 }
530