1use std::{
2 io::Read,
3 sync::atomic::{AtomicUsize, Ordering},
4};
5
6use crate::date::OffsetDateTime;
7
8static RAND_SEED: AtomicUsize = AtomicUsize::new(2100);
12
13pub(crate) fn random_number() -> usize {
15 let mut x = RAND_SEED.fetch_add(21, Ordering::SeqCst);
16 #[cfg(target_pointer_width = "64")]
17 {
18 x ^= x << 21;
19 x ^= x >> 35;
20 x ^= x << 4;
21 x
22 }
23
24 #[cfg(target_pointer_width = "32")]
25 {
26 x ^= x << 13;
27 x ^= x >> 17;
28 x ^= x << 5;
29 x
30 }
31}
32
33pub(crate) fn random_character_string_32() -> String {
35 const MAX_CHARS: usize = 32;
36 let mut final_string = String::with_capacity(MAX_CHARS);
37 let mut char_pos = 0;
38
39 'outer: while char_pos < MAX_CHARS {
40 let rand = format!("{}", crate::utils::random_number());
41 for ch in rand.chars() {
42 if char_pos < MAX_CHARS {
43 final_string.push(u8_to_char(ch.to_digit(10).unwrap() as u8));
44 char_pos += 1;
45 } else {
46 break 'outer;
47 }
48 }
49 }
50
51 final_string
52}
53
54#[cfg(target_family = "wasm")]
56pub(crate) fn to_pdf_time_stamp_metadata(_date: &OffsetDateTime) -> String {
57 "D:19700101000000+00'00'".to_string()
58}
59
60#[cfg(not(target_family = "wasm"))]
61pub(crate) fn to_pdf_time_stamp_metadata(date: &OffsetDateTime) -> String {
62 format!(
63 "D:{:04}{:02}{:02}{:02}{:02}{:02}+00'00'",
64 date.year(),
65 u8::from(date.month()),
66 date.day(),
67 date.hour(),
68 date.minute(),
69 date.second(),
70 )
71}
72
73#[cfg(target_family = "wasm")]
74pub(crate) fn to_pdf_xmp_date(_date: &OffsetDateTime) -> String {
75 "D:1970-01-01T00:00:00+00'00'".to_string()
76}
77
78#[cfg(not(target_family = "wasm"))]
80pub(crate) fn to_pdf_xmp_date(date: &OffsetDateTime) -> String {
81 format!(
84 "D:{:04}-{:02}-{:02}T{:02}:{:02}:{:02}+00'00'",
85 date.year(),
86 date.month(),
87 date.day(),
88 date.hour(),
89 date.minute(),
90 date.second(),
91 )
92}
93
94#[inline(always)]
96fn u8_to_char(input: u8) -> char {
97 (b'A' + input) as char
98}
99
100#[allow(dead_code)]
101pub(crate) fn compress(bytes: &[u8]) -> Vec<u8> {
102 use std::io::prelude::*;
103
104 use flate2::{write::GzEncoder, Compression};
105 let mut encoder = GzEncoder::new(Vec::new(), Compression::best());
106 let _ = encoder.write_all(bytes);
107 encoder.finish().unwrap_or_default()
108}
109
110pub(crate) fn uncompress(bytes: &[u8]) -> Vec<u8> {
111 use flate2::read::GzDecoder;
112 let mut gz = GzDecoder::new(bytes);
113 let mut s = Vec::<u8>::new();
114 let _ = gz.read_to_end(&mut s);
115 s
116}