1/* endinconv.c -- Endian conversions utilities.
2 *
3 * This functions are never called directly, but always using the macros
4 * defined into endianconv.h, this way we define everything is a non-operation
5 * if the arch is already little endian.
6 *
7 * Redis tries to encode everything as little endian (but a few things that need
8 * to be backward compatible are still in big endian) because most of the
9 * production environments are little endian, and we have a lot of conversions
10 * in a few places because ziplists, intsets, zipmaps, need to be endian-neutral
11 * even in memory, since they are serialized on RDB files directly with a single
12 * write(2) without other additional steps.
13 *
14 * ----------------------------------------------------------------------------
15 *
16 * Copyright (c) 2011-2012, Salvatore Sanfilippo <antirez at gmail dot com>
17 * All rights reserved.
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions are met:
21 *
22 * * Redistributions of source code must retain the above copyright notice,
23 * this list of conditions and the following disclaimer.
24 * * Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * * Neither the name of Redis nor the names of its contributors may be used
28 * to endorse or promote products derived from this software without
29 * specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
42 */
43
44
45#include <stdint.h>
46
47/* Toggle the 16 bit unsigned integer pointed by *p from little endian to
48 * big endian */
49void memrev16(void *p) {
50 unsigned char *x = p, t;
51
52 t = x[0];
53 x[0] = x[1];
54 x[1] = t;
55}
56
57/* Toggle the 32 bit unsigned integer pointed by *p from little endian to
58 * big endian */
59void memrev32(void *p) {
60 unsigned char *x = p, t;
61
62 t = x[0];
63 x[0] = x[3];
64 x[3] = t;
65 t = x[1];
66 x[1] = x[2];
67 x[2] = t;
68}
69
70/* Toggle the 64 bit unsigned integer pointed by *p from little endian to
71 * big endian */
72void memrev64(void *p) {
73 unsigned char *x = p, t;
74
75 t = x[0];
76 x[0] = x[7];
77 x[7] = t;
78 t = x[1];
79 x[1] = x[6];
80 x[6] = t;
81 t = x[2];
82 x[2] = x[5];
83 x[5] = t;
84 t = x[3];
85 x[3] = x[4];
86 x[4] = t;
87}
88
89uint16_t intrev16(uint16_t v) {
90 memrev16(&v);
91 return v;
92}
93
94uint32_t intrev32(uint32_t v) {
95 memrev32(&v);
96 return v;
97}
98
99uint64_t intrev64(uint64_t v) {
100 memrev64(&v);
101 return v;
102}
103
104#ifdef REDIS_TEST
105#include <stdio.h>
106
107#define UNUSED(x) (void)(x)
108int endianconvTest(int argc, char *argv[], int flags) {
109 char buf[32];
110
111 UNUSED(argc);
112 UNUSED(argv);
113 UNUSED(flags);
114
115 sprintf(buf,"ciaoroma");
116 memrev16(buf);
117 printf("%s\n", buf);
118
119 sprintf(buf,"ciaoroma");
120 memrev32(buf);
121 printf("%s\n", buf);
122
123 sprintf(buf,"ciaoroma");
124 memrev64(buf);
125 printf("%s\n", buf);
126
127 return 0;
128}
129#endif
130