mirror of
https://github.com/storytold/cadcraft.git
synced 2026-11-15 10:23:43 -06:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91b14c83cf |
Generated
+16
@@ -700,6 +700,7 @@ dependencies = [
|
||||
"cadcraft-render",
|
||||
"craft-docpath",
|
||||
"craft-dxf",
|
||||
"craft-mime",
|
||||
"libc",
|
||||
"log",
|
||||
"rstar",
|
||||
@@ -1131,6 +1132,11 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "craft-codepage"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=451a390542fbde0519cbb8ade3a3325cf02d97be#451a390542fbde0519cbb8ade3a3325cf02d97be"
|
||||
|
||||
[[package]]
|
||||
name = "craft-docpath"
|
||||
version = "0.1.0"
|
||||
@@ -1183,6 +1189,16 @@ dependencies = [
|
||||
"writeable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "craft-mime"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=451a390542fbde0519cbb8ade3a3325cf02d97be#451a390542fbde0519cbb8ade3a3325cf02d97be"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"craft-codepage",
|
||||
"encoding_rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "craft-pdf"
|
||||
version = "0.1.0"
|
||||
|
||||
@@ -16,6 +16,7 @@ cadcraft-geom = { path = "crates/geom" }
|
||||
# DXF tags: the shared reader and writer (moved from crates/dxf; craft-libs#791).
|
||||
craft-dxf = { git = "https://github.com/storytold/craft-libs", rev = "006e4df225fca57e95ead0fb1f91920900798a99" }
|
||||
craft-dwg = { git = "https://github.com/storytold/craft-libs", rev = "7bb6c90076a0177d01cc4c482e7fd8dc9f31a8bf" }
|
||||
craft-mime = { git = "https://github.com/storytold/craft-libs", rev = "451a390542fbde0519cbb8ade3a3325cf02d97be" }
|
||||
cadcraft-color = { path = "crates/color" }
|
||||
cadcraft-doc = { path = "crates/doc" }
|
||||
cadcraft-constraints = { path = "crates/constraints" }
|
||||
|
||||
@@ -12,6 +12,7 @@ workspace = true
|
||||
cadcraft-geom = { workspace = true }
|
||||
cadcraft-color = { workspace = true }
|
||||
cadcraft-doc = { workspace = true }
|
||||
craft-mime = { workspace = true }
|
||||
craft-dxf = { workspace = true }
|
||||
cadcraft-constraints = { workspace = true }
|
||||
cadcraft-fonts = { workspace = true }
|
||||
|
||||
@@ -1020,46 +1020,14 @@ fn run_saveas_reporting(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
save_reporting(s, p, run_saveas, asked)
|
||||
}
|
||||
|
||||
const B64: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/// Encode bytes with the standard padded Base64 alphabet.
|
||||
pub fn base64_encode(data: &[u8]) -> String {
|
||||
let mut out = String::with_capacity(data.len().div_ceil(3) * 4);
|
||||
for chunk in data.chunks(3) {
|
||||
let b = [chunk.first().copied().unwrap_or(0), chunk.get(1).copied().unwrap_or(0), chunk.get(2).copied().unwrap_or(0)];
|
||||
let n = (u32::from(b[0]) << 16) | (u32::from(b[1]) << 8) | u32::from(b[2]);
|
||||
for i in 0..4 {
|
||||
if i <= chunk.len() {
|
||||
out.push(char::from(B64[((n >> (18 - 6 * i)) & 63) as usize]));
|
||||
} else {
|
||||
out.push('=');
|
||||
}
|
||||
}
|
||||
}
|
||||
out
|
||||
craft_mime::base64::STANDARD.encode(data)
|
||||
}
|
||||
|
||||
/// Decode the legacy file/control Base64 form, retaining its permissive alphabet and padding.
|
||||
pub fn base64_decode(s: &str) -> Option<Vec<u8>> {
|
||||
let mut out = Vec::with_capacity(s.len() * 3 / 4);
|
||||
let mut buf = 0u32;
|
||||
let mut bits = 0;
|
||||
for c in s.bytes() {
|
||||
let v = match c {
|
||||
b'A'..=b'Z' => c - b'A',
|
||||
b'a'..=b'z' => c - b'a' + 26,
|
||||
b'0'..=b'9' => c - b'0' + 52,
|
||||
b'+' | b'-' => 62,
|
||||
b'/' | b'_' => 63,
|
||||
b'=' | b'\n' | b'\r' | b' ' => continue,
|
||||
_ => return None,
|
||||
};
|
||||
buf = (buf << 6) | u32::from(v);
|
||||
bits += 6;
|
||||
if bits >= 8 {
|
||||
bits -= 8;
|
||||
out.push(((buf >> bits) & 0xff) as u8);
|
||||
}
|
||||
}
|
||||
Some(out)
|
||||
craft_mime::base64_compat::decode(s).ok()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//! File and automation inputs retain CADCraft's accepted Base64 forms.
|
||||
use cadcraft_engine::cmd::file::{base64_decode, base64_encode};
|
||||
|
||||
#[test]
|
||||
fn legacy_inputs_and_standard_outputs_survive_the_shared_cutover() {
|
||||
for bytes in [&b""[..], b"f", b"fo", b"foo", b"foobar", &[0, 255, 127]] {
|
||||
assert_eq!(base64_decode(&base64_encode(bytes)).as_deref(), Some(bytes));
|
||||
}
|
||||
assert_eq!(base64_decode("+_8=").as_deref(), Some(&[251, 255][..]));
|
||||
assert_eq!(base64_decode("Z=m 9\nv\r").as_deref(), Some(&b"foo"[..]));
|
||||
assert_eq!(base64_decode("A").as_deref(), Some(&b""[..]));
|
||||
assert!(base64_decode("Zm9v\t").is_none());
|
||||
assert!(base64_decode("Zm9v!").is_none());
|
||||
}
|
||||
Reference in New Issue
Block a user