1use crate::base64;
2
3const VLQ_BASE_SHIFT: usize = 5;
16
17const VLQ_BASE: usize = 1 << VLQ_BASE_SHIFT;
19
20const VLQ_BASE_MASK: usize = VLQ_BASE - 1;
22
23const VLQ_CONTINUATION_BIT: usize = VLQ_BASE;
25
26fn to_vlq_signed(value: i32) -> i32 {
27 if value < 0 {
28 (-value << 1) + 1
29 } else {
30 value << 1
31 }
32}
33
34pub fn base64vlq_encode(value: i32) -> String {
35 let mut encoded = String::new();
36 let mut digit: i32;
37
38 let mut vlq = to_vlq_signed(value);
39
40 loop {
41 digit = ((vlq as usize) & VLQ_BASE_MASK) as i32;
42 vlq = ((vlq as usize) >> VLQ_BASE_SHIFT) as i32;
43
44 if vlq > 0 {
45 digit = ((digit as usize) | VLQ_CONTINUATION_BIT) as i32;
48 }
49 encoded.push(base64::encode(digit).unwrap());
50 if vlq <= 0 {
51 break;
52 }
53 }
54 encoded
55}
56
57#[test]
58fn test_to_vlq_signed() {
59 assert_eq!(to_vlq_signed(1), 0b10);
60 assert_eq!(to_vlq_signed(-1), 0b11);
61 assert_eq!(to_vlq_signed(2), 0b100);
62 assert_eq!(to_vlq_signed(-2), 0b101)
63}
64
65#[test]
66fn test_base64vlq_encode() {
67 let vlqs = [
68 (-255, "/P"),
69 (-254, "9P"),
70 (-253, "7P"),
71 (-252, "5P"),
72 (-251, "3P"),
73 (-250, "1P"),
74 (-249, "zP"),
75 (-248, "xP"),
76 (-247, "vP"),
77 (-246, "tP"),
78 (-245, "rP"),
79 (-244, "pP"),
80 (-243, "nP"),
81 (-242, "lP"),
82 (-241, "jP"),
83 (-240, "hP"),
84 (-239, "/O"),
85 (-238, "9O"),
86 (-237, "7O"),
87 (-236, "5O"),
88 (-235, "3O"),
89 (-234, "1O"),
90 (-233, "zO"),
91 (-232, "xO"),
92 (-231, "vO"),
93 (-230, "tO"),
94 (-229, "rO"),
95 (-228, "pO"),
96 (-227, "nO"),
97 (-226, "lO"),
98 (-225, "jO"),
99 (-224, "hO"),
100 (-223, "/N"),
101 (-222, "9N"),
102 (-221, "7N"),
103 (-220, "5N"),
104 (-219, "3N"),
105 (-218, "1N"),
106 (-217, "zN"),
107 (-216, "xN"),
108 (-215, "vN"),
109 (-214, "tN"),
110 (-213, "rN"),
111 (-212, "pN"),
112 (-211, "nN"),
113 (-210, "lN"),
114 (-209, "jN"),
115 (-208, "hN"),
116 (-207, "/M"),
117 (-206, "9M"),
118 (-205, "7M"),
119 (-204, "5M"),
120 (-203, "3M"),
121 (-202, "1M"),
122 (-201, "zM"),
123 (-200, "xM"),
124 (-199, "vM"),
125 (-198, "tM"),
126 (-197, "rM"),
127 (-196, "pM"),
128 (-195, "nM"),
129 (-194, "lM"),
130 (-193, "jM"),
131 (-192, "hM"),
132 (-191, "/L"),
133 (-190, "9L"),
134 (-189, "7L"),
135 (-188, "5L"),
136 (-187, "3L"),
137 (-186, "1L"),
138 (-185, "zL"),
139 (-184, "xL"),
140 (-183, "vL"),
141 (-182, "tL"),
142 (-181, "rL"),
143 (-180, "pL"),
144 (-179, "nL"),
145 (-178, "lL"),
146 (-177, "jL"),
147 (-176, "hL"),
148 (-175, "/K"),
149 (-174, "9K"),
150 (-173, "7K"),
151 (-172, "5K"),
152 (-171, "3K"),
153 (-170, "1K"),
154 (-169, "zK"),
155 (-168, "xK"),
156 (-167, "vK"),
157 (-166, "tK"),
158 (-165, "rK"),
159 (-164, "pK"),
160 (-163, "nK"),
161 (-162, "lK"),
162 (-161, "jK"),
163 (-160, "hK"),
164 (-159, "/J"),
165 (-158, "9J"),
166 (-157, "7J"),
167 (-156, "5J"),
168 (-155, "3J"),
169 (-154, "1J"),
170 (-153, "zJ"),
171 (-152, "xJ"),
172 (-151, "vJ"),
173 (-150, "tJ"),
174 (-149, "rJ"),
175 (-148, "pJ"),
176 (-147, "nJ"),
177 (-146, "lJ"),
178 (-145, "jJ"),
179 (-144, "hJ"),
180 (-143, "/I"),
181 (-142, "9I"),
182 (-141, "7I"),
183 (-140, "5I"),
184 (-139, "3I"),
185 (-138, "1I"),
186 (-137, "zI"),
187 (-136, "xI"),
188 (-135, "vI"),
189 (-134, "tI"),
190 (-133, "rI"),
191 (-132, "pI"),
192 (-131, "nI"),
193 (-130, "lI"),
194 (-129, "jI"),
195 (-128, "hI"),
196 (-127, "/H"),
197 (-126, "9H"),
198 (-125, "7H"),
199 (-124, "5H"),
200 (-123, "3H"),
201 (-122, "1H"),
202 (-121, "zH"),
203 (-120, "xH"),
204 (-119, "vH"),
205 (-118, "tH"),
206 (-117, "rH"),
207 (-116, "pH"),
208 (-115, "nH"),
209 (-114, "lH"),
210 (-113, "jH"),
211 (-112, "hH"),
212 (-111, "/G"),
213 (-110, "9G"),
214 (-109, "7G"),
215 (-108, "5G"),
216 (-107, "3G"),
217 (-106, "1G"),
218 (-105, "zG"),
219 (-104, "xG"),
220 (-103, "vG"),
221 (-102, "tG"),
222 (-101, "rG"),
223 (-100, "pG"),
224 (-99, "nG"),
225 (-98, "lG"),
226 (-97, "jG"),
227 (-96, "hG"),
228 (-95, "/F"),
229 (-94, "9F"),
230 (-93, "7F"),
231 (-92, "5F"),
232 (-91, "3F"),
233 (-90, "1F"),
234 (-89, "zF"),
235 (-88, "xF"),
236 (-87, "vF"),
237 (-86, "tF"),
238 (-85, "rF"),
239 (-84, "pF"),
240 (-83, "nF"),
241 (-82, "lF"),
242 (-81, "jF"),
243 (-80, "hF"),
244 (-79, "/E"),
245 (-78, "9E"),
246 (-77, "7E"),
247 (-76, "5E"),
248 (-75, "3E"),
249 (-74, "1E"),
250 (-73, "zE"),
251 (-72, "xE"),
252 (-71, "vE"),
253 (-70, "tE"),
254 (-69, "rE"),
255 (-68, "pE"),
256 (-67, "nE"),
257 (-66, "lE"),
258 (-65, "jE"),
259 (-64, "hE"),
260 (-63, "/D"),
261 (-62, "9D"),
262 (-61, "7D"),
263 (-60, "5D"),
264 (-59, "3D"),
265 (-58, "1D"),
266 (-57, "zD"),
267 (-56, "xD"),
268 (-55, "vD"),
269 (-54, "tD"),
270 (-53, "rD"),
271 (-52, "pD"),
272 (-51, "nD"),
273 (-50, "lD"),
274 (-49, "jD"),
275 (-48, "hD"),
276 (-47, "/C"),
277 (-46, "9C"),
278 (-45, "7C"),
279 (-44, "5C"),
280 (-43, "3C"),
281 (-42, "1C"),
282 (-41, "zC"),
283 (-40, "xC"),
284 (-39, "vC"),
285 (-38, "tC"),
286 (-37, "rC"),
287 (-36, "pC"),
288 (-35, "nC"),
289 (-34, "lC"),
290 (-33, "jC"),
291 (-32, "hC"),
292 (-31, "/B"),
293 (-30, "9B"),
294 (-29, "7B"),
295 (-28, "5B"),
296 (-27, "3B"),
297 (-26, "1B"),
298 (-99, "nG"),
299 (-98, "lG"),
300 (-97, "jG"),
301 (-96, "hG"),
302 (-95, "/F"),
303 (-94, "9F"),
304 (-93, "7F"),
305 (-92, "5F"),
306 (-91, "3F"),
307 (-90, "1F"),
308 (-89, "zF"),
309 (-88, "xF"),
310 (-87, "vF"),
311 (-86, "tF"),
312 (-85, "rF"),
313 (-84, "pF"),
314 (-83, "nF"),
315 (-82, "lF"),
316 (-81, "jF"),
317 (-80, "hF"),
318 (-79, "/E"),
319 (-78, "9E"),
320 (-77, "7E"),
321 (-76, "5E"),
322 (-75, "3E"),
323 (-74, "1E"),
324 (-73, "zE"),
325 (-72, "xE"),
326 (-71, "vE"),
327 (-70, "tE"),
328 (-69, "rE"),
329 (-68, "pE"),
330 (-67, "nE"),
331 (-66, "lE"),
332 (-65, "jE"),
333 (-64, "hE"),
334 (-63, "/D"),
335 (-62, "9D"),
336 (-61, "7D"),
337 (-60, "5D"),
338 (-59, "3D"),
339 (-58, "1D"),
340 (-57, "zD"),
341 (-56, "xD"),
342 (-55, "vD"),
343 (-54, "tD"),
344 (-53, "rD"),
345 (-52, "pD"),
346 (-51, "nD"),
347 (-50, "lD"),
348 (-49, "jD"),
349 (-48, "hD"),
350 (-47, "/C"),
351 (-46, "9C"),
352 (-45, "7C"),
353 (-44, "5C"),
354 (-43, "3C"),
355 (-42, "1C"),
356 (-41, "zC"),
357 (-40, "xC"),
358 (-39, "vC"),
359 (-38, "tC"),
360 (-37, "rC"),
361 (-36, "pC"),
362 (-35, "nC"),
363 (-34, "lC"),
364 (-33, "jC"),
365 (-32, "hC"),
366 (-31, "/B"),
367 (-30, "9B"),
368 (-29, "7B"),
369 (-28, "5B"),
370 (-27, "3B"),
371 (-26, "1B"),
372 (-25, "zB"),
373 (-24, "xB"),
374 (-23, "vB"),
375 (-22, "tB"),
376 (-21, "rB"),
377 (-20, "pB"),
378 (-19, "nB"),
379 (-18, "lB"),
380 (-17, "jB"),
381 (-16, "hB"),
382 (-25, "zB"),
383 (-24, "xB"),
384 (-23, "vB"),
385 (-22, "tB"),
386 (-21, "rB"),
387 (-20, "pB"),
388 (-19, "nB"),
389 (-18, "lB"),
390 (-17, "jB"),
391 (-16, "hB"),
392 (-15, "f"),
393 (-14, "d"),
394 (-13, "b"),
395 (-12, "Z"),
396 (-11, "X"),
397 (-10, "V"),
398 (-9, "T"),
399 (-8, "R"),
400 (-7, "P"),
401 (-6, "N"),
402 (-5, "L"),
403 (-4, "J"),
404 (-3, "H"),
405 (-2, "F"),
406 (-1, "D"),
407 (0, "A"),
408 (1, "C"),
409 (2, "E"),
410 (3, "G"),
411 (4, "I"),
412 (5, "K"),
413 (6, "M"),
414 (7, "O"),
415 (8, "Q"),
416 (9, "S"),
417 (10, "U"),
418 (11, "W"),
419 (12, "Y"),
420 (13, "a"),
421 (14, "c"),
422 (15, "e"),
423 (16, "gB"),
424 (17, "iB"),
425 (18, "kB"),
426 (19, "mB"),
427 (20, "oB"),
428 (21, "qB"),
429 (22, "sB"),
430 (23, "uB"),
431 (24, "wB"),
432 (25, "yB"),
433 (26, "0B"),
434 (27, "2B"),
435 (28, "4B"),
436 (29, "6B"),
437 (30, "8B"),
438 (31, "+B"),
439 (32, "gC"),
440 (33, "iC"),
441 (34, "kC"),
442 (35, "mC"),
443 (36, "oC"),
444 (37, "qC"),
445 (38, "sC"),
446 (39, "uC"),
447 (40, "wC"),
448 (41, "yC"),
449 (42, "0C"),
450 (43, "2C"),
451 (44, "4C"),
452 (45, "6C"),
453 (46, "8C"),
454 (47, "+C"),
455 (48, "gD"),
456 (49, "iD"),
457 (50, "kD"),
458 (51, "mD"),
459 (52, "oD"),
460 (53, "qD"),
461 (54, "sD"),
462 (55, "uD"),
463 (56, "wD"),
464 (57, "yD"),
465 (58, "0D"),
466 (59, "2D"),
467 (60, "4D"),
468 (61, "6D"),
469 (62, "8D"),
470 (63, "+D"),
471 (64, "gE"),
472 (65, "iE"),
473 (66, "kE"),
474 (67, "mE"),
475 (68, "oE"),
476 (69, "qE"),
477 (70, "sE"),
478 (71, "uE"),
479 (72, "wE"),
480 (73, "yE"),
481 (74, "0E"),
482 (75, "2E"),
483 (76, "4E"),
484 (77, "6E"),
485 (78, "8E"),
486 (79, "+E"),
487 (80, "gF"),
488 (81, "iF"),
489 (82, "kF"),
490 (83, "mF"),
491 (84, "oF"),
492 (85, "qF"),
493 (86, "sF"),
494 (87, "uF"),
495 (88, "wF"),
496 (89, "yF"),
497 (90, "0F"),
498 (91, "2F"),
499 (92, "4F"),
500 (93, "6F"),
501 (94, "8F"),
502 (95, "+F"),
503 (96, "gG"),
504 (97, "iG"),
505 (98, "kG"),
506 (99, "mG"),
507 (100, "oG"),
508 (101, "qG"),
509 (102, "sG"),
510 (103, "uG"),
511 (104, "wG"),
512 (105, "yG"),
513 (106, "0G"),
514 (107, "2G"),
515 (108, "4G"),
516 (109, "6G"),
517 (110, "8G"),
518 (111, "+G"),
519 (112, "gH"),
520 (113, "iH"),
521 (114, "kH"),
522 (115, "mH"),
523 (116, "oH"),
524 (117, "qH"),
525 (118, "sH"),
526 (119, "uH"),
527 (120, "wH"),
528 (121, "yH"),
529 (122, "0H"),
530 (123, "2H"),
531 (124, "4H"),
532 (125, "6H"),
533 (126, "8H"),
534 (127, "+H"),
535 (128, "gI"),
536 (129, "iI"),
537 (130, "kI"),
538 (131, "mI"),
539 (132, "oI"),
540 (133, "qI"),
541 (134, "sI"),
542 (135, "uI"),
543 (136, "wI"),
544 (137, "yI"),
545 (138, "0I"),
546 (139, "2I"),
547 (140, "4I"),
548 (141, "6I"),
549 (142, "8I"),
550 (143, "+I"),
551 (144, "gJ"),
552 (145, "iJ"),
553 (146, "kJ"),
554 (147, "mJ"),
555 (148, "oJ"),
556 (149, "qJ"),
557 (150, "sJ"),
558 (151, "uJ"),
559 (152, "wJ"),
560 (157, "6J"),
561 (158, "8J"),
562 (159, "+J"),
563 (160, "gK"),
564 (161, "iK"),
565 (162, "kK"),
566 (163, "mK"),
567 (164, "oK"),
568 (165, "qK"),
569 (166, "sK"),
570 (167, "uK"),
571 (168, "wK"),
572 (169, "yK"),
573 (170, "0K"),
574 (171, "2K"),
575 (172, "4K"),
576 (173, "6K"),
577 (174, "8K"),
578 (175, "+K"),
579 (176, "gL"),
580 (177, "iL"),
581 (178, "kL"),
582 (179, "mL"),
583 (180, "oL"),
584 (181, "qL"),
585 (182, "sL"),
586 (183, "uL"),
587 (184, "wL"),
588 (185, "yL"),
589 (186, "0L"),
590 (187, "2L"),
591 (188, "4L"),
592 (189, "6L"),
593 (190, "8L"),
594 (191, "+L"),
595 (192, "gM"),
596 (193, "iM"),
597 (194, "kM"),
598 (195, "mM"),
599 (196, "oM"),
600 (197, "qM"),
601 (198, "sM"),
602 (199, "uM"),
603 (200, "wM"),
604 (201, "yM"),
605 (202, "0M"),
606 (203, "2M"),
607 (204, "4M"),
608 (205, "6M"),
609 (206, "8M"),
610 (207, "+M"),
611 (208, "gN"),
612 (209, "iN"),
613 (210, "kN"),
614 (211, "mN"),
615 (212, "oN"),
616 (213, "qN"),
617 (214, "sN"),
618 (215, "uN"),
619 (216, "wN"),
620 (217, "yN"),
621 (218, "0N"),
622 (219, "2N"),
623 (220, "4N"),
624 (221, "6N"),
625 (222, "8N"),
626 (223, "+N"),
627 (224, "gO"),
628 (225, "iO"),
629 (226, "kO"),
630 (227, "mO"),
631 (228, "oO"),
632 (229, "qO"),
633 (230, "sO"),
634 (231, "uO"),
635 (232, "wO"),
636 (233, "yO"),
637 (234, "0O"),
638 (235, "2O"),
639 (236, "4O"),
640 (237, "6O"),
641 (238, "8O"),
642 (239, "+O"),
643 (240, "gP"),
644 (241, "iP"),
645 (242, "kP"),
646 (243, "mP"),
647 (244, "oP"),
648 (245, "qP"),
649 (246, "sP"),
650 (247, "uP"),
651 (248, "wP"),
652 (249, "yP"),
653 (250, "0P"),
654 (251, "2P"),
655 (252, "4P"),
656 (253, "6P"),
657 (254, "8P"),
658 (255, "+P"),
659 ];
660
661 for vlq in vlqs {
662 assert_eq!(base64vlq_encode(vlq.0), vlq.1.to_string());
663 }
664}