script/dom/stream/
bytelengthqueuingstrategy.rs1use std::rc::Rc;
6
7use dom_struct::dom_struct;
8use js::error::throw_type_error;
9use js::gc::{HandleValue, MutableHandleValue};
10use js::jsapi::{CallArgs, JSContext};
11use js::jsval::{JSVal, UndefinedValue};
12use js::rust::HandleObject;
13use script_bindings::reflector::{Reflector, reflect_dom_object_with_proto};
14
15use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function;
16use crate::dom::bindings::codegen::Bindings::QueuingStrategyBinding::{
17 ByteLengthQueuingStrategyMethods, QueuingStrategyInit,
18};
19use crate::dom::bindings::error::Fallible;
20use crate::dom::bindings::reflector::DomGlobal;
21use crate::dom::bindings::root::DomRoot;
22use crate::dom::bindings::utils::get_dictionary_property;
23use crate::dom::types::GlobalScope;
24use crate::native_fn;
25use crate::script_runtime::CanGc;
26
27#[dom_struct]
28pub(crate) struct ByteLengthQueuingStrategy {
29 reflector_: Reflector,
30 high_water_mark: f64,
31}
32
33impl ByteLengthQueuingStrategy {
34 pub(crate) fn new_inherited(init: f64) -> Self {
35 Self {
36 reflector_: Reflector::new(),
37 high_water_mark: init,
38 }
39 }
40
41 pub(crate) fn new(
42 global: &GlobalScope,
43 proto: Option<HandleObject>,
44 init: f64,
45 can_gc: CanGc,
46 ) -> DomRoot<Self> {
47 reflect_dom_object_with_proto(Box::new(Self::new_inherited(init)), global, proto, can_gc)
48 }
49}
50
51impl ByteLengthQueuingStrategyMethods<crate::DomTypeHolder> for ByteLengthQueuingStrategy {
52 fn Constructor(
54 global: &GlobalScope,
55 proto: Option<HandleObject>,
56 can_gc: CanGc,
57 init: &QueuingStrategyInit,
58 ) -> DomRoot<Self> {
59 Self::new(global, proto, init.highWaterMark, can_gc)
60 }
61 fn HighWaterMark(&self) -> f64 {
63 self.high_water_mark
64 }
65
66 fn GetSize(&self, cx: &mut js::context::JSContext) -> Fallible<Rc<Function>> {
68 let global = self.global();
69 if let Some(fun) = global.get_byte_length_queuing_strategy_size() {
72 return Ok(fun);
73 }
74
75 let fun = native_fn!(cx, byte_length_queuing_strategy_size, c"size", 1, 0);
81 global.set_byte_length_queuing_strategy_size(fun.clone());
85 Ok(fun)
86 }
87}
88
89#[expect(unsafe_code)]
91pub(crate) fn byte_length_queuing_strategy_size(
92 cx: &mut js::context::JSContext,
93 args: CallArgs,
94) -> bool {
95 let chunk = unsafe { HandleValue::from_raw(args.get(0)) };
98
99 if chunk.is_undefined() || chunk.is_null() {
102 unsafe {
103 throw_type_error(
104 cx.raw_cx(),
105 c"ByteLengthQueuingStrategy size called with undefined or nulll",
106 )
107 };
108 return false;
109 }
110
111 if !chunk.is_object() {
112 args.rval().set(UndefinedValue());
115 return true;
116 }
117
118 rooted!(&in(cx) let object = chunk.to_object());
119
120 match unsafe {
122 get_dictionary_property(
123 cx.raw_cx(),
124 object.handle(),
125 c"byteLength",
126 MutableHandleValue::from_raw(args.rval()),
127 CanGc::from_cx(cx),
128 )
129 } {
130 Ok(true) => true,
131 Ok(false) => {
132 args.rval().set(UndefinedValue());
133 true
134 },
135 Err(()) => false,
136 }
137}