1use crate::{
2 aa_byte_stream::{ArchiveCompressionAlgorithm, ArchiveFlags, ByteStream, ByteStreamUpstream},
3 aa_entry_blob::NamedBlobEntry,
4 ffi, util, CompressionError, Result,
5};
6use std::ffi::{c_void, CStr};
7use std::ptr::{null, null_mut, NonNull};
8
9#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
11#[repr(u32)]
12pub enum AeaProfile {
13 HkdfSha256HmacNoneEcdsaP256 = 0,
15 HkdfSha256AesctrHmacSymmetricNone = 1,
17 HkdfSha256AesctrHmacSymmetricEcdsaP256 = 2,
19 HkdfSha256AesctrHmacEcdheP256None = 3,
21 HkdfSha256AesctrHmacEcdheP256EcdsaP256 = 4,
23 HkdfSha256AesctrHmacScryptNone = 5,
25}
26
27impl AeaProfile {
28 const fn from_raw(raw: u32) -> Option<Self> {
29 match raw {
30 x if x == Self::HkdfSha256HmacNoneEcdsaP256 as u32 => {
31 Some(Self::HkdfSha256HmacNoneEcdsaP256)
32 }
33 x if x == Self::HkdfSha256AesctrHmacSymmetricNone as u32 => {
34 Some(Self::HkdfSha256AesctrHmacSymmetricNone)
35 }
36 x if x == Self::HkdfSha256AesctrHmacSymmetricEcdsaP256 as u32 => {
37 Some(Self::HkdfSha256AesctrHmacSymmetricEcdsaP256)
38 }
39 x if x == Self::HkdfSha256AesctrHmacEcdheP256None as u32 => {
40 Some(Self::HkdfSha256AesctrHmacEcdheP256None)
41 }
42 x if x == Self::HkdfSha256AesctrHmacEcdheP256EcdsaP256 as u32 => {
43 Some(Self::HkdfSha256AesctrHmacEcdheP256EcdsaP256)
44 }
45 x if x == Self::HkdfSha256AesctrHmacScryptNone as u32 => {
46 Some(Self::HkdfSha256AesctrHmacScryptNone)
47 }
48 _ => None,
49 }
50 }
51
52 pub const fn raw(self) -> u32 {
54 self as u32
55 }
56
57 pub const fn ciphersuite(self) -> AeaCiphersuite {
59 match self {
60 Self::HkdfSha256HmacNoneEcdsaP256 => AeaCiphersuite::HkdfSha256Hmac,
61 Self::HkdfSha256AesctrHmacSymmetricNone
62 | Self::HkdfSha256AesctrHmacSymmetricEcdsaP256
63 | Self::HkdfSha256AesctrHmacEcdheP256None
64 | Self::HkdfSha256AesctrHmacEcdheP256EcdsaP256
65 | Self::HkdfSha256AesctrHmacScryptNone => AeaCiphersuite::HkdfSha256AesctrHmac,
66 }
67 }
68
69 pub const fn signature_mode(self) -> AeaSignatureMode {
71 match self {
72 Self::HkdfSha256HmacNoneEcdsaP256
73 | Self::HkdfSha256AesctrHmacSymmetricEcdsaP256
74 | Self::HkdfSha256AesctrHmacEcdheP256EcdsaP256 => AeaSignatureMode::EcdsaP256,
75 Self::HkdfSha256AesctrHmacSymmetricNone
76 | Self::HkdfSha256AesctrHmacEcdheP256None
77 | Self::HkdfSha256AesctrHmacScryptNone => AeaSignatureMode::None,
78 }
79 }
80
81 pub const fn encryption_mode(self) -> AeaEncryptionMode {
83 match self {
84 Self::HkdfSha256HmacNoneEcdsaP256 => AeaEncryptionMode::None,
85 Self::HkdfSha256AesctrHmacSymmetricNone
86 | Self::HkdfSha256AesctrHmacSymmetricEcdsaP256 => AeaEncryptionMode::Symmetric,
87 Self::HkdfSha256AesctrHmacEcdheP256None
88 | Self::HkdfSha256AesctrHmacEcdheP256EcdsaP256 => AeaEncryptionMode::EcdheP256,
89 Self::HkdfSha256AesctrHmacScryptNone => AeaEncryptionMode::Scrypt,
90 }
91 }
92}
93
94#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
96#[repr(u32)]
97pub enum AeaContextField {
98 Profile = 0,
100 PaddingSize = 1,
102 ChecksumMode = 2,
104 CompressionAlgorithm = 3,
106 CompressionBlockSize = 4,
108 AuthData = 5,
110 MainKey = 6,
112 SigningPublicKey = 7,
114 SigningPrivateKey = 8,
116 SymmetricKey = 9,
118 RecipientPublicKey = 10,
120 RecipientPrivateKey = 11,
122 SignatureEncryptionKey = 12,
124 RawSize = 13,
126 ContainerSize = 14,
128 BlocksPerCluster = 17,
130 ArchiveIdentifier = 18,
132 Password = 19,
134}
135
136impl AeaContextField {
137 pub const fn raw(self) -> u32 {
139 self as u32
140 }
141}
142
143#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
145#[repr(u32)]
146pub enum AeaContextFieldRepresentation {
147 Raw = 0,
149 X963 = 1,
151 Generate = 2,
153}
154
155impl AeaContextFieldRepresentation {
156 const fn raw(self) -> u32 {
157 self as u32
158 }
159}
160
161#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
163#[repr(u32)]
164pub enum AeaCiphersuite {
165 HkdfSha256Hmac = 0,
167 HkdfSha256AesctrHmac = 1,
169}
170
171#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
173#[repr(u32)]
174pub enum AeaSignatureMode {
175 None = 0,
177 EcdsaP256 = 1,
179}
180
181#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
183#[repr(u32)]
184pub enum AeaEncryptionMode {
185 None = 0,
187 Symmetric = 1,
189 EcdheP256 = 2,
191 Scrypt = 3,
193}
194
195#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
197#[repr(u32)]
198pub enum AeaChecksumMode {
199 None = 0,
201 MurmurHash64 = 1,
203 Sha256 = 2,
205}
206
207impl AeaChecksumMode {
208 const fn from_raw(raw: u32) -> Option<Self> {
209 match raw {
210 x if x == Self::None as u32 => Some(Self::None),
211 x if x == Self::MurmurHash64 as u32 => Some(Self::MurmurHash64),
212 x if x == Self::Sha256 as u32 => Some(Self::Sha256),
213 _ => None,
214 }
215 }
216
217 const fn raw(self) -> u32 {
218 self as u32
219 }
220}
221
222#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash)]
224pub struct AeaPadding;
225
226impl AeaPadding {
227 pub const NONE: u64 = 0;
229 pub const ADAPTIVE: u64 = 1;
231 pub const MIN_SIZE: u64 = 16;
233}
234
235#[derive(Debug)]
237pub struct AeaContext {
238 handle: NonNull<c_void>,
239}
240
241impl AeaContext {
242 fn from_handle(handle: *mut c_void, operation: &'static str) -> Result<Self> {
243 Ok(Self {
244 handle: util::nonnull_handle(handle, operation)?,
245 })
246 }
247
248 fn open_byte_stream(
249 handle: *mut c_void,
250 operation: &'static str,
251 upstream: ByteStream,
252 ) -> Result<ByteStream> {
253 ByteStream::from_handle_with_upstream(
254 handle,
255 operation,
256 Some(ByteStreamUpstream::Stream(Box::new(upstream))),
257 )
258 }
259
260 pub fn with_profile(profile: AeaProfile) -> Result<Self> {
262 let handle =
263 unsafe { ffi::aea::compression_rs_aea_context_create_with_profile(profile.raw()) };
264 Self::from_handle(handle, "AEAContextCreateWithProfile")
265 }
266
267 pub fn from_encrypted_stream(stream: &mut ByteStream) -> Result<Self> {
269 let handle = unsafe {
270 ffi::aea::compression_rs_aea_context_create_with_encrypted_stream(stream.as_ptr())
271 };
272 Self::from_handle(handle, "AEAContextCreateWithEncryptedStream")
273 }
274
275 pub(crate) fn as_ptr(&self) -> *mut c_void {
276 self.handle.as_ptr()
277 }
278
279 pub fn field_uint(&self, field: AeaContextField) -> Result<u64> {
281 let value = unsafe {
282 ffi::aea::compression_rs_aea_context_get_field_uint(self.as_ptr(), field.raw())
283 };
284 if value == u64::MAX {
285 Err(CompressionError::OperationFailed {
286 operation: "AEAContextGetFieldUInt",
287 code: -1,
288 })
289 } else {
290 Ok(value)
291 }
292 }
293
294 pub fn field_blob(
296 &self,
297 field: AeaContextField,
298 representation: AeaContextFieldRepresentation,
299 ) -> Result<Vec<u8>> {
300 let mut size = 0_usize;
301 let status = unsafe {
302 ffi::aea::compression_rs_aea_context_get_field_blob(
303 self.as_ptr(),
304 field.raw(),
305 representation.raw(),
306 0,
307 null_mut(),
308 &mut size,
309 )
310 };
311 util::status_result("AEAContextGetFieldBlob", status)?;
312
313 let mut data = vec![0_u8; size];
314 let status = unsafe {
315 ffi::aea::compression_rs_aea_context_get_field_blob(
316 self.as_ptr(),
317 field.raw(),
318 representation.raw(),
319 data.len(),
320 if data.is_empty() {
321 null_mut()
322 } else {
323 data.as_mut_ptr()
324 },
325 &mut size,
326 )
327 };
328 util::status_result("AEAContextGetFieldBlob", status)?;
329 Ok(data)
330 }
331
332 pub fn set_field_uint(&mut self, field: AeaContextField, value: u64) -> Result<()> {
334 let status = unsafe {
335 ffi::aea::compression_rs_aea_context_set_field_uint(self.as_ptr(), field.raw(), value)
336 };
337 util::status_result("AEAContextSetFieldUInt", status)
338 }
339
340 pub fn set_field_blob(
342 &mut self,
343 field: AeaContextField,
344 representation: AeaContextFieldRepresentation,
345 value: &[u8],
346 ) -> Result<()> {
347 let value_ptr = if value.is_empty() {
348 null()
349 } else {
350 value.as_ptr()
351 };
352 let status = unsafe {
353 ffi::aea::compression_rs_aea_context_set_field_blob(
354 self.as_ptr(),
355 field.raw(),
356 representation.raw(),
357 value_ptr,
358 value.len(),
359 )
360 };
361 util::status_result("AEAContextSetFieldBlob", status)
362 }
363
364 pub fn generate_field_blob(&mut self, field: AeaContextField) -> Result<()> {
366 let status = unsafe {
367 ffi::aea::compression_rs_aea_context_generate_field_blob(self.as_ptr(), field.raw())
368 };
369 util::status_result("AEAContextGenerateFieldBlob", status)
370 }
371
372 pub fn decrypt_attributes(&mut self) -> Result<()> {
374 let status =
375 unsafe { ffi::aea::compression_rs_aea_context_decrypt_attributes(self.as_ptr()) };
376 util::status_result("AEAContextDecryptAttributes", status)
377 }
378
379 pub fn profile(&self) -> Result<AeaProfile> {
381 let raw = u32::try_from(self.field_uint(AeaContextField::Profile)?).unwrap_or(u32::MAX);
382 AeaProfile::from_raw(raw).ok_or_else(|| CompressionError::OperationFailed {
383 operation: "AEAContextGetProfile",
384 code: i32::try_from(raw).unwrap_or(i32::MAX),
385 })
386 }
387
388 pub fn checksum_mode(&self) -> Result<AeaChecksumMode> {
390 let raw =
391 u32::try_from(self.field_uint(AeaContextField::ChecksumMode)?).unwrap_or(u32::MAX);
392 AeaChecksumMode::from_raw(raw).ok_or_else(|| CompressionError::OperationFailed {
393 operation: "AEAContextGetChecksumMode",
394 code: i32::try_from(raw).unwrap_or(i32::MAX),
395 })
396 }
397
398 pub fn compression_algorithm(&self) -> Result<ArchiveCompressionAlgorithm> {
400 let raw = u32::try_from(self.field_uint(AeaContextField::CompressionAlgorithm)?)
401 .unwrap_or(u32::MAX);
402 ArchiveCompressionAlgorithm::from_raw(raw).ok_or_else(|| {
403 CompressionError::OperationFailed {
404 operation: "AEAContextGetCompressionAlgorithm",
405 code: i32::try_from(raw).unwrap_or(i32::MAX),
406 }
407 })
408 }
409
410 pub fn compression_block_size(&self) -> Result<usize> {
412 usize::try_from(self.field_uint(AeaContextField::CompressionBlockSize)?).map_err(|_| {
413 CompressionError::OperationFailed {
414 operation: "AEAContextGetCompressionBlockSize",
415 code: i32::MAX,
416 }
417 })
418 }
419
420 pub fn raw_size(&self) -> Result<u64> {
422 self.field_uint(AeaContextField::RawSize)
423 }
424
425 pub fn container_size(&self) -> Result<u64> {
427 self.field_uint(AeaContextField::ContainerSize)
428 }
429
430 pub fn auth_data(&self) -> Result<Vec<u8>> {
432 self.field_blob(
433 AeaContextField::AuthData,
434 AeaContextFieldRepresentation::Raw,
435 )
436 }
437
438 pub fn signature_encryption_key(&self) -> Result<Vec<u8>> {
440 self.field_blob(
441 AeaContextField::SignatureEncryptionKey,
442 AeaContextFieldRepresentation::Raw,
443 )
444 }
445
446 pub fn archive_identifier(&self) -> Result<Vec<u8>> {
448 self.field_blob(
449 AeaContextField::ArchiveIdentifier,
450 AeaContextFieldRepresentation::Raw,
451 )
452 }
453
454 pub fn main_key(&self) -> Result<Vec<u8>> {
456 self.field_blob(AeaContextField::MainKey, AeaContextFieldRepresentation::Raw)
457 }
458
459 pub fn set_compression_algorithm(
461 &mut self,
462 compression_algorithm: ArchiveCompressionAlgorithm,
463 ) -> Result<()> {
464 self.set_field_uint(
465 AeaContextField::CompressionAlgorithm,
466 u64::from(compression_algorithm.as_raw()),
467 )
468 }
469
470 pub fn set_compression_block_size(&mut self, compression_block_size: usize) -> Result<()> {
472 self.set_field_uint(
473 AeaContextField::CompressionBlockSize,
474 u64::try_from(compression_block_size).unwrap_or(u64::MAX),
475 )
476 }
477
478 pub fn set_checksum_mode(&mut self, checksum_mode: AeaChecksumMode) -> Result<()> {
480 self.set_field_uint(
481 AeaContextField::ChecksumMode,
482 u64::from(checksum_mode.raw()),
483 )
484 }
485
486 pub fn set_padding_size(&mut self, padding_size: u64) -> Result<()> {
488 self.set_field_uint(AeaContextField::PaddingSize, padding_size)
489 }
490
491 pub fn set_auth_data_bytes(&mut self, auth_data: &[u8]) -> Result<()> {
493 self.set_field_blob(
494 AeaContextField::AuthData,
495 AeaContextFieldRepresentation::Raw,
496 auth_data,
497 )
498 }
499
500 pub fn set_auth_data_blob(&mut self, auth_data: &AeaAuthData) -> Result<()> {
502 self.set_auth_data_bytes(&auth_data.encoded_data()?)
503 }
504
505 pub fn set_signature_encryption_key(&mut self, key: &[u8]) -> Result<()> {
507 self.set_field_blob(
508 AeaContextField::SignatureEncryptionKey,
509 AeaContextFieldRepresentation::Raw,
510 key,
511 )
512 }
513
514 pub fn set_symmetric_key(&mut self, key: &[u8]) -> Result<()> {
516 self.set_field_blob(
517 AeaContextField::SymmetricKey,
518 AeaContextFieldRepresentation::Raw,
519 key,
520 )
521 }
522
523 pub fn set_password(&mut self, password: &[u8]) -> Result<()> {
525 self.set_field_blob(
526 AeaContextField::Password,
527 AeaContextFieldRepresentation::Raw,
528 password,
529 )
530 }
531
532 pub fn set_signing_public_key(&mut self, key: &[u8]) -> Result<()> {
534 self.set_field_blob(
535 AeaContextField::SigningPublicKey,
536 AeaContextFieldRepresentation::X963,
537 key,
538 )
539 }
540
541 pub fn set_signing_private_key(&mut self, key: &[u8]) -> Result<()> {
543 self.set_field_blob(
544 AeaContextField::SigningPrivateKey,
545 AeaContextFieldRepresentation::X963,
546 key,
547 )
548 }
549
550 pub fn set_recipient_public_key(&mut self, key: &[u8]) -> Result<()> {
552 self.set_field_blob(
553 AeaContextField::RecipientPublicKey,
554 AeaContextFieldRepresentation::X963,
555 key,
556 )
557 }
558
559 pub fn set_recipient_private_key(&mut self, key: &[u8]) -> Result<()> {
561 self.set_field_blob(
562 AeaContextField::RecipientPrivateKey,
563 AeaContextFieldRepresentation::X963,
564 key,
565 )
566 }
567
568 pub fn set_main_key(&mut self, key: &[u8]) -> Result<()> {
570 self.set_field_blob(
571 AeaContextField::MainKey,
572 AeaContextFieldRepresentation::Raw,
573 key,
574 )
575 }
576
577 pub fn encryption_output_stream(
579 &self,
580 encrypted_stream: ByteStream,
581 flags: ArchiveFlags,
582 n_threads: i32,
583 ) -> Result<ByteStream> {
584 let handle = unsafe {
585 ffi::aea::compression_rs_aea_encryption_output_stream_open(
586 encrypted_stream.as_ptr(),
587 self.as_ptr(),
588 flags.bits(),
589 n_threads,
590 )
591 };
592 Self::open_byte_stream(handle, "AEAEncryptionOutputStreamOpen", encrypted_stream)
593 }
594
595 pub fn encryption_output_stream_existing(
597 &self,
598 encrypted_stream: ByteStream,
599 flags: ArchiveFlags,
600 n_threads: i32,
601 ) -> Result<ByteStream> {
602 let handle = unsafe {
603 ffi::aea::compression_rs_aea_encryption_output_stream_open_existing(
604 encrypted_stream.as_ptr(),
605 self.as_ptr(),
606 flags.bits(),
607 n_threads,
608 )
609 };
610 Self::open_byte_stream(
611 handle,
612 "AEAEncryptionOutputStreamOpenExisting",
613 encrypted_stream,
614 )
615 }
616
617 pub fn decryption_input_stream(
619 &mut self,
620 encrypted_stream: ByteStream,
621 flags: ArchiveFlags,
622 n_threads: i32,
623 ) -> Result<ByteStream> {
624 let handle = unsafe {
625 ffi::aea::compression_rs_aea_decryption_input_stream_open(
626 encrypted_stream.as_ptr(),
627 self.as_ptr(),
628 flags.bits(),
629 n_threads,
630 )
631 };
632 Self::open_byte_stream(handle, "AEADecryptionInputStreamOpen", encrypted_stream)
633 }
634
635 pub fn decryption_random_access_input_stream(
637 &mut self,
638 encrypted_stream: ByteStream,
639 alloc_limit: usize,
640 flags: ArchiveFlags,
641 n_threads: i32,
642 ) -> Result<ByteStream> {
643 let handle = unsafe {
644 ffi::aea::compression_rs_aea_decryption_random_access_input_stream_open(
645 encrypted_stream.as_ptr(),
646 self.as_ptr(),
647 alloc_limit,
648 flags.bits(),
649 n_threads,
650 )
651 };
652 Self::open_byte_stream(
653 handle,
654 "AEADecryptionRandomAccessInputStreamOpen",
655 encrypted_stream,
656 )
657 }
658
659 pub fn close_encryption_output_stream(&mut self, stream: &mut ByteStream) -> Result<()> {
661 let status = unsafe {
662 ffi::aea::compression_rs_aea_encryption_output_stream_close_and_update_context(
663 stream.as_ptr(),
664 self.as_ptr(),
665 )
666 };
667 util::status_result("AEAEncryptionOutputStreamCloseAndUpdateContext", status)?;
668 stream.mark_closed();
669 Ok(())
670 }
671
672 pub fn sign_stream(&self, stream: &mut ByteStream) -> Result<()> {
674 let status =
675 unsafe { ffi::aea::compression_rs_aea_stream_sign(stream.as_ptr(), self.as_ptr()) };
676 util::status_result("AEAStreamSign", status)
677 }
678}
679
680impl Drop for AeaContext {
681 fn drop(&mut self) {
682 unsafe { ffi::aea::compression_rs_aea_context_release(self.as_ptr()) };
683 }
684}
685
686#[derive(Debug)]
688pub struct AeaAuthData {
689 handle: NonNull<c_void>,
690}
691
692impl AeaAuthData {
693 fn from_handle(handle: *mut c_void, operation: &'static str) -> Result<Self> {
694 Ok(Self {
695 handle: util::nonnull_handle(handle, operation)?,
696 })
697 }
698
699 pub fn new() -> Result<Self> {
701 let handle = unsafe { ffi::aea::compression_rs_aea_auth_data_create() };
702 Self::from_handle(handle, "AEAAuthDataCreate")
703 }
704
705 pub fn from_context(context: &AeaContext) -> Result<Self> {
707 let handle =
708 unsafe { ffi::aea::compression_rs_aea_auth_data_create_with_context(context.as_ptr()) };
709 Self::from_handle(handle, "AEAAuthDataCreateWithContext")
710 }
711
712 pub(crate) fn as_ptr(&self) -> *mut c_void {
713 self.handle.as_ptr()
714 }
715
716 pub fn entry_count(&self) -> u32 {
718 unsafe { ffi::aea::compression_rs_aea_auth_data_get_entry_count(self.as_ptr()) }
719 }
720
721 pub fn is_empty(&self) -> bool {
723 self.entry_count() == 0
724 }
725
726 pub fn entry(&self, index: u32) -> Result<NamedBlobEntry> {
728 let mut key_length = 0_usize;
729 let mut data_size = 0_usize;
730 let status = unsafe {
731 ffi::aea::compression_rs_aea_auth_data_get_entry(
732 self.as_ptr(),
733 index,
734 0,
735 null_mut(),
736 &mut key_length,
737 0,
738 null_mut(),
739 &mut data_size,
740 )
741 };
742 util::status_result("AEAAuthDataGetEntry", status)?;
743
744 let mut key = vec![0_i8; key_length.saturating_add(1)];
745 let mut value = vec![0_u8; data_size];
746 let status = unsafe {
747 ffi::aea::compression_rs_aea_auth_data_get_entry(
748 self.as_ptr(),
749 index,
750 key.len(),
751 key.as_mut_ptr(),
752 &mut key_length,
753 value.len(),
754 if value.is_empty() {
755 null_mut()
756 } else {
757 value.as_mut_ptr()
758 },
759 &mut data_size,
760 )
761 };
762 util::status_result("AEAAuthDataGetEntry", status)?;
763
764 let key = unsafe { CStr::from_ptr(key.as_ptr()) }
765 .to_str()
766 .map_err(|_| CompressionError::Utf8Error {
767 operation: "AEAAuthDataGetEntry",
768 })?
769 .to_string();
770
771 Ok(NamedBlobEntry { key, value })
772 }
773
774 pub fn entries(&self) -> Result<Vec<NamedBlobEntry>> {
776 (0..self.entry_count())
777 .map(|index| self.entry(index))
778 .collect()
779 }
780
781 pub fn append_entry(&mut self, entry: &NamedBlobEntry) -> Result<()> {
783 let key = util::cstring("key", &entry.key)?;
784 let data_ptr = if entry.value.is_empty() {
785 null()
786 } else {
787 entry.value.as_ptr()
788 };
789 let status = unsafe {
790 ffi::aea::compression_rs_aea_auth_data_append_entry(
791 self.as_ptr(),
792 key.as_ptr(),
793 data_ptr,
794 entry.value.len(),
795 )
796 };
797 util::status_result("AEAAuthDataAppendEntry", status)
798 }
799
800 pub fn set_entry(&mut self, index: u32, entry: &NamedBlobEntry) -> Result<()> {
802 let key = util::cstring("key", &entry.key)?;
803 let data_ptr = if entry.value.is_empty() {
804 null()
805 } else {
806 entry.value.as_ptr()
807 };
808 let status = unsafe {
809 ffi::aea::compression_rs_aea_auth_data_set_entry(
810 self.as_ptr(),
811 index,
812 key.as_ptr(),
813 data_ptr,
814 entry.value.len(),
815 )
816 };
817 util::status_result("AEAAuthDataSetEntry", status)
818 }
819
820 pub fn clear(&mut self) -> Result<()> {
822 let status = unsafe { ffi::aea::compression_rs_aea_auth_data_clear(self.as_ptr()) };
823 util::status_result("AEAAuthDataClear", status)
824 }
825
826 pub fn remove_entry(&mut self, index: u32) -> Result<()> {
828 let status =
829 unsafe { ffi::aea::compression_rs_aea_auth_data_remove_entry(self.as_ptr(), index) };
830 util::status_result("AEAAuthDataRemoveEntry", status)
831 }
832
833 pub fn encoded_size(&self) -> usize {
835 unsafe { ffi::aea::compression_rs_aea_auth_data_get_encoded_size(self.as_ptr()) }
836 }
837
838 pub fn encoded_data(&self) -> Result<Vec<u8>> {
840 let size = self.encoded_size();
841 let mut data = vec![0_u8; size];
842 if size == 0 {
843 return Ok(data);
844 }
845 let copied = unsafe {
846 ffi::aea::compression_rs_aea_auth_data_copy_encoded_data(
847 self.as_ptr(),
848 data.as_mut_ptr(),
849 )
850 };
851 if copied {
852 Ok(data)
853 } else {
854 Err(CompressionError::OperationFailed {
855 operation: "AEAAuthDataGetEncodedData",
856 code: -1,
857 })
858 }
859 }
860}
861
862impl Clone for AeaAuthData {
863 fn clone(&self) -> Self {
864 let mut clone = Self::new().expect("AEAAuthDataCreate returned null");
865 for entry in self.entries().expect("AEAAuthDataGetEntry failed") {
866 clone
867 .append_entry(&entry)
868 .expect("AEAAuthDataAppendEntry failed");
869 }
870 clone
871 }
872}
873
874impl Drop for AeaAuthData {
875 fn drop(&mut self) {
876 unsafe { ffi::aea::compression_rs_aea_auth_data_release(self.as_ptr()) };
877 }
878}