1228753Smm/*-
2228753Smm * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
3228753Smm * All rights reserved.
4228753Smm *
5228753Smm * Redistribution and use in source and binary forms, with or without
6228753Smm * modification, are permitted provided that the following conditions
7228753Smm * are met:
8228753Smm * 1. Redistributions of source code must retain the above copyright
9228753Smm *    notice, this list of conditions and the following disclaimer.
10228753Smm * 2. Redistributions in binary form must reproduce the above copyright
11228753Smm *    notice, this list of conditions and the following disclaimer in the
12228753Smm *    documentation and/or other materials provided with the distribution.
13228753Smm *
14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15228753Smm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16228753Smm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17228753Smm * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18228753Smm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19228753Smm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20228753Smm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21228753Smm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22228753Smm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23228753Smm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24228753Smm * SUCH DAMAGE.
25228753Smm *
26229592Smm * $FreeBSD$
27228753Smm *
28228753Smm * Borrowed from FreeBSD's <sys/endian.h>
29228753Smm */
30228753Smm
31228753Smm#ifndef __LIBARCHIVE_BUILD
32228753Smm#error This header is only to be used internally to libarchive.
33228753Smm#endif
34228753Smm
35228753Smm/* Note:  This is a purely internal header! */
36228753Smm/* Do not use this outside of libarchive internal code! */
37228753Smm
38228753Smm#ifndef ARCHIVE_ENDIAN_H_INCLUDED
39228753Smm#define ARCHIVE_ENDIAN_H_INCLUDED
40228753Smm
41228753Smm
42228753Smm/*
43228753Smm * Disabling inline keyword for compilers known to choke on it:
44228753Smm * - Watcom C++ in C code.  (For any version?)
45228753Smm * - SGI MIPSpro
46228753Smm * - Microsoft Visual C++ 6.0 (supposedly newer versions too)
47228753Smm */
48228753Smm#if defined(__WATCOMC__) || defined(__sgi) || defined(__hpux) || defined(__BORLANDC__)
49228753Smm#define	inline
50228753Smm#elif defined(_MSC_VER)
51228753Smm#define inline __inline
52228753Smm#endif
53228753Smm
54228753Smm/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
55228753Smm
56228753Smmstatic inline uint16_t
57228753Smmarchive_be16dec(const void *pp)
58228753Smm{
59228753Smm	unsigned char const *p = (unsigned char const *)pp;
60228753Smm
61228753Smm	return ((p[0] << 8) | p[1]);
62228753Smm}
63228753Smm
64228753Smmstatic inline uint32_t
65228753Smmarchive_be32dec(const void *pp)
66228753Smm{
67228753Smm	unsigned char const *p = (unsigned char const *)pp;
68228753Smm
69228753Smm	return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
70228753Smm}
71228753Smm
72228753Smmstatic inline uint64_t
73228753Smmarchive_be64dec(const void *pp)
74228753Smm{
75228753Smm	unsigned char const *p = (unsigned char const *)pp;
76228753Smm
77228753Smm	return (((uint64_t)archive_be32dec(p) << 32) | archive_be32dec(p + 4));
78228753Smm}
79228753Smm
80228753Smmstatic inline uint16_t
81228753Smmarchive_le16dec(const void *pp)
82228753Smm{
83228753Smm	unsigned char const *p = (unsigned char const *)pp;
84228753Smm
85228753Smm	return ((p[1] << 8) | p[0]);
86228753Smm}
87228753Smm
88228753Smmstatic inline uint32_t
89228753Smmarchive_le32dec(const void *pp)
90228753Smm{
91228753Smm	unsigned char const *p = (unsigned char const *)pp;
92228753Smm
93228753Smm	return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
94228753Smm}
95228753Smm
96228753Smmstatic inline uint64_t
97228753Smmarchive_le64dec(const void *pp)
98228753Smm{
99228753Smm	unsigned char const *p = (unsigned char const *)pp;
100228753Smm
101228753Smm	return (((uint64_t)archive_le32dec(p + 4) << 32) | archive_le32dec(p));
102228753Smm}
103228753Smm
104228753Smmstatic inline void
105228753Smmarchive_be16enc(void *pp, uint16_t u)
106228753Smm{
107228753Smm	unsigned char *p = (unsigned char *)pp;
108228753Smm
109228753Smm	p[0] = (u >> 8) & 0xff;
110228753Smm	p[1] = u & 0xff;
111228753Smm}
112228753Smm
113228753Smmstatic inline void
114228753Smmarchive_be32enc(void *pp, uint32_t u)
115228753Smm{
116228753Smm	unsigned char *p = (unsigned char *)pp;
117228753Smm
118228753Smm	p[0] = (u >> 24) & 0xff;
119228753Smm	p[1] = (u >> 16) & 0xff;
120228753Smm	p[2] = (u >> 8) & 0xff;
121228753Smm	p[3] = u & 0xff;
122228753Smm}
123228753Smm
124228753Smmstatic inline void
125228753Smmarchive_be64enc(void *pp, uint64_t u)
126228753Smm{
127228753Smm	unsigned char *p = (unsigned char *)pp;
128228753Smm
129228753Smm	archive_be32enc(p, u >> 32);
130228753Smm	archive_be32enc(p + 4, u & 0xffffffff);
131228753Smm}
132228753Smm
133228753Smmstatic inline void
134228753Smmarchive_le16enc(void *pp, uint16_t u)
135228753Smm{
136228753Smm	unsigned char *p = (unsigned char *)pp;
137228753Smm
138228753Smm	p[0] = u & 0xff;
139228753Smm	p[1] = (u >> 8) & 0xff;
140228753Smm}
141228753Smm
142228753Smmstatic inline void
143228753Smmarchive_le32enc(void *pp, uint32_t u)
144228753Smm{
145228753Smm	unsigned char *p = (unsigned char *)pp;
146228753Smm
147228753Smm	p[0] = u & 0xff;
148228753Smm	p[1] = (u >> 8) & 0xff;
149228753Smm	p[2] = (u >> 16) & 0xff;
150228753Smm	p[3] = (u >> 24) & 0xff;
151228753Smm}
152228753Smm
153228753Smmstatic inline void
154228753Smmarchive_le64enc(void *pp, uint64_t u)
155228753Smm{
156228753Smm	unsigned char *p = (unsigned char *)pp;
157228753Smm
158228753Smm	archive_le32enc(p, u & 0xffffffff);
159228753Smm	archive_le32enc(p + 4, u >> 32);
160228753Smm}
161228753Smm
162228753Smm#endif
163