BRL-CAD
cv.h
Go to the documentation of this file.
1 /* C V . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2024 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #ifndef BU_CV_H
22 #define BU_CV_H
23 
24 #include "common.h"
25 
26 #include <stddef.h> /* for size_t */
27 
28 #include "bu/defines.h"
29 
30 __BEGIN_DECLS
31 
32 /*----------------------------------------------------------------------*/
33 
34 /** @addtogroup bu_conv
35  *
36  * @brief
37  * Routines to translate data formats.
38  *
39  * The data formats are:
40  *
41  * \li Host/Network is the data in host format or local format
42  * \li signed/unsigned Is the data signed?
43  * \li char/short/int/long/double
44  * Is the data 8bits, 16bits, 32bits, 64bits
45  * or a double?
46  *
47  * The method of conversion is to convert up to double then back down the
48  * the expected output format.
49  *
50  * Also included are library routines for conversion between the local host 64-bit
51  * ("double precision") representation, and 64-bit IEEE double
52  * precision representation, in "network order", i.e., big-endian, the
53  * MSB in byte [0], on the left.
54  *
55  * As a quick review, the IEEE double precision format is as follows:
56  * sign bit, 11 bits of exponent (bias 1023), and 52 bits of mantissa,
57  * with a hidden leading one (0.1 binary).
58  *
59  * When the exponent is 0, IEEE defines a "denormalized number", which
60  * is not supported here.
61  *
62  * When the exponent is 2047 (all bits set), and:
63  * all mantissa bits are zero,
64  * value is infinity*sign,
65  * mantissa is non-zero, and:
66  * msb of mantissa=0: signaling NAN
67  * msb of mantissa=1: quiet NAN
68  *
69  * Note that neither the input or output buffers need be word aligned,
70  * for greatest flexibility in converting data, even though this
71  * imposes a speed penalty here.
72  *
73  * These subroutines operate on a sequential block of numbers, to save
74  * on subroutine linkage execution costs, and to allow some hope for
75  * vectorization.
76  *
77  * On brain-damaged machines like the SGI 3-D, where type "double"
78  * allocates only 4 bytes of space, these routines *still* return 8
79  * bytes in the IEEE buffer.
80  *
81  * The base64 encoding algorithm is an adaptation of the libb64 project - for
82  * details, see http://sourceforge.net/projects/libb64
83  */
84 /** @{*/
85 /** @file bu/cv.h */
86 /** @}*/
87 
88 /** @ingroup bu_conv */
89 /** @defgroup bu_conv_network_sizes Network Data Sizes */
90 /** @addtogroup bu_conv_network_sizes
91  * Sizes of "network" format data. We use the same convention as the
92  * TCP/IP specification, namely, big-Endian, IEEE format, twos
93  * complement. This is the BRL-CAD external data representation
94  * (XDR). See also the support routines in libbu/xdr.c
95  */
96 /** @{*/
97 #define SIZEOF_NETWORK_SHORT 2 /* htons(), bu_gshort(), bu_pshort() */
98 #define SIZEOF_NETWORK_LONG 4 /* htonl(), bu_glong(), bu_plong() */
99 #define SIZEOF_NETWORK_FLOAT 4 /* htonf() */
100 #define SIZEOF_NETWORK_DOUBLE 8 /* htond() */
101 /** @}*/
102 
103 /** @ingroup bu_conv */
104 /** @defgroup bu_cv_masks Conversion Bit Masks */
105 /** @addtogroup bu_cv_masks
106  * Mask definitions for CV
107  */
108 /** @{*/
109 #define CV_CHANNEL_MASK 0x00ff
110 #define CV_HOST_MASK 0x0100
111 #define CV_SIGNED_MASK 0x0200
112 #define CV_TYPE_MASK 0x1c00 /* 0001 1100 0000 0000 */
113 #define CV_CONVERT_MASK 0x6000 /* 0110 0000 0000 0000 */
114 /** @}*/
115 
116 /** @ingroup bu_conv */
117 /** @defgroup bu_cv_defs Conversion Defines */
118 /** @addtogroup bu_cv_defs
119  * Various convenience definitions for CV
120  */
121 /** @{*/
122 #define CV_TYPE_SHIFT 10
123 #define CV_CONVERT_SHIFT 13
124 
125 #define CV_8 0x0400
126 #define CV_16 0x0800
127 #define CV_32 0x0c00
128 #define CV_64 0x1000
129 #define CV_D 0x1400
130 
131 #define CV_CLIP 0x0000
132 #define CV_NORMAL 0x2000
133 #define CV_LIT 0x4000
134 
135 /** deprecated */
136 #define END_NOTSET 0
137 #define END_BIG 1 /* PowerPC/MIPS */
138 #define END_LITTLE 2 /* Intel */
139 #define END_ILL 3 /* PDP-11 */
140 #define END_CRAY 4 /* Old Cray */
141 
142 /** deprecated */
143 #define IND_NOTSET 0
144 #define IND_BIG 1
145 #define IND_LITTLE 2
146 #define IND_ILL 3
147 #define IND_CRAY 4
148 /** @}*/
149 
150 /** @addtogroup bu_conv */
151 /** @{*/
152 
153 /**
154  * provide for 64-bit network/host conversions using ntohl()
155  */
156 #if !defined(HAVE_NTOHLL) && !defined(ntohll)
157 # define ntohll(_val) ((bu_byteorder() == BU_LITTLE_ENDIAN) ? \
158  ((((uint64_t)ntohl((_val))) << 32) + ntohl((_val) >> 32)) : \
159  (_val)) /* sorry pdp-endian */
160 #endif
161 #if !defined(HAVE_HTONLL) && !defined(htonll)
162 # define htonll(_val) ntohll(_val)
163 #endif
164 
165 
166 /**
167  * convert from one format to another.
168  *
169  * @param in input pointer
170  * @param out output pointer
171  * @param count number of entries to convert
172  * @param size size of output buffer
173  * @param infmt input format
174  * @param outfmt output format
175  *
176  */
177 BU_EXPORT extern size_t bu_cv(void *out, char *outfmt, size_t size, void *in, char *infmt, size_t count);
178 
179 /**
180  * Sets a bit vector after parsing an input string.
181  *
182  * Set up the conversion tables/flags for vert.
183  *
184  * @param in format description.
185  *
186  * @return a 32 bit vector.
187  *
188  * Format description:
189  * [channels][h|n][s|u] c|s|i|l|d|8|16|32|64 [N|C|L]
190  *
191  * @n channels must be null or 1
192  * @n Host | Network
193  * @n signed | unsigned
194  * @n char | short | integer | long | double | number of bits of integer
195  * @n Normalize | Clip | low-order
196  */
197 BU_EXPORT extern int bu_cv_cookie(const char *in);
198 
199 /**
200  * It is always more efficient to handle host data, rather than
201  * network. If host and network formats are the same, and the request
202  * was for network format, modify the cookie to request host format.
203  */
204 BU_EXPORT extern int bu_cv_optimize(int cookie);
205 
206 /**
207  * Returns the number of bytes each "item" of type "cookie" occupies.
208  */
209 BU_EXPORT extern size_t bu_cv_itemlen(int cookie);
210 
211 /**
212  * convert with cookie
213  *
214  * @param in input pointer
215  * @param incookie input format cookie.
216  * @param count number of entries to convert.
217  * @param out output pointer.
218  * @param outcookie output format cookie.
219  * @param size size of output buffer in bytes;
220  *
221  *
222  * A worst case would be: ns16 on vax to ns32
223  * @code
224  * ns16 -> hs16
225  * -> hd
226  * -> hs32
227  * -> ns32
228  * @endcode
229  * The worst case is probably the easiest to deal with because all
230  * steps are done. The more difficult cases are when only a subset of
231  * steps need to be done.
232  *
233  * @par Method:
234  * @code
235  * HOSTDBL defined as true or false
236  * if ! hostother then
237  * hostother = (Endian == END_BIG) ? SAME : DIFFERENT;
238  * fi
239  * if (infmt == double) then
240  * if (HOSTDBL == SAME) {
241  * inIsHost = host;
242  * fi
243  * else
244  * if (hostother == SAME) {
245  * inIsHost = host;
246  * fi
247  * fi
248  * if (outfmt == double) then
249  * if (HOSTDBL == SAME) {
250  * outIsHost == host;
251  * else
252  * if (hostother == SAME) {
253  * outIsHost = host;
254  * fi
255  * fi
256  * if (infmt == outfmt) {
257  * if (inIsHost == outIsHost) {
258  * copy(in, out)
259  * exit
260  * else if (inIsHost == net) {
261  * ntoh?(in, out);
262  * exit
263  * else
264  * hton?(in, out);
265  * exit
266  * fi
267  * fi
268  *
269  * while not done {
270  * from = in;
271  *
272  * if (inIsHost == net) {
273  * ntoh?(from, t1);
274  * from = t1;
275  * fi
276  * if (infmt != double) {
277  * if (outIsHost == host) {
278  * to = out;
279  * else
280  * to = t2;
281  * fi
282  * castdbl(from, to);
283  * from = to;
284  * fi
285  *
286  * if (outfmt == double) {
287  * if (outIsHost == net) {
288  * hton?(from, out);
289  * fi
290  * else
291  * if (outIsHost == host) {
292  * dblcast(from, out);
293  * else
294  * dblcast(from, t3);
295  * hton?(t3, out);
296  * fi
297  * fi
298  * done
299  * @endcode
300  */
301 BU_EXPORT extern size_t bu_cv_w_cookie(void *out, int outcookie, size_t size, void *in, int incookie, size_t count);
302 
303 /** @} */
304 
305 
306 
307 /** @ingroup bu_conv */
308 /** @defgroup bu_cv_b64 Base64 Encoding and Decoding */
309 /** @addtogroup bu_cv_b64
310  * Functions for b64 encoding and decoding.
311  */
312 /** @{*/
313 /**
314  * Encode null terminated input char array to b64.
315  *
316  * Caller is responsible for freeing memory allocated to
317  * hold output buffer.
318  */
319 BU_EXPORT extern signed char *bu_b64_encode(const signed char *input);
320 
321 /**
322  * Encode length_in blocks in char array input to b64.
323  *
324  * Caller is responsible for freeing memory allocated to
325  * hold output buffer.
326  */
327 
328 BU_EXPORT extern signed char *bu_b64_encode_block(const signed char* input, size_t length_in);
329 
330 /**
331  * Decode null terminated b64 array to output_buffer.
332  *
333  * Caller is responsible for freeing memory allocated to
334  * hold output buffer.
335  */
336 
337 BU_EXPORT extern int bu_b64_decode(signed char **output_buffer, const signed char *input);
338 
339 /**
340  * Decode length_in blocks in b64 array input to output_buffer.
341  *
342  * Caller is responsible for freeing memory allocated to
343  * hold output buffer.
344  */
345 BU_EXPORT extern int bu_b64_decode_block(signed char **output_buffer, const signed char* input, size_t length_in);
346 /** @}*/
347 
348 
349 /** @ingroup bu_conv */
350 /** @defgroup bu_hton Network Byte-order Conversion */
351 /** @addtogroup bu_hton
352  * Network to host and host to network conversion routines.
353  *
354  * It is assumed that these routines will only be called if there is
355  * real work to do - there is no checking to see if it is reasonable
356  * to do any conversions.
357  */
358 /** @ingroup bu_hton */
359 /** @defgroup bu_htond Network Conversion - Doubles */
360 /** @ingroup bu_hton */
361 /** @defgroup bu_htonf Network Conversion - Floats */
362 /** @ingroup bu_hton */
363 /** @defgroup bu_htons Network Conversion - Signed Short */
364 
365 /** @addtogroup bu_htond
366  * @brief Convert doubles to host/network format.
367  */
368 /** @{*/
369 BU_EXPORT extern void bu_cv_htond(unsigned char *out,
370  const unsigned char *in,
371  size_t count);
372 BU_EXPORT extern void bu_cv_ntohd(unsigned char *out,
373  const unsigned char *in,
374  size_t count);
375 /** @}*/
376 
377 
378 /** @addtogroup bu_htonf
379  * @brief convert floats to host/network format
380  */
381 /** @{*/
382 BU_EXPORT extern void bu_cv_htonf(unsigned char *out,
383  const unsigned char *in,
384  size_t count);
385 BU_EXPORT extern void bu_cv_ntohf(unsigned char *out,
386  const unsigned char *in,
387  size_t count);
388 /** @}*/
389 
390 /** @addtogroup bu_htons
391  * @brief Network to Host Signed Short
392  *
393  * @param in generic pointer for input.
394  * @param count number of shorts to be generated.
395  * @param out short pointer for output
396  * @param size number of bytes of space reserved for out.
397  *
398  * @return number of conversions done.
399  */
400 /** @{*/
401 BU_EXPORT extern size_t bu_cv_ntohss(signed short *in, /* FIXME: in/out right? */
402  size_t count,
403  void *out,
404  size_t size);
405 BU_EXPORT extern size_t bu_cv_ntohus(unsigned short *,
406  size_t,
407  void *,
408  size_t);
409 BU_EXPORT extern size_t bu_cv_ntohsl(signed long int *,
410  size_t,
411  void *,
412  size_t);
413 BU_EXPORT extern size_t bu_cv_ntohul(unsigned long int *,
414  size_t,
415  void *,
416  size_t);
417 BU_EXPORT extern size_t bu_cv_htonss(void *,
418  size_t,
419  signed short *,
420  size_t);
421 BU_EXPORT extern size_t bu_cv_htonus(void *,
422  size_t,
423  unsigned short *,
424  size_t);
425 BU_EXPORT extern size_t bu_cv_htonsl(void *,
426  size_t,
427  long *,
428  size_t);
429 BU_EXPORT extern size_t bu_cv_htonul(void *,
430  size_t,
431  unsigned long *,
432  size_t);
433 /** @}*/
434 
435 
436 
437 
438 /*
439  * DEPRECATED.
440  *
441  * Routines to implement an external data representation (XDR)
442  * compatible with the usual InterNet standards, e.g.:
443  * big-endian, twos-complement fixed point, and IEEE floating point.
444  *
445  * Routines to insert/extract short/long's into char arrays,
446  * independent of machine byte order and word-alignment.
447  * Uses encoding compatible with routines found in libpkg,
448  * and BSD system routines htonl(), htons(), ntohl(), ntohs().
449  *
450  */
451 
452 /*
453  * DEPRECATED: use ntohll()
454  * Macro version of library routine bu_glonglong()
455  * The argument is expected to be of type "unsigned char *"
456  */
457 #define BU_GLONGLONG(_cp) \
458  ((((uint64_t)((_cp)[0])) << 56) | \
459  (((uint64_t)((_cp)[1])) << 48) | \
460  (((uint64_t)((_cp)[2])) << 40) | \
461  (((uint64_t)((_cp)[3])) << 32) | \
462  (((uint64_t)((_cp)[4])) << 24) | \
463  (((uint64_t)((_cp)[5])) << 16) | \
464  (((uint64_t)((_cp)[6])) << 8) | \
465  ((uint64_t)((_cp)[7])))
466 /*
467  * DEPRECATED: use ntohl()
468  * Macro version of library routine bu_glong()
469  * The argument is expected to be of type "unsigned char *"
470  */
471 #define BU_GLONG(_cp) \
472  ((((uint32_t)((_cp)[0])) << 24) | \
473  (((uint32_t)((_cp)[1])) << 16) | \
474  (((uint32_t)((_cp)[2])) << 8) | \
475  ((uint32_t)((_cp)[3])))
476 /*
477  * DEPRECATED: use ntohs()
478  * Macro version of library routine bu_gshort()
479  * The argument is expected to be of type "unsigned char *"
480  */
481 #define BU_GSHORT(_cp) \
482  ((((uint16_t)((_cp)[0])) << 8) | \
483  (_cp)[1])
484 
485 /*
486  * DEPRECATED: use ntohs()
487  */
488 DEPRECATED BU_EXPORT extern uint16_t bu_gshort(const unsigned char *msgp);
489 
490 /*
491  * DEPRECATED: use ntohl()
492  */
493 DEPRECATED BU_EXPORT extern uint32_t bu_glong(const unsigned char *msgp);
494 
495 /*
496  * DEPRECATED: use htons()
497  */
498 DEPRECATED BU_EXPORT extern unsigned char *bu_pshort(unsigned char *msgp, uint16_t s);
499 
500 /*
501  * DEPRECATED: use htonl()
502  */
503 DEPRECATED BU_EXPORT extern unsigned char *bu_plong(unsigned char *msgp, uint32_t l);
504 
505 /*
506  * DEPRECATED: use htonll()
507  */
508 DEPRECATED BU_EXPORT extern unsigned char *bu_plonglong(unsigned char *msgp, uint64_t l);
509 
510 
511 __END_DECLS
512 
513 #endif /* BU_CV_H */
514 
515 /*
516  * Local Variables:
517  * mode: C
518  * tab-width: 8
519  * indent-tabs-mode: t
520  * c-file-style: "stroustrup"
521  * End:
522  * ex: shiftwidth=4 tabstop=8
523  */
Header file for the BRL-CAD common definitions.
DEPRECATED uint16_t bu_gshort(const unsigned char *msgp)
DEPRECATED uint32_t bu_glong(const unsigned char *msgp)
DEPRECATED unsigned char * bu_pshort(unsigned char *msgp, uint16_t s)
DEPRECATED unsigned char * bu_plong(unsigned char *msgp, uint32_t l)
DEPRECATED unsigned char * bu_plonglong(unsigned char *msgp, uint64_t l)
size_t bu_cv_itemlen(int cookie)
int bu_cv_optimize(int cookie)
size_t bu_cv_w_cookie(void *out, int outcookie, size_t size, void *in, int incookie, size_t count)
size_t bu_cv(void *out, char *outfmt, size_t size, void *in, char *infmt, size_t count)
int bu_cv_cookie(const char *in)
int bu_b64_decode(signed char **output_buffer, const signed char *input)
signed char * bu_b64_encode(const signed char *input)
int bu_b64_decode_block(signed char **output_buffer, const signed char *input, size_t length_in)
signed char * bu_b64_encode_block(const signed char *input, size_t length_in)
void bu_cv_htond(unsigned char *out, const unsigned char *in, size_t count)
void bu_cv_ntohd(unsigned char *out, const unsigned char *in, size_t count)
void bu_cv_htonf(unsigned char *out, const unsigned char *in, size_t count)
void bu_cv_ntohf(unsigned char *out, const unsigned char *in, size_t count)
size_t bu_cv_ntohss(signed short *in, size_t count, void *out, size_t size)
size_t bu_cv_htonss(void *, size_t, signed short *, size_t)
size_t bu_cv_ntohus(unsigned short *, size_t, void *, size_t)
size_t bu_cv_ntohsl(signed long int *, size_t, void *, size_t)
size_t bu_cv_htonul(void *, size_t, unsigned long *, size_t)
size_t bu_cv_ntohul(unsigned long int *, size_t, void *, size_t)
size_t bu_cv_htonsl(void *, size_t, long *, size_t)
size_t bu_cv_htonus(void *, size_t, unsigned short *, size_t)
void float float int int int int float * size
Definition: tig.h:132
void float * input
Definition: tig.h:163
#define DEPRECATED
Definition: common.h:401