]>
Commit | Line | Data |
---|---|---|
70ad1dc8 A |
1 | /* |
2 | * Copyright (c) 2018 Apple Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | #include "internal.h" | |
24 | ||
25 | #pragma mark API | |
26 | void | |
507116e3 | 27 | os_localtime_file(char buff[static 32]) |
70ad1dc8 A |
28 | { |
29 | struct timeval tv; | |
30 | struct tm curtime; | |
31 | ||
32 | posix_assert_zero(gettimeofday(&tv, NULL)); | |
33 | (void)localtime_r(&tv.tv_sec, &curtime); | |
34 | ||
35 | // Return a time representation that is ideal for use in filenames, so no | |
36 | // spaces or things that need to be escaped. | |
37 | snprintf(buff, 32, "%d-%02d-%02d_%02d.%02d.%02d.%06d", | |
38 | curtime.tm_year + 1900, curtime.tm_mon + 1, curtime.tm_mday, | |
39 | curtime.tm_hour, curtime.tm_min, curtime.tm_sec, tv.tv_usec); | |
40 | } | |
41 | ||
42 | // MurmurHash2 was written by Austin Appleby, and is placed in the public | |
43 | // domain. The author hereby disclaims copyright to this source code. | |
44 | uint64_t | |
507116e3 | 45 | os_simple_hash_with_seed(const void *buff, size_t len, uint64_t seed) |
70ad1dc8 | 46 | { |
70ad1dc8 A |
47 | #ifdef __LP64__ |
48 | // MurmurHash64A | |
49 | const uint64_t m = 0xc6a4a7935bd1e995; | |
50 | const int r = 47; | |
51 | uint64_t h = seed ^ (len * m); | |
52 | const uint64_t * data = (const uint64_t *)buff; | |
53 | const uint64_t * end = data + (len / 8); | |
54 | while(data != end) { | |
55 | uint64_t k = *data++; | |
56 | k *= m; | |
57 | k ^= k >> r; | |
58 | k *= m; | |
59 | h ^= k; | |
60 | h *= m; | |
61 | } | |
62 | const unsigned char * data2 = (const unsigned char *)data; | |
63 | switch(len & 7) { | |
64 | case 7: h ^= ((uint64_t)data2[6]) << 48; | |
65 | case 6: h ^= ((uint64_t)data2[5]) << 40; | |
66 | case 5: h ^= ((uint64_t)data2[4]) << 32; | |
67 | case 4: h ^= ((uint64_t)data2[3]) << 24; | |
68 | case 3: h ^= ((uint64_t)data2[2]) << 16; | |
69 | case 2: h ^= ((uint64_t)data2[1]) << 8; | |
70 | case 1: h ^= ((uint64_t)data2[0]); | |
71 | h *= m; | |
72 | }; | |
73 | h ^= h >> r; | |
74 | h *= m; | |
75 | h ^= h >> r; | |
76 | #else // __LP64__ | |
77 | // MurmurHash64B | |
78 | const uint32_t m = 0x5bd1e995; | |
79 | const int r = 24; | |
80 | ||
81 | uint32_t h1 = (uint32_t)(seed) ^ len; | |
82 | uint32_t h2 = (uint32_t)(seed >> 32); | |
83 | ||
84 | const uint32_t * data = (const uint32_t *)buff; | |
85 | ||
86 | #define MIX(k, h) \ | |
87 | (k) *= m; (k) ^= (k) >> r; (k) *= m; (h) *= m; (h) ^= (k); len -= 4; | |
88 | ||
89 | while(len >= 8) { | |
90 | uint32_t k[2]; | |
91 | memcpy(k, (const char*)data, sizeof(k)); | |
92 | data += sizeof(k)/sizeof(k[0]); | |
93 | ||
94 | MIX(k[0], h1) | |
95 | MIX(k[1], h2) | |
96 | } | |
97 | ||
98 | if(len >= 4) { | |
99 | uint32_t k[1]; | |
100 | memcpy(k, (const char *)data, sizeof(k)); | |
101 | data += sizeof(k)/sizeof(k[0]); | |
102 | ||
103 | MIX(k[0], h1); | |
104 | } | |
105 | ||
106 | #undef MIX | |
107 | ||
108 | switch(len) { | |
109 | case 3: h2 ^= ((unsigned char*)data)[2] << 16; | |
110 | case 2: h2 ^= ((unsigned char*)data)[1] << 8; | |
111 | case 1: h2 ^= ((unsigned char*)data)[0]; | |
112 | h2 *= m; | |
113 | }; | |
114 | ||
115 | h1 ^= h2 >> 18; h1 *= m; | |
116 | h2 ^= h1 >> 22; h2 *= m; | |
117 | h1 ^= h2 >> 17; h1 *= m; | |
118 | h2 ^= h1 >> 19; h2 *= m; | |
119 | ||
120 | uint64_t h = h1; | |
121 | ||
122 | h = (h << 32) | h2; | |
123 | #endif // __LP64__ | |
124 | return h; | |
125 | } | |
126 | ||
127 | uint64_t | |
507116e3 A |
128 | os_simple_hash(const void *buff, size_t len) |
129 | { | |
130 | return os_simple_hash_with_seed(buff, len, 0); | |
131 | } | |
132 | ||
133 | uint64_t | |
134 | os_simple_hash_string_with_seed(const char *string, uint64_t seed) | |
70ad1dc8 A |
135 | { |
136 | size_t len = strlen(string); | |
507116e3 A |
137 | return os_simple_hash_with_seed(string, len, seed); |
138 | } | |
139 | ||
140 | uint64_t | |
141 | os_simple_hash_string(const char *string) | |
142 | { | |
143 | return os_simple_hash_string_with_seed(string, 0); | |
144 | } | |
145 | ||
146 | errno_t | |
147 | realpath_np(os_fd_t fd, char buff[static PATH_MAX]) | |
148 | { | |
149 | errno_t error = -1; | |
150 | int ret = -1; | |
151 | ||
152 | ret = fcntl(fd, F_GETPATH, buff); | |
153 | if (ret) { | |
154 | error = errno; | |
155 | } else { | |
156 | error = 0; | |
157 | } | |
158 | ||
159 | return error; | |
70ad1dc8 | 160 | } |