ulid-transform 1.0.1__cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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.