BRL-CAD
cv.h
Go to the documentation of this file.
1/* C V . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2022 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
165BU_EXPORT extern uint32_t
166bu_ntohl(uint32_t netlong, uint32_t n_min, uint32_t n_max);
167
168
169BU_EXPORT extern uint16_t
170bu_ntohs(uint16_t netshort, uint32_t n_min, uint32_t n_max);
171
172/**
173 * convert from one format to another.
174 *
175 * @param in input pointer
176 * @param out output pointer
177 * @param count number of entries to convert
178 * @param size size of output buffer
179 * @param infmt input format
180 * @param outfmt output format
181 *
182 */
183BU_EXPORT extern size_t bu_cv(void *out, char *outfmt, size_t size, void *in, char *infmt, size_t count);
184
185/**
186 * Sets a bit vector after parsing an input string.
187 *
188 * Set up the conversion tables/flags for vert.
189 *
190 * @param in format description.
191 *
192 * @return a 32 bit vector.
193 *
194 * Format description:
195 * [channels][h|n][s|u] c|s|i|l|d|8|16|32|64 [N|C|L]
196 *
197 * @n channels must be null or 1
198 * @n Host | Network
199 * @n signed | unsigned
200 * @n char | short | integer | long | double | number of bits of integer
201 * @n Normalize | Clip | low-order
202 */
203BU_EXPORT extern int bu_cv_cookie(const char *in);
204
205/**
206 * It is always more efficient to handle host data, rather than
207 * network. If host and network formats are the same, and the request
208 * was for network format, modify the cookie to request host format.
209 */
210BU_EXPORT extern int bu_cv_optimize(int cookie);
211
212/**
213 * Returns the number of bytes each "item" of type "cookie" occupies.
214 */
215BU_EXPORT extern size_t bu_cv_itemlen(int cookie);
216
217/**
218 * convert with cookie
219 *
220 * @param in input pointer
221 * @param incookie input format cookie.
222 * @param count number of entries to convert.
223 * @param out output pointer.
224 * @param outcookie output format cookie.
225 * @param size size of output buffer in bytes;
226 *
227 *
228 * A worst case would be: ns16 on vax to ns32
229 * @code
230 * ns16 -> hs16
231 * -> hd
232 * -> hs32
233 * -> ns32
234 * @endcode
235 * The worst case is probably the easiest to deal with because all
236 * steps are done. The more difficult cases are when only a subset of
237 * steps need to be done.
238 *
239 * @par Method:
240 * @code
241 * HOSTDBL defined as true or false
242 * if ! hostother then
243 * hostother = (Endian == END_BIG) ? SAME : DIFFERENT;
244 * fi
245 * if (infmt == double) then
246 * if (HOSTDBL == SAME) {
247 * inIsHost = host;
248 * fi
249 * else
250 * if (hostother == SAME) {
251 * inIsHost = host;
252 * fi
253 * fi
254 * if (outfmt == double) then
255 * if (HOSTDBL == SAME) {
256 * outIsHost == host;
257 * else
258 * if (hostother == SAME) {
259 * outIsHost = host;
260 * fi
261 * fi
262 * if (infmt == outfmt) {
263 * if (inIsHost == outIsHost) {
264 * copy(in, out)
265 * exit
266 * else if (inIsHost == net) {
267 * ntoh?(in, out);
268 * exit
269 * else
270 * hton?(in, out);
271 * exit
272 * fi
273 * fi
274 *
275 * while not done {
276 * from = in;
277 *
278 * if (inIsHost == net) {
279 * ntoh?(from, t1);
280 * from = t1;
281 * fi
282 * if (infmt != double) {
283 * if (outIsHost == host) {
284 * to = out;
285 * else
286 * to = t2;
287 * fi
288 * castdbl(from, to);
289 * from = to;
290 * fi
291 *
292 * if (outfmt == double) {
293 * if (outIsHost == net) {
294 * hton?(from, out);
295 * fi
296 * else
297 * if (outIsHost == host) {
298 * dblcast(from, out);
299 * else
300 * dblcast(from, t3);
301 * hton?(t3, out);
302 * fi
303 * fi
304 * done
305 * @endcode
306 */
307BU_EXPORT extern size_t bu_cv_w_cookie(void *out, int outcookie, size_t size, void *in, int incookie, size_t count);
308
309/** @} */
310
311
312
313/** @ingroup bu_conv */
314/** @defgroup bu_cv_b64 Base64 Encoding and Decoding */
315/** @addtogroup bu_cv_b64
316 * Functions for b64 encoding and decoding.
317 */
318/** @{*/
319/**
320 * Encode null terminated input char array to b64.
321 *
322 * Caller is responsible for freeing memory allocated to
323 * hold output buffer.
324 */
325BU_EXPORT extern signed char *bu_b64_encode(const signed char *input);
326
327/**
328 * Encode length_in blocks in char array input to b64.
329 *
330 * Caller is responsible for freeing memory allocated to
331 * hold output buffer.
332 */
333
334BU_EXPORT extern signed char *bu_b64_encode_block(const signed char* input, size_t length_in);
335
336/**
337 * Decode null terminated b64 array to output_buffer.
338 *
339 * Caller is responsible for freeing memory allocated to
340 * hold output buffer.
341 */
342
343BU_EXPORT extern int bu_b64_decode(signed char **output_buffer, const signed char *input);
344
345/**
346 * Decode length_in blocks in b64 array input to output_buffer.
347 *
348 * Caller is responsible for freeing memory allocated to
349 * hold output buffer.
350 */
351BU_EXPORT extern int bu_b64_decode_block(signed char **output_buffer, const signed char* input, size_t length_in);
352/** @}*/
353
354
355/** @ingroup bu_conv */
356/** @defgroup bu_hton Network Byte-order Conversion */
357/** @addtogroup bu_hton
358 * Network to host and host to network conversion routines.
359 *
360 * It is assumed that these routines will only be called if there is
361 * real work to do - there is no checking to see if it is reasonable
362 * to do any conversions.
363 */
364/** @ingroup bu_hton */
365/** @defgroup bu_htond Network Conversion - Doubles */
366/** @ingroup bu_hton */
367/** @defgroup bu_htonf Network Conversion - Floats */
368/** @ingroup bu_hton */
369/** @defgroup bu_htons Network Conversion - Signed Short */
370
371/** @addtogroup bu_htond
372 * @brief Convert doubles to host/network format.
373 */
374/** @{*/
375BU_EXPORT extern void bu_cv_htond(unsigned char *out,
376 const unsigned char *in,
377 size_t count);
378BU_EXPORT extern void bu_cv_ntohd(unsigned char *out,
379 const unsigned char *in,
380 size_t count);
381/** @}*/
382
383
384/** @addtogroup bu_htonf
385 * @brief convert floats to host/network format
386 */
387/** @{*/
388BU_EXPORT extern void bu_cv_htonf(unsigned char *out,
389 const unsigned char *in,
390 size_t count);
391BU_EXPORT extern void bu_cv_ntohf(unsigned char *out,
392 const unsigned char *in,
393 size_t count);
394/** @}*/
395
396/** @addtogroup bu_htons
397 * @brief Network to Host Signed Short
398 *
399 * @param in generic pointer for input.
400 * @param count number of shorts to be generated.
401 * @param out short pointer for output
402 * @param size number of bytes of space reserved for out.
403 *
404 * @return number of conversions done.
405 */
406/** @{*/
407BU_EXPORT extern size_t bu_cv_ntohss(signed short *in, /* FIXME: in/out right? */
408 size_t count,
409 void *out,
410 size_t size);
411BU_EXPORT extern size_t bu_cv_ntohus(unsigned short *,
412 size_t,
413 void *,
414 size_t);
415BU_EXPORT extern size_t bu_cv_ntohsl(signed long int *,
416 size_t,
417 void *,
418 size_t);
419BU_EXPORT extern size_t bu_cv_ntohul(unsigned long int *,
420 size_t,
421 void *,
422 size_t);
423BU_EXPORT extern size_t bu_cv_htonss(void *,
424 size_t,
425 signed short *,
426 size_t);
427BU_EXPORT extern size_t bu_cv_htonus(void *,
428 size_t,
429 unsigned short *,
430 size_t);
431BU_EXPORT extern size_t bu_cv_htonsl(void *,
432 size_t,
433 long *,
434 size_t);
435BU_EXPORT extern size_t bu_cv_htonul(void *,
436 size_t,
437 unsigned long *,
438 size_t);
439/** @}*/
440
441
442
443
444/*
445 * DEPRECATED.
446 *
447 * Routines to implement an external data representation (XDR)
448 * compatible with the usual InterNet standards, e.g.:
449 * big-endian, twos-complement fixed point, and IEEE floating point.
450 *
451 * Routines to insert/extract short/long's into char arrays,
452 * independent of machine byte order and word-alignment.
453 * Uses encoding compatible with routines found in libpkg,
454 * and BSD system routines htonl(), htons(), ntohl(), ntohs().
455 *
456 */
457
458/*
459 * DEPRECATED: use ntohll()
460 * Macro version of library routine bu_glonglong()
461 * The argument is expected to be of type "unsigned char *"
462 */
463#define BU_GLONGLONG(_cp) \
464 ((((uint64_t)((_cp)[0])) << 56) | \
465 (((uint64_t)((_cp)[1])) << 48) | \
466 (((uint64_t)((_cp)[2])) << 40) | \
467 (((uint64_t)((_cp)[3])) << 32) | \
468 (((uint64_t)((_cp)[4])) << 24) | \
469 (((uint64_t)((_cp)[5])) << 16) | \
470 (((uint64_t)((_cp)[6])) << 8) | \
471 ((uint64_t)((_cp)[7])))
472/*
473 * DEPRECATED: use ntohl()
474 * Macro version of library routine bu_glong()
475 * The argument is expected to be of type "unsigned char *"
476 */
477#define BU_GLONG(_cp) \
478 ((((uint32_t)((_cp)[0])) << 24) | \
479 (((uint32_t)((_cp)[1])) << 16) | \
480 (((uint32_t)((_cp)[2])) << 8) | \
481 ((uint32_t)((_cp)[3])))
482/*
483 * DEPRECATED: use ntohs()
484 * Macro version of library routine bu_gshort()
485 * The argument is expected to be of type "unsigned char *"
486 */
487#define BU_GSHORT(_cp) \
488 ((((uint16_t)((_cp)[0])) << 8) | \
489 (_cp)[1])
490
491/*
492 * DEPRECATED: use ntohs()
493 */
494DEPRECATED BU_EXPORT extern uint16_t bu_gshort(const unsigned char *msgp);
495
496/*
497 * DEPRECATED: use ntohl()
498 */
499DEPRECATED BU_EXPORT extern uint32_t bu_glong(const unsigned char *msgp);
500
501/*
502 * DEPRECATED: use htons()
503 */
504DEPRECATED BU_EXPORT extern unsigned char *bu_pshort(unsigned char *msgp, uint16_t s);
505
506/*
507 * DEPRECATED: use htonl()
508 */
509DEPRECATED BU_EXPORT extern unsigned char *bu_plong(unsigned char *msgp, uint32_t l);
510
511/*
512 * DEPRECATED: use htonll()
513 */
514DEPRECATED BU_EXPORT extern unsigned char *bu_plonglong(unsigned char *msgp, uint64_t l);
515
516
517__END_DECLS
518
519#endif /* BU_CV_H */
520
521/*
522 * Local Variables:
523 * mode: C
524 * tab-width: 8
525 * indent-tabs-mode: t
526 * c-file-style: "stroustrup"
527 * End:
528 * ex: shiftwidth=4 tabstop=8
529 */
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)
uint16_t bu_ntohs(uint16_t netshort, uint32_t n_min, uint32_t n_max)
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)
uint32_t bu_ntohl(uint32_t netlong, uint32_t n_min, uint32_t n_max)
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:409