aboutsummaryrefslogtreecommitdiffstats
path: root/libfat/ulint.h
blob: 79eeaf41d0b3d1cfb76f4a6fe520d0f54f21b585 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* ----------------------------------------------------------------------- *
 *
 *   Copyright 2001-2004 H. Peter Anvin - All Rights Reserved
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
 *   USA; either version 2 of the License, or (at your option) any later
 *   version; incorporated herein by reference.
 *
 * ----------------------------------------------------------------------- */

/*
 * ulint.h
 *
 * Basic operations on unaligned, littleendian integers
 */

#ifndef ULINT_H
#define ULINT_H

#include <inttypes.h>

/* These are unaligned, littleendian integer types */

typedef uint8_t le8_t;		/*  8-bit byte */
typedef uint8_t le16_t[2];	/* 16-bit word */
typedef uint8_t le32_t[4];	/* 32-bit dword */

/* Read/write these quantities */

static inline unsigned char
read8(le8_t *_p)
{
  return *_p;
}

static inline void
write8(le8_t *_p, uint8_t _v)
{
  *_p = _v;
}

#if defined(__i386__) || defined(__x86_64__)

/* Littleendian architectures which support unaligned memory accesses */

static inline unsigned short
read16(le16_t *_p)
{
  return *((const uint16_t *)_p);
}

static inline void
write16(le16_t *_p, unsigned short _v)
{
  *((uint16_t *)_p) = _v;
}

static inline unsigned int
read32(le32_t *_p)
{
  return *((const uint32_t *)_p);
}

static inline void
write32(le32_t *_p, uint32_t _v)
{
  *((uint32_t *)_p) = _v;
}

#else

/* Generic, mostly portable versions */

static inline unsigned short
read16(le16_t *_pp)
{
  uint8_t *_p = *_pp;
  uint16_t _v;

  _v  = _p[0];
  _v |= _p[1] << 8;
  return _v;
}

static inline void
write16(le16_t *_pp, uint16_t _v)
{
  uint8_t *_p = *_pp;

  _p[0] = _v & 0xFF;
  _p[1] = (_v >> 8) & 0xFF;
}

static inline unsigned int
read32(le32_t *_pp)
{
  uint8_t *_p = *_pp;
  uint32_t _v;

  _v  = _p[0];
  _v |= _p[1] << 8;
  _v |= _p[2] << 16;
  _v |= _p[3] << 24;
  return _v;
}

static inline void
write32(le32_t *_pp, uint32_t _v)
{
  uint8_t *_p = *_pp;

  _p[0] = _v & 0xFF;
  _p[1] = (_v >> 8) & 0xFF;
  _p[2] = (_v >> 16) & 0xFF;
  _p[3] = (_v >> 24) & 0xFF;
}

#endif

#endif /* ULINT_H */