BRL-CAD
cv.h
Go to the documentation of this file.
1/* C V . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2023 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 */
177BU_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 */
197BU_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 */
204BU_EXPORT extern int bu_cv_optimize(int cookie);
205
206/**
207 * Returns the number of bytes each "item" of type "cookie" occupies.
208 */
209BU_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 */
301BU_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 */
319BU_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
328BU_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
337BU_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 */
345BU_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/** @{*/
369BU_EXPORT extern void bu_cv_htond(unsigned char *out,
370 const unsigned char *in,
371 size_t count);
372BU_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/** @{*/
382BU_EXPORT extern void bu_cv_htonf(unsigned char *out,
383 const unsigned char *in,
384 size_t count);
385BU_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/** @{*/
401BU_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);
405BU_EXPORT extern size_t bu_cv_ntohus(unsigned short *,
406 size_t,
407 void *,
408 size_t);
409BU_EXPORT extern size_t bu_cv_ntohsl(signed long int *,
410 size_t,
411 void *,
412 size_t);
413BU_EXPORT extern size_t bu_cv_ntohul(unsigned long int *,
414 size_t,
415 void *,
416 size_t);
417BU_EXPORT extern size_t bu_cv_htonss(void *,
418 size_t,
419 signed short *,
420 size_t);
421BU_EXPORT extern size_t bu_cv_htonus(void *,
422 size_t,
423 unsigned short *,
424 size_t);
425BU_EXPORT extern size_t bu_cv_htonsl(void *,
426 size_t,
427 long *,
428 size_t);
429BU_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 */
488DEPRECATED BU_EXPORT extern uint16_t bu_gshort(const unsigned char *msgp);
489
490/*
491 * DEPRECATED: use ntohl()
492 */
493DEPRECATED BU_EXPORT extern uint32_t bu_glong(const unsigned char *msgp);
494
495/*
496 * DEPRECATED: use htons()
497 */
498DEPRECATED BU_EXPORT extern unsigned char *bu_pshort(unsigned char *msgp, uint16_t s);
499
500/*
501 * DEPRECATED: use htonl()
502 */
503DEPRECATED BU_EXPORT extern unsigned char *bu_plong(unsigned char *msgp, uint32_t l);
504
505/*
506 * DEPRECATED: use htonll()
507 */
508DEPRECATED 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 unsigned char * bu_pshort(unsigned char *msgp, uint16_t s)
DEPRECATED uint16_t bu_gshort(const unsigned char *msgp)
DEPRECATED uint32_t bu_glong(const unsigned char *msgp)
DEPRECATED unsigned char * bu_plonglong(unsigned char *msgp, uint64_t l)
DEPRECATED unsigned char * bu_plong(unsigned char *msgp, uint32_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)
signed char * bu_b64_encode(const signed char *input)
signed char * bu_b64_encode_block(const signed char *input, size_t length_in)
int bu_b64_decode(signed char **output_buffer, const signed char *input)
int bu_b64_decode_block(signed char **output_buffer, 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:400