ulid-transform 1.2.0__cp312-cp312-musllinux_1_2_aarch64.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,555 @@
1
+ #ifndef ULID_UINT128_HH
2
+ #define ULID_UINT128_HH
3
+
4
+ #include <chrono>
5
+ #include <cstdlib>
6
+ #include <ctime>
7
+ #include <functional>
8
+ #include <random>
9
+ #include <vector>
10
+
11
+ #if _MSC_VER > 0
12
+ typedef uint32_t rand_t;
13
+ # else
14
+ typedef uint8_t rand_t;
15
+ #endif
16
+
17
+ namespace ulid {
18
+
19
+ /**
20
+ * ULID is a 16 byte Universally Unique Lexicographically Sortable Identifier
21
+ * */
22
+ typedef __uint128_t ULID;
23
+
24
+ /**
25
+ * EncodeTimestamp will encode the int64_t timestamp to the passed ulid
26
+ * */
27
+ inline void EncodeTimestamp(int64_t timestamp, ULID& ulid) {
28
+ ULID t = static_cast<uint8_t>(timestamp >> 40);
29
+
30
+ t <<= 8;
31
+ t |= static_cast<uint8_t>(timestamp >> 32);
32
+
33
+ t <<= 8;
34
+ t |= static_cast<uint8_t>(timestamp >> 24);
35
+
36
+ t <<= 8;
37
+ t |= static_cast<uint8_t>(timestamp >> 16);
38
+
39
+ t <<= 8;
40
+ t |= static_cast<uint8_t>(timestamp >> 8);
41
+
42
+ t <<= 8;
43
+ t |= static_cast<uint8_t>(timestamp);
44
+
45
+ t <<= 80;
46
+
47
+ ULID mask = 1;
48
+ mask <<= 80;
49
+ mask--;
50
+
51
+ ulid = t | (ulid & mask);
52
+ }
53
+
54
+ /**
55
+ * EncodeTime will encode the time point to the passed ulid
56
+ * */
57
+ inline void EncodeTime(std::chrono::time_point<std::chrono::system_clock> time_point, ULID& ulid) {
58
+ auto time_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(time_point);
59
+ int64_t timestamp = time_ms.time_since_epoch().count();
60
+ EncodeTimestamp(timestamp, ulid);
61
+ }
62
+
63
+ /**
64
+ * EncodeTimeNow will encode a ULID using the time obtained using std::time(nullptr)
65
+ * */
66
+ inline void EncodeTimeNow(ULID& ulid) {
67
+ auto time_now = std::chrono::system_clock::from_time_t(time(nullptr));
68
+ EncodeTime(time_now, ulid);
69
+ }
70
+
71
+ /**
72
+ * EncodeTimeSystemClockNow will encode a ULID using the time obtained using
73
+ * std::chrono::system_clock::now() by taking the timestamp in milliseconds.
74
+ * */
75
+ inline void EncodeTimeSystemClockNow(ULID& ulid) {
76
+ EncodeTime(std::chrono::system_clock::now(), ulid);
77
+ }
78
+
79
+ /**
80
+ * EncodeEntropy will encode the last 10 bytes of the passed uint8_t array with
81
+ * the values generated using the passed random number generator.
82
+ * */
83
+ inline void EncodeEntropy(const std::function<uint8_t()>& rng, ULID& ulid) {
84
+ ulid = (ulid >> 80) << 80;
85
+
86
+ ULID e = rng();
87
+
88
+ e <<= 8;
89
+ e |= rng();
90
+
91
+ e <<= 8;
92
+ e |= rng();
93
+
94
+ e <<= 8;
95
+ e |= rng();
96
+
97
+ e <<= 8;
98
+ e |= rng();
99
+
100
+ e <<= 8;
101
+ e |= rng();
102
+
103
+ e <<= 8;
104
+ e |= rng();
105
+
106
+ e <<= 8;
107
+ e |= rng();
108
+
109
+ e <<= 8;
110
+ e |= rng();
111
+
112
+ e <<= 8;
113
+ e |= rng();
114
+
115
+ ulid |= e;
116
+ }
117
+
118
+ /**
119
+ * EncodeEntropyRand will encode a ulid using std::rand
120
+ *
121
+ * std::rand returns values in [0, RAND_MAX]
122
+ * */
123
+ inline void EncodeEntropyRand(ULID& ulid) {
124
+ ulid = (ulid >> 80) << 80;
125
+
126
+ ULID e = (std::rand() * 255ull) / RAND_MAX;
127
+
128
+ e <<= 8;
129
+ e |= (std::rand() * 255ull) / RAND_MAX;
130
+
131
+ e <<= 8;
132
+ e |= (std::rand() * 255ull) / RAND_MAX;
133
+
134
+ e <<= 8;
135
+ e |= (std::rand() * 255ull) / RAND_MAX;
136
+
137
+ e <<= 8;
138
+ e |= (std::rand() * 255ull) / RAND_MAX;
139
+
140
+ e <<= 8;
141
+ e |= (std::rand() * 255ull) / RAND_MAX;
142
+
143
+ e <<= 8;
144
+ e |= (std::rand() * 255ull) / RAND_MAX;
145
+
146
+ e <<= 8;
147
+ e |= (std::rand() * 255ull) / RAND_MAX;
148
+
149
+ e <<= 8;
150
+ e |= (std::rand() * 255ull) / RAND_MAX;
151
+
152
+ e <<= 8;
153
+ e |= (std::rand() * 255ull) / RAND_MAX;
154
+
155
+ ulid |= e;
156
+ }
157
+
158
+ static std::uniform_int_distribution<rand_t> Distribution_0_255(0, 255);
159
+
160
+ /**
161
+ * EncodeEntropyMt19937 will encode a ulid using std::mt19937
162
+ *
163
+ * It also creates a std::uniform_int_distribution to generate values in [0, 255]
164
+ * */
165
+ inline void EncodeEntropyMt19937(std::mt19937& generator, ULID& ulid) {
166
+ ulid = (ulid >> 80) << 80;
167
+
168
+ ULID e = Distribution_0_255(generator);
169
+
170
+ e <<= 8;
171
+ e |= Distribution_0_255(generator);
172
+
173
+ e <<= 8;
174
+ e |= Distribution_0_255(generator);
175
+
176
+ e <<= 8;
177
+ e |= Distribution_0_255(generator);
178
+
179
+ e <<= 8;
180
+ e |= Distribution_0_255(generator);
181
+
182
+ e <<= 8;
183
+ e |= Distribution_0_255(generator);
184
+
185
+ e <<= 8;
186
+ e |= Distribution_0_255(generator);
187
+
188
+ e <<= 8;
189
+ e |= Distribution_0_255(generator);
190
+
191
+ e <<= 8;
192
+ e |= Distribution_0_255(generator);
193
+
194
+ e <<= 8;
195
+ e |= Distribution_0_255(generator);
196
+
197
+ ulid |= e;
198
+ }
199
+
200
+ /**
201
+ * Encode will create an encoded ULID with a timestamp and a generator.
202
+ * */
203
+ inline void Encode(std::chrono::time_point<std::chrono::system_clock> timestamp, const std::function<uint8_t()>& rng, ULID& ulid) {
204
+ EncodeTime(timestamp, ulid);
205
+ EncodeEntropy(rng, ulid);
206
+ }
207
+
208
+ /**
209
+ * EncodeNowRand = EncodeTimeNow + EncodeEntropyRand.
210
+ * */
211
+ inline void EncodeNowRand(ULID& ulid) {
212
+ EncodeTimeNow(ulid);
213
+ EncodeEntropyRand(ulid);
214
+ }
215
+
216
+ /**
217
+ * Create will create a ULID with a timestamp and a generator.
218
+ * */
219
+ inline ULID Create(std::chrono::time_point<std::chrono::system_clock> timestamp, const std::function<uint8_t()>& rng) {
220
+ ULID ulid = 0;
221
+ Encode(timestamp, rng, ulid);
222
+ return ulid;
223
+ }
224
+
225
+ /**
226
+ * CreateNowRand:EncodeNowRand = Create:Encode.
227
+ * */
228
+ inline ULID CreateNowRand() {
229
+ ULID ulid = 0;
230
+ EncodeNowRand(ulid);
231
+ return ulid;
232
+ }
233
+
234
+ /**
235
+ * Crockford's Base32
236
+ * */
237
+ static const char Encoding[33] = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
238
+
239
+ /**
240
+ * MarshalTo will marshal a ULID to the passed character array.
241
+ *
242
+ * Implementation taken directly from oklog/ulid
243
+ * (https://sourcegraph.com/github.com/oklog/ulid@0774f81f6e44af5ce5e91c8d7d76cf710e889ebb/-/blob/ulid.go#L162-190)
244
+ *
245
+ * timestamp:
246
+ * dst[0]: first 3 bits of data[0]
247
+ * dst[1]: last 5 bits of data[0]
248
+ * dst[2]: first 5 bits of data[1]
249
+ * dst[3]: last 3 bits of data[1] + first 2 bits of data[2]
250
+ * dst[4]: bits 3-7 of data[2]
251
+ * dst[5]: last bit of data[2] + first 4 bits of data[3]
252
+ * dst[6]: last 4 bits of data[3] + first bit of data[4]
253
+ * dst[7]: bits 2-6 of data[4]
254
+ * dst[8]: last 2 bits of data[4] + first 3 bits of data[5]
255
+ * dst[9]: last 5 bits of data[5]
256
+ *
257
+ * entropy:
258
+ * follows similarly, except now all components are set to 5 bits.
259
+ * */
260
+ inline void MarshalTo(const ULID& ulid, char dst[26]) {
261
+ // 10 byte timestamp
262
+ dst[0] = Encoding[(static_cast<uint8_t>(ulid >> 120) & 224) >> 5];
263
+ dst[1] = Encoding[static_cast<uint8_t>(ulid >> 120) & 31];
264
+ dst[2] = Encoding[(static_cast<uint8_t>(ulid >> 112) & 248) >> 3];
265
+ dst[3] = Encoding[((static_cast<uint8_t>(ulid >> 112) & 7) << 2) | ((static_cast<uint8_t>(ulid >> 104) & 192) >> 6)];
266
+ dst[4] = Encoding[(static_cast<uint8_t>(ulid >> 104) & 62) >> 1];
267
+ dst[5] = Encoding[((static_cast<uint8_t>(ulid >> 104) & 1) << 4) | ((static_cast<uint8_t>(ulid >> 96) & 240) >> 4)];
268
+ dst[6] = Encoding[((static_cast<uint8_t>(ulid >> 96) & 15) << 1) | ((static_cast<uint8_t>(ulid >> 88) & 128) >> 7)];
269
+ dst[7] = Encoding[(static_cast<uint8_t>(ulid >> 88) & 124) >> 2];
270
+ dst[8] = Encoding[((static_cast<uint8_t>(ulid >> 88) & 3) << 3) | ((static_cast<uint8_t>(ulid >> 80) & 224) >> 5)];
271
+ dst[9] = Encoding[static_cast<uint8_t>(ulid >> 80) & 31];
272
+
273
+ // 16 bytes of entropy
274
+ dst[10] = Encoding[(static_cast<uint8_t>(ulid >> 72) & 248) >> 3];
275
+ dst[11] = Encoding[((static_cast<uint8_t>(ulid >> 72) & 7) << 2) | ((static_cast<uint8_t>(ulid >> 64) & 192) >> 6)];
276
+ dst[12] = Encoding[(static_cast<uint8_t>(ulid >> 64) & 62) >> 1];
277
+ dst[13] = Encoding[((static_cast<uint8_t>(ulid >> 64) & 1) << 4) | ((static_cast<uint8_t>(ulid >> 56) & 240) >> 4)];
278
+ dst[14] = Encoding[((static_cast<uint8_t>(ulid >> 56) & 15) << 1) | ((static_cast<uint8_t>(ulid >> 48) & 128) >> 7)];
279
+ dst[15] = Encoding[(static_cast<uint8_t>(ulid >> 48) & 124) >> 2];
280
+ dst[16] = Encoding[((static_cast<uint8_t>(ulid >> 48) & 3) << 3) | ((static_cast<uint8_t>(ulid >> 40) & 224) >> 5)];
281
+ dst[17] = Encoding[static_cast<uint8_t>(ulid >> 40) & 31];
282
+ dst[18] = Encoding[(static_cast<uint8_t>(ulid >> 32) & 248) >> 3];
283
+ dst[19] = Encoding[((static_cast<uint8_t>(ulid >> 32) & 7) << 2) | ((static_cast<uint8_t>(ulid >> 24) & 192) >> 6)];
284
+ dst[20] = Encoding[(static_cast<uint8_t>(ulid >> 24) & 62) >> 1];
285
+ dst[21] = Encoding[((static_cast<uint8_t>(ulid >> 24) & 1) << 4) | ((static_cast<uint8_t>(ulid >> 16) & 240) >> 4)];
286
+ dst[22] = Encoding[((static_cast<uint8_t>(ulid >> 16) & 15) << 1) | ((static_cast<uint8_t>(ulid >> 8) & 128) >> 7)];
287
+ dst[23] = Encoding[(static_cast<uint8_t>(ulid >> 8) & 124) >> 2];
288
+ dst[24] = Encoding[((static_cast<uint8_t>(ulid >> 8) & 3) << 3) | (((static_cast<uint8_t>(ulid)) & 224) >> 5)];
289
+ dst[25] = Encoding[(static_cast<uint8_t>(ulid)) & 31];
290
+ }
291
+
292
+ /**
293
+ * Marshal will marshal a ULID to a std::string.
294
+ * */
295
+ inline std::string Marshal(const ULID& ulid) {
296
+ char data[27];
297
+ data[26] = '\0';
298
+ MarshalTo(ulid, data);
299
+ return std::string(data);
300
+ }
301
+
302
+ /**
303
+ * MarshalBinaryTo will Marshal a ULID to the passed byte array
304
+ * */
305
+ inline void MarshalBinaryTo(const ULID& ulid, uint8_t dst[16]) {
306
+ // timestamp
307
+ dst[0] = static_cast<uint8_t>(ulid >> 120);
308
+ dst[1] = static_cast<uint8_t>(ulid >> 112);
309
+ dst[2] = static_cast<uint8_t>(ulid >> 104);
310
+ dst[3] = static_cast<uint8_t>(ulid >> 96);
311
+ dst[4] = static_cast<uint8_t>(ulid >> 88);
312
+ dst[5] = static_cast<uint8_t>(ulid >> 80);
313
+
314
+ // entropy
315
+ dst[6] = static_cast<uint8_t>(ulid >> 72);
316
+ dst[7] = static_cast<uint8_t>(ulid >> 64);
317
+ dst[8] = static_cast<uint8_t>(ulid >> 56);
318
+ dst[9] = static_cast<uint8_t>(ulid >> 48);
319
+ dst[10] = static_cast<uint8_t>(ulid >> 40);
320
+ dst[11] = static_cast<uint8_t>(ulid >> 32);
321
+ dst[12] = static_cast<uint8_t>(ulid >> 24);
322
+ dst[13] = static_cast<uint8_t>(ulid >> 16);
323
+ dst[14] = static_cast<uint8_t>(ulid >> 8);
324
+ dst[15] = static_cast<uint8_t>(ulid);
325
+ }
326
+
327
+ /**
328
+ * MarshalBinary will Marshal a ULID to a byte vector.
329
+ * */
330
+ inline std::vector<uint8_t> MarshalBinary(const ULID& ulid) {
331
+ std::vector<uint8_t> dst(16);
332
+ MarshalBinaryTo(ulid, dst.data());
333
+ return dst;
334
+ }
335
+
336
+ /**
337
+ * dec storesdecimal encodings for characters.
338
+ * 0xFF indicates invalid character.
339
+ * 48-57 are digits.
340
+ * 65-90 are capital alphabets.
341
+ * */
342
+ static const uint8_t dec[256] = {
343
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
344
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
345
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
346
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
347
+
348
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
349
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
350
+ /* 0 1 2 3 4 5 6 7 */
351
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
352
+ /* 8 9 */
353
+ 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
354
+
355
+ /* 10(A) 11(B) 12(C) 13(D) 14(E) 15(F) 16(G) */
356
+ 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
357
+ /*17(H) 18(J) 19(K) 20(M) 21(N) */
358
+ 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF,
359
+ /*22(P)23(Q)24(R) 25(S) 26(T) 27(V) 28(W) */
360
+ 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C,
361
+ /*29(X)30(Y)31(Z) */
362
+ 0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
363
+
364
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
365
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
366
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
367
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
368
+
369
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
370
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
371
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
372
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
373
+
374
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
375
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
376
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
377
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
378
+
379
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
380
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
381
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
382
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
383
+
384
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
385
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
386
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
387
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
388
+ };
389
+
390
+ /**
391
+ * UnmarshalFrom will unmarshal a ULID from the passed character array.
392
+ * */
393
+ inline void UnmarshalFrom(const char str[26], ULID& ulid) {
394
+ // timestamp
395
+ ulid = (dec[int(str[0])] << 5) | dec[int(str[1])];
396
+
397
+ ulid <<= 8;
398
+ ulid |= (dec[int(str[2])] << 3) | (dec[int(str[3])] >> 2);
399
+
400
+ ulid <<= 8;
401
+ ulid |= (dec[int(str[3])] << 6) | (dec[int(str[4])] << 1) | (dec[int(str[5])] >> 4);
402
+
403
+ ulid <<= 8;
404
+ ulid |= (dec[int(str[5])] << 4) | (dec[int(str[6])] >> 1);
405
+
406
+ ulid <<= 8;
407
+ ulid |= (dec[int(str[6])] << 7) | (dec[int(str[7])] << 2) | (dec[int(str[8])] >> 3);
408
+
409
+ ulid <<= 8;
410
+ ulid |= (dec[int(str[8])] << 5) | dec[int(str[9])];
411
+
412
+ // entropy
413
+ ulid <<= 8;
414
+ ulid |= (dec[int(str[10])] << 3) | (dec[int(str[11])] >> 2);
415
+
416
+ ulid <<= 8;
417
+ ulid |= (dec[int(str[11])] << 6) | (dec[int(str[12])] << 1) | (dec[int(str[13])] >> 4);
418
+
419
+ ulid <<= 8;
420
+ ulid |= (dec[int(str[13])] << 4) | (dec[int(str[14])] >> 1);
421
+
422
+ ulid <<= 8;
423
+ ulid |= (dec[int(str[14])] << 7) | (dec[int(str[15])] << 2) | (dec[int(str[16])] >> 3);
424
+
425
+ ulid <<= 8;
426
+ ulid |= (dec[int(str[16])] << 5) | dec[int(str[17])];
427
+
428
+ ulid <<= 8;
429
+ ulid |= (dec[int(str[18])] << 3) | (dec[int(str[19])] >> 2);
430
+
431
+ ulid <<= 8;
432
+ ulid |= (dec[int(str[19])] << 6) | (dec[int(str[20])] << 1) | (dec[int(str[21])] >> 4);
433
+
434
+ ulid <<= 8;
435
+ ulid |= (dec[int(str[21])] << 4) | (dec[int(str[22])] >> 1);
436
+
437
+ ulid <<= 8;
438
+ ulid |= (dec[int(str[22])] << 7) | (dec[int(str[23])] << 2) | (dec[int(str[24])] >> 3);
439
+
440
+ ulid <<= 8;
441
+ ulid |= (dec[int(str[24])] << 5) | dec[int(str[25])];
442
+ }
443
+
444
+ /**
445
+ * Unmarshal will create a new ULID by unmarshaling the passed string.
446
+ * */
447
+ inline ULID Unmarshal(const std::string& str) {
448
+ ULID ulid;
449
+ UnmarshalFrom(str.c_str(), ulid);
450
+ return ulid;
451
+ }
452
+
453
+ /**
454
+ * UnmarshalBinaryFrom will unmarshal a ULID from the passed byte array.
455
+ * */
456
+ inline void UnmarshalBinaryFrom(const uint8_t b[16], ULID& ulid) {
457
+ // timestamp
458
+ ulid = b[0];
459
+
460
+ ulid <<= 8;
461
+ ulid |= b[1];
462
+
463
+ ulid <<= 8;
464
+ ulid |= b[2];
465
+
466
+ ulid <<= 8;
467
+ ulid |= b[3];
468
+
469
+ ulid <<= 8;
470
+ ulid |= b[4];
471
+
472
+ ulid <<= 8;
473
+ ulid |= b[5];
474
+
475
+ // entropy
476
+ ulid <<= 8;
477
+ ulid |= b[6];
478
+
479
+ ulid <<= 8;
480
+ ulid |= b[7];
481
+
482
+ ulid <<= 8;
483
+ ulid |= b[8];
484
+
485
+ ulid <<= 8;
486
+ ulid |= b[9];
487
+
488
+ ulid <<= 8;
489
+ ulid |= b[10];
490
+
491
+ ulid <<= 8;
492
+ ulid |= b[11];
493
+
494
+ ulid <<= 8;
495
+ ulid |= b[12];
496
+
497
+ ulid <<= 8;
498
+ ulid |= b[13];
499
+
500
+ ulid <<= 8;
501
+ ulid |= b[14];
502
+
503
+ ulid <<= 8;
504
+ ulid |= b[15];
505
+ }
506
+
507
+ /**
508
+ * Unmarshal will create a new ULID by unmarshaling the passed byte vector.
509
+ * */
510
+ inline ULID UnmarshalBinary(const std::vector<uint8_t>& b) {
511
+ ULID ulid;
512
+ UnmarshalBinaryFrom(b.data(), ulid);
513
+ return ulid;
514
+ }
515
+
516
+ /**
517
+ * CompareULIDs will compare two ULIDs.
518
+ * returns:
519
+ * -1 if ulid1 is Lexicographically before ulid2
520
+ * 1 if ulid1 is Lexicographically after ulid2
521
+ * 0 if ulid1 is same as ulid2
522
+ * */
523
+ inline int CompareULIDs(const ULID& ulid1, const ULID& ulid2) {
524
+ return -2 * (ulid1 < ulid2) - 1 * (ulid1 == ulid2) + 1;
525
+ }
526
+
527
+ /**
528
+ * Time will extract the timestamp used to generate a ULID
529
+ * */
530
+ inline std::chrono::time_point<std::chrono::system_clock> Time(const ULID& ulid) {
531
+ int64_t ans = 0;
532
+
533
+ ans |= static_cast<uint8_t>(ulid >> 120);
534
+
535
+ ans <<= 8;
536
+ ans |= static_cast<uint8_t>(ulid >> 112);
537
+
538
+ ans <<= 8;
539
+ ans |= static_cast<uint8_t>(ulid >> 104);
540
+
541
+ ans <<= 8;
542
+ ans |= static_cast<uint8_t>(ulid >> 96);
543
+
544
+ ans <<= 8;
545
+ ans |= static_cast<uint8_t>(ulid >> 88);
546
+
547
+ ans <<= 8;
548
+ ans |= static_cast<uint8_t>(ulid >> 80);
549
+
550
+ return std::chrono::time_point<std::chrono::system_clock>(std::chrono::milliseconds{ans});
551
+ }
552
+
553
+ }; // namespace ulid
554
+
555
+ #endif // ULID_UINT128_HH
@@ -0,0 +1,94 @@
1
+ #include "ulid_wrapper.h"
2
+ #include "ulid.hh"
3
+
4
+ /**
5
+ * Generate a new text ULID and write it to the provided buffer.
6
+ * The buffer is NOT null-terminated.
7
+ */
8
+ void _cpp_ulid(char dst[26]) {
9
+ ulid::ULID ulid;
10
+ ulid::EncodeTimeSystemClockNow(ulid);
11
+ ulid::EncodeEntropyRand(ulid);
12
+ ulid::MarshalTo(ulid, dst);
13
+ }
14
+
15
+ /**
16
+ * Generate a new binary ULID and write it to the provided buffer.
17
+ */
18
+ void _cpp_ulid_bytes(uint8_t dst[16]) {
19
+ ulid::ULID ulid;
20
+ ulid::EncodeTimeSystemClockNow(ulid);
21
+ ulid::EncodeEntropyRand(ulid);
22
+ ulid::MarshalBinaryTo(ulid, dst);
23
+ }
24
+
25
+ /**
26
+ * Generate a new text ULID at the provided epoch time and write it to the provided buffer.
27
+ * The buffer is NOT null-terminated.
28
+ */
29
+ void _cpp_ulid_at_time(double epoch_time, char dst[26]) {
30
+ ulid::ULID ulid;
31
+ ulid::EncodeTimestamp(static_cast<int64_t>(epoch_time*1000), ulid);
32
+ ulid::EncodeEntropyRand(ulid);
33
+ ulid::MarshalTo(ulid, dst);
34
+ }
35
+
36
+ /**
37
+ * Generate a new binary ULID at the provided epoch time and write it to the provided buffer.
38
+ */
39
+ void _cpp_ulid_at_time_bytes(double epoch_time, uint8_t dst[16]) {
40
+ ulid::ULID ulid;
41
+ ulid::EncodeTimestamp(static_cast<int64_t>(epoch_time*1000), ulid);
42
+ ulid::EncodeEntropyRand(ulid);
43
+ ulid::MarshalBinaryTo(ulid, dst);
44
+ }
45
+
46
+ /**
47
+ * Convert a text ULID to a binary ULID.
48
+ * The buffer passed in must contain at least 26 bytes.
49
+ * Invalid data will result in undefined behavior.
50
+ */
51
+ void _cpp_ulid_to_bytes(const char * ulid_string, uint8_t dst[16]) {
52
+ ulid::ULID ulid;
53
+ ulid::UnmarshalFrom(ulid_string, ulid);
54
+ ulid::MarshalBinaryTo(ulid, dst);
55
+ }
56
+
57
+ /**
58
+ * Convert a binary ULID to a text ULID.
59
+ * The buffer passed in must contain at least 16 bytes.
60
+ * The output buffer will NOT be null-terminated.
61
+ */
62
+ void _cpp_bytes_to_ulid(const uint8_t b[16], char dst[26]) {
63
+ ulid::ULID ulid;
64
+ ulid::UnmarshalBinaryFrom(b, ulid);
65
+ ulid::MarshalTo(ulid, dst);
66
+ }
67
+
68
+ /**
69
+ * Convert a buffer of exactly 16 bytes to 32 hex characters.
70
+ * The output buffer will NOT be null-terminated.
71
+ */
72
+ void _cpp_hexlify_16(const uint8_t b[16], char dst[32]) {
73
+ static const char hexdigits[17] = "0123456789abcdef";
74
+ int in_index, out_index;
75
+ for (in_index = out_index = 0; in_index < 16; in_index++) {
76
+ uint8_t c = b[in_index];
77
+ dst[out_index++] = hexdigits[c >> 4];
78
+ dst[out_index++] = hexdigits[c & 0x0f];
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Interpret the first 6 bytes of a binary ULID as a timestamp.
84
+ */
85
+ uint64_t _cpp_bytes_to_timestamp(const uint8_t b[16]) {
86
+ uint64_t timestamp = 0;
87
+ timestamp |= static_cast<uint64_t>(b[0]) << 40;
88
+ timestamp |= static_cast<uint64_t>(b[1]) << 32;
89
+ timestamp |= static_cast<uint64_t>(b[2]) << 24;
90
+ timestamp |= static_cast<uint64_t>(b[3]) << 16;
91
+ timestamp |= static_cast<uint64_t>(b[4]) << 8;
92
+ timestamp |= static_cast<uint64_t>(b[5]);
93
+ return timestamp;
94
+ }
@@ -0,0 +1,13 @@
1
+ #ifndef ULID_WRAPPER_H
2
+ #define ULID_WRAPPER_H
3
+ #include <stdint.h>
4
+
5
+ void _cpp_ulid(char dst[26]);
6
+ void _cpp_ulid_bytes(uint8_t dst[16]);
7
+ void _cpp_ulid_at_time(double epoch_time, char dst[26]);
8
+ void _cpp_ulid_at_time_bytes(double epoch_time, uint8_t dst[16]);
9
+ void _cpp_ulid_to_bytes(const char * ulid_string, uint8_t dst[16]);
10
+ void _cpp_bytes_to_ulid(const uint8_t b[16], char dst[26]);
11
+ void _cpp_hexlify_16(const uint8_t b[16], char dst[32]);
12
+ uint64_t _cpp_bytes_to_timestamp(const uint8_t b[16]);
13
+ #endif
@@ -0,0 +1,22 @@
1
+
2
+ MIT License
3
+
4
+ Copyright (c) 2022 J. Nick Koston
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.