File: byteutils.c

package info (click to toggle)
uxplay 1.72.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,196 kB
  • sloc: ansic: 22,822; cpp: 2,342; makefile: 7
file content (136 lines) | stat: -rw-r--r-- 4,183 bytes parent folder | download
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
 * Copyright (c) 2019 dsafa22, All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 *=================================================================
 * modified by fduncanh 2021-23
 */
 

#define SECOND_IN_NSECS 1000000000UL

#include <time.h>
#ifdef _WIN32
# include <winsock2.h>
#else
# include <netinet/in.h>
#endif

#include "byteutils.h"

#ifdef _WIN32
# ifndef ntonll
#  define ntohll(x) ((1==ntohl(1)) ? (x) : (((uint64_t)ntohl((x) & 0xFFFFFFFFUL)) << 32) | ntohl((uint32_t)((x) >> 32)))
# endif
#ifndef htonll
#  define htonll(x) ((1==htonl(1)) ? (x) : (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32)))
#endif
#else
#  ifndef htonll
#   ifdef SYS_ENDIAN_H
#    include <sys/endian.h>
#   else
#    include <endian.h>
#   endif
#   define htonll(x) htobe64(x)
#   define ntohll(x) be64toh(x)
#  endif
#endif

// The functions in this file assume a little endian cpu architecture!

/**
 * Reads a little endian unsigned 16 bit integer from the buffer at position offset
 */
uint16_t byteutils_get_short(unsigned char* b, int offset) {
    return *((uint16_t*)(b + offset));
}

/**
 * Reads a little endian unsigned 32 bit integer from the buffer at position offset
 */
uint32_t byteutils_get_int(unsigned char* b, int offset) {
    return *((uint32_t*)(b + offset));
}

/**
 * Reads a little endian unsigned 64 bit integer from the buffer at position offset
 */
uint64_t byteutils_get_long(unsigned char* b, int offset) {
    return *((uint64_t*)(b + offset));
}

/**
 * Reads a big endian unsigned 16 bit integer from the buffer at position offset
 */
uint16_t byteutils_get_short_be(unsigned char* b, int offset) {
    return ntohs(byteutils_get_short(b, offset));
}

/**
 * Reads a big endian unsigned 32 bit integer from the buffer at position offset
 */
uint32_t byteutils_get_int_be(unsigned char* b, int offset) {
    return ntohl(byteutils_get_int(b, offset));
}

/**
 * Reads a big endian unsigned 64 bit integer from the buffer at position offset
 */
uint64_t byteutils_get_long_be(unsigned char* b, int offset) {
    return ntohll(byteutils_get_long(b, offset));
}
/**
 * Writes a big endian unsigned 64 bit integer to the buffer at position offset
 */
void byteutils_put_long_be(unsigned char* b, int offset, uint64_t value) {
    *((uint64_t*)(b + offset)) = htonll(value);
}

/**
 * Reads a float from the buffer at position offset
 */
float byteutils_get_float(unsigned char* b, int offset) {
    return *((float*)(b + offset));
}

/**
 * Writes a little endian unsigned 32 bit integer to the buffer at position offset
 */
void byteutils_put_int(unsigned char* b, int offset, uint32_t value) {
    *((uint32_t*)(b + offset)) = value;
}

/**
 * Reads an ntp timestamp and returns it as nano seconds since the Unix epoch
 */
uint64_t byteutils_get_ntp_timestamp(unsigned char *b, int offset) {
    uint64_t seconds = ntohl(((unsigned int) byteutils_get_int(b, offset))) - SECONDS_FROM_1900_TO_1970;
    uint64_t fraction = ntohl((unsigned int) byteutils_get_int(b, offset + 4));
    return (seconds * SECOND_IN_NSECS) + ((fraction * SECOND_IN_NSECS) >> 32);
}

/**
 * Writes a time given as nano seconds since the Unix time epoch as an ntp timestamp
 * into the buffer at position offset
 */
void byteutils_put_ntp_timestamp(unsigned char *b, int offset, uint64_t ns_since_1970) {
    uint64_t seconds = ns_since_1970 / SECOND_IN_NSECS;
    uint64_t nanoseconds = ns_since_1970 % SECOND_IN_NSECS;
    seconds += SECONDS_FROM_1900_TO_1970;
    uint64_t fraction = (nanoseconds << 32) / SECOND_IN_NSECS;

    // Write in big endian!
    byteutils_put_int(b, offset, htonl(seconds));
    byteutils_put_int(b, offset + 4, htonl(fraction));
}