forked from Jimmy-Z/bfCL
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathutils.c
202 lines (180 loc) · 4.28 KB
/
utils.c
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#ifndef _WIN32
#define _POSIX_C_SOURCE 199309L
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <immintrin.h>
#include "utils.h"
#ifdef __GNUC__
#include <cpuid.h>
#elif _MSC_VER
#include <intrin.h>
#endif
#ifndef _WIN32
#include <unistd.h>
#endif
int htoi(char a){
if(a >= '0' && a <= '9'){
return a - '0';
}else if(a >= 'a' && a <= 'f'){
return a - ('a' - 0xa);
}else if(a >= 'A' && a <= 'F'){
return a - ('A' - 0xa);
}else{
return -1;
}
}
int hex2bytes(unsigned char *out, unsigned byte_len, const char *in, int critical){
if (strlen(in) != byte_len << 1){
fprintf(stderr, "%s: invalid input length, expecting %u, got %u.\n",
__FUNCTION__, (unsigned)byte_len << 1, (unsigned)strlen(in));
assert(!critical);
return -1;
}
for(unsigned i = 0; i < byte_len; ++i){
int h = htoi(*in++), l = htoi(*in++);
if(h == -1 || l == -1){
fprintf(stderr, "%s: invalid input \"%c%c\"\n",
__FUNCTION__, *(in - 2), *(in - 1));
assert(!critical);
return -2;
}
*out++ = (h << 4) + l;
}
return 0;
}
#ifndef HEXDUMP_BUF_SIZE
#define HEXDUMP_BUF_SIZE 0x100
#endif
static char hexdump_buf[HEXDUMP_BUF_SIZE];
// CAUTION, this always assume the buffer is big enough
const char *hexdump(const void *b, unsigned l, int space){
const unsigned char *p = (unsigned char*)b;
char *out = hexdump_buf;
for(unsigned i = 0; i < l; ++i){
out += sprintf(out, "%02x", *p);
++p;
if(space && i < l - 1){
*out++ = ' ';
}
}
return hexdump_buf;
}
#ifdef _WIN32
long long hp_time_diff(LARGE_INTEGER *pt0, LARGE_INTEGER *pt1) {
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
long long diff = pt1->QuadPart - pt0->QuadPart;
diff *= 1000000;
diff /= freq.QuadPart;
return diff;
}
#else
void get_hp_time(struct timespec *pt) {
clock_gettime(CLOCK_MONOTONIC, pt);
}
long long hp_time_diff(struct timespec *pt0, struct timespec *pt1) {
long long diff = pt1->tv_sec - pt0->tv_sec;
diff *= 1000000;
diff += (pt1->tv_nsec - pt0->tv_nsec) / 1000;
return diff;
}
#endif
// CAUTION: caller is responsible to free the buf
char * read_file(const char *file_name, size_t *p_size) {
FILE * f = fopen(file_name, "rb");
if (f == NULL) {
fprintf(stderr, "can't read file: %s\n", file_name);
exit(-1);
}
fseek(f, 0, SEEK_END);
*p_size = ftell(f);
char * buf = malloc(*p_size);
fseek(f, 0, SEEK_SET);
if (fread(buf, *p_size, 1, f) != 1) {
fprintf(stderr, "error durring fread\n");
exit(-1);
}
fclose(f);
return buf;
}
void read_files(unsigned num_files, const char *file_names[], char *ptrs[], size_t sizes[]) {
for (unsigned i = 0; i < num_files; ++i) {
ptrs[i] = read_file(file_names[i], &sizes[i]);
}
}
void dump_to_file(const char *file_name, const void *buf, size_t len) {
FILE *f = fopen(file_name, "wb");
if (f == NULL) {
fprintf(stderr, "can't open file to write: %s\n", file_name);
return;
}
fwrite(buf, len, 1, f);
fclose(f);
}
int cpu_has_rdrand() {
#if __GNUC__
unsigned a = 0, b = 0, c = 0, d = 0;
__get_cpuid(1, &a, &b, &c, &d);
return c & bit_RDRND;
#elif _MSC_VER
int regs[4];
__cpuid(regs, 1);
return regs[2] & (1<<30);
#else
// ICL only?
return _may_i_use_cpu_feature(_FEATURE_RDRND);
#endif
}
// input must be multiple of uint64_t
int rdrand_fill(unsigned long long *p, size_t size) {
unsigned long long *p_end = p + size;
int success = 1;
while (p < p_end) {
success &= _rdrand64_step(p++);
}
return success;
}
inline int is_white_space(char c) {
return c == ' ' || c == '\t' || c == '\n' || c == '\r';
}
// the crudest trim
// it works by:
// setting the char next to the last non ws char to '\0'
// return the pointer to the first non ws character
// so beware the input string got modified
// and the returned ptr becomes unavailable if the input is gone
// and if the input is malloced, you should save the ptr for free
char * trim(char *in) {
char *first_non_ws = 0;
char *last_non_ws = 0;
while (*in) {
if (!is_white_space(*in)) {
if (!first_non_ws) {
first_non_ws = in;
}
last_non_ws = in;
}
++in;
}
// cut the trailing
++last_non_ws;
if (last_non_ws < in) {
*last_non_ws = '\0';
}
return first_non_ws;
}
void real_sleep(int sleep_sec) {
#ifdef _WIN32
Sleep(sleep_sec * 1000);
#else
sleep(sleep_sec);
#endif
}
void intHandler() {
// Not really needed for now.
stop_bfcl = 1;
exit(0);
}