diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2022-04-02 13:35:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-02 13:35:57 +0200 |
commit | 13b9fc93048baf66c51a83a8201d3af9034b5ba3 (patch) | |
tree | 81af00f9fdd16096ee7d0bd71d67bd67311c264b /serde_v8/magic/detached_buffer.rs | |
parent | 4b33dd887e35a89343d9cd06fdbce96337f1bea3 (diff) |
feat(serde_v8): DetachedBuffer (#14102)
Diffstat (limited to 'serde_v8/magic/detached_buffer.rs')
-rw-r--r-- | serde_v8/magic/detached_buffer.rs | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/serde_v8/magic/detached_buffer.rs b/serde_v8/magic/detached_buffer.rs new file mode 100644 index 000000000..1435a0fa6 --- /dev/null +++ b/serde_v8/magic/detached_buffer.rs @@ -0,0 +1,69 @@ +// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. + +use core::ops::Range; +use std::ops::Deref; +use std::ops::DerefMut; + +use super::transl8::FromV8; +use super::transl8::ToV8; +use super::zero_copy_buf::to_ranged_buffer; +use super::zero_copy_buf::ZeroCopyBuf; +use crate::magic::transl8::impl_magic; + +// A buffer that detaches when deserialized from JS +pub struct DetachedBuffer(ZeroCopyBuf); +impl_magic!(DetachedBuffer); + +impl AsRef<[u8]> for DetachedBuffer { + fn as_ref(&self) -> &[u8] { + self.0.as_ref() + } +} + +impl AsMut<[u8]> for DetachedBuffer { + fn as_mut(&mut self) -> &mut [u8] { + self.0.as_mut() + } +} + +impl Deref for DetachedBuffer { + type Target = [u8]; + fn deref(&self) -> &[u8] { + self.0.deref() + } +} + +impl DerefMut for DetachedBuffer { + fn deref_mut(&mut self) -> &mut [u8] { + self.0.deref_mut() + } +} + +impl ToV8 for DetachedBuffer { + fn to_v8<'a>( + &self, + scope: &mut v8::HandleScope<'a>, + ) -> Result<v8::Local<'a, v8::Value>, crate::Error> { + let buffer = v8::ArrayBuffer::with_backing_store(scope, &self.0.store); + let Range { start, end } = self.0.range; + let (off, len) = (start, end - start); + let v = v8::Uint8Array::new(scope, buffer, off, len).unwrap(); + Ok(v.into()) + } +} + +impl FromV8 for DetachedBuffer { + fn from_v8( + scope: &mut v8::HandleScope, + value: v8::Local<v8::Value>, + ) -> Result<Self, crate::Error> { + let (b, range) = + to_ranged_buffer(scope, value).or(Err(crate::Error::ExpectedBuffer))?; + if !b.is_detachable() { + return Err(crate::Error::ExpectedDetachable); + } + let store = b.get_backing_store(); + b.detach(); // Detach + Ok(Self(ZeroCopyBuf { store, range })) + } +} |