1pub use shank_parse_macro::shank_parse;
2
3#[doc(hidden)]
4pub mod __private {
5 pub use solana_sdk::instruction::{AccountMeta, Instruction};
6 pub use solana_sdk::pubkey::Pubkey;
7
8 use base64::Engine;
9
10 pub fn base64_decode(input: &str) -> Result<Vec<u8>, base64::DecodeError> {
11 base64::engine::general_purpose::STANDARD.decode(input)
12 }
13
14 pub fn base64_encode(data: &[u8]) -> String {
15 base64::engine::general_purpose::STANDARD.encode(data)
16 }
17
18 pub fn read_u8(data: &[u8], offset: &mut usize) -> Result<u8, std::io::Error> {
21 if *offset >= data.len() {
22 return Err(std::io::Error::new(
23 std::io::ErrorKind::UnexpectedEof,
24 "unexpected eof",
25 ));
26 }
27 let val = data[*offset];
28 *offset += 1;
29 Ok(val)
30 }
31
32 pub fn read_bool(data: &[u8], offset: &mut usize) -> Result<bool, std::io::Error> {
33 Ok(read_u8(data, offset)? != 0)
34 }
35
36 macro_rules! impl_read_int {
37 ($fname:ident, $ty:ty, $size:expr) => {
38 pub fn $fname(data: &[u8], offset: &mut usize) -> Result<$ty, std::io::Error> {
39 let end = *offset + $size;
40 if end > data.len() {
41 return Err(std::io::Error::new(
42 std::io::ErrorKind::UnexpectedEof,
43 "unexpected eof",
44 ));
45 }
46 let mut bytes = [0u8; $size];
47 bytes.copy_from_slice(&data[*offset..end]);
48 *offset = end;
49 Ok(<$ty>::from_le_bytes(bytes))
50 }
51 };
52 }
53
54 impl_read_int!(read_u16, u16, 2);
55 impl_read_int!(read_u32, u32, 4);
56 impl_read_int!(read_u64, u64, 8);
57 impl_read_int!(read_u128, u128, 16);
58 impl_read_int!(read_i8, i8, 1);
59 impl_read_int!(read_i16, i16, 2);
60 impl_read_int!(read_i32, i32, 4);
61 impl_read_int!(read_i64, i64, 8);
62 impl_read_int!(read_i128, i128, 16);
63
64 pub fn read_bytes<const N: usize>(
65 data: &[u8],
66 offset: &mut usize,
67 ) -> Result<[u8; N], std::io::Error> {
68 let end = *offset + N;
69 if end > data.len() {
70 return Err(std::io::Error::new(
71 std::io::ErrorKind::UnexpectedEof,
72 "unexpected eof",
73 ));
74 }
75 let mut bytes = [0u8; N];
76 bytes.copy_from_slice(&data[*offset..end]);
77 *offset = end;
78 Ok(bytes)
79 }
80
81 pub fn write_u8(data: &mut Vec<u8>, val: u8) {
84 data.push(val);
85 }
86
87 pub fn write_bool(data: &mut Vec<u8>, val: bool) {
88 data.push(val as u8);
89 }
90
91 macro_rules! impl_write_int {
92 ($fname:ident, $ty:ty) => {
93 pub fn $fname(data: &mut Vec<u8>, val: $ty) {
94 data.extend_from_slice(&val.to_le_bytes());
95 }
96 };
97 }
98
99 impl_write_int!(write_u16, u16);
100 impl_write_int!(write_u32, u32);
101 impl_write_int!(write_u64, u64);
102 impl_write_int!(write_u128, u128);
103 impl_write_int!(write_i8, i8);
104 impl_write_int!(write_i16, i16);
105 impl_write_int!(write_i32, i32);
106 impl_write_int!(write_i64, i64);
107 impl_write_int!(write_i128, i128);
108
109 pub fn write_bytes(data: &mut Vec<u8>, val: &[u8]) {
110 data.extend_from_slice(val);
111 }
112}