diff options
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 26 | ||||
-rw-r--r-- | src/components/script/dom/bindings/conversions.rs | 42 | ||||
-rw-r--r-- | src/components/script/dom/bindings/str.rs | 16 | ||||
-rw-r--r-- | src/components/script/dom/testbinding.rs | 10 | ||||
-rw-r--r-- | src/components/script/dom/webidls/TestBinding.webidl | 7 | ||||
-rw-r--r-- | src/components/script/script.rs | 1 |
6 files changed, 100 insertions, 2 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index f7d6c23ed98..0fe840a33a0 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -687,6 +687,24 @@ def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None, return handleOptional(getConversionCode(), CGGeneric(declType), isOptional) + if type.isByteString(): + assert not isEnforceRange and not isClamp + + conversionCode = ( + "match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" + " Ok(strval) => strval,\n" + " Err(_) => { %s },\n" + "}" % exceptionCode) + + declType = CGGeneric("ByteString") + if type.nullable(): + declType = CGWrapper(declType, pre="Option<", post=">") + conversionCode = handleDefaultNull(conversionCode, "None") + else: + assert defaultValue is None + + return handleOptional(conversionCode, declType, isOptional) + if type.isEnum(): assert not isEnforceRange and not isClamp @@ -996,6 +1014,11 @@ def getRetvalDeclarationForType(returnType, descriptorProvider): if returnType.nullable(): result = CGWrapper(result, pre="Option<", post=">") return result + if returnType.isByteString(): + result = CGGeneric("ByteString") + if returnType.nullable(): + result = CGWrapper(result, pre="Option<", post=">") + return result if returnType.isEnum(): result = CGGeneric(returnType.unroll().inner.identifier.name) if returnType.nullable(): @@ -4283,11 +4306,12 @@ class CGBindingRoot(CGThing): 'dom::bindings::error::{FailureUnknown, Fallible, Error, ErrorResult}', 'dom::bindings::error::{throw_method_failed_with_details}', 'dom::bindings::error::throw_type_error', - 'script_task::JSPageInfo', 'dom::bindings::proxyhandler', 'dom::bindings::proxyhandler::{_obj_toString, defineProperty}', 'dom::bindings::proxyhandler::{FillPropertyDescriptor, GetExpandoObject}', 'dom::bindings::proxyhandler::{getPropertyDescriptor}', + 'dom::bindings::str::ByteString', + 'script_task::JSPageInfo', 'libc', 'servo_util::str::DOMString', 'servo_util::vec::zip_copies', diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs index 9f97897dd20..6721f3f5dde 100644 --- a/src/components/script/dom/bindings/conversions.rs +++ b/src/components/script/dom/bindings/conversions.rs @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::js::JS; +use dom::bindings::str::ByteString; use dom::bindings::utils::Reflectable; use dom::bindings::utils::jsstring_to_str; use dom::bindings::utils::unwrap_jsmanaged; @@ -12,7 +13,8 @@ use js::jsapi::{JSBool, JSContext}; use js::jsapi::{JS_ValueToUint64, JS_ValueToInt64}; use js::jsapi::{JS_ValueToECMAUint32, JS_ValueToECMAInt32}; use js::jsapi::{JS_ValueToUint16, JS_ValueToNumber, JS_ValueToBoolean}; -use js::jsapi::{JS_NewUCStringCopyN, JS_ValueToString}; +use js::jsapi::{JS_ValueToString, JS_GetStringCharsAndLength}; +use js::jsapi::{JS_NewUCStringCopyN, JS_NewStringCopyN}; use js::jsapi::{JS_WrapValue}; use js::jsval::JSVal; use js::jsval::{UndefinedValue, NullValue, BooleanValue, Int32Value, UInt32Value}; @@ -20,6 +22,7 @@ use js::jsval::{StringValue, ObjectValue}; use js::glue::RUST_JS_NumberValue; use libc; use std::default::Default; +use std::slice; use dom::bindings::codegen::PrototypeList; @@ -253,6 +256,43 @@ impl FromJSValConvertible<StringificationBehavior> for DOMString { } } +impl ToJSValConvertible for ByteString { + fn to_jsval(&self, cx: *JSContext) -> JSVal { + unsafe { + let slice = self.as_slice(); + let jsstr = JS_NewStringCopyN(cx, slice.as_ptr() as *libc::c_char, + slice.len() as libc::size_t); + if jsstr.is_null() { + fail!("JS_NewStringCopyN failed"); + } + StringValue(&*jsstr) + } + } +} + +impl FromJSValConvertible<()> for ByteString { + fn from_jsval(cx: *JSContext, value: JSVal, _option: ()) -> Result<ByteString, ()> { + unsafe { + let string = JS_ValueToString(cx, value); + if string.is_null() { + debug!("JS_ValueToString failed"); + return Err(()); + } + + let mut length = 0; + let chars = JS_GetStringCharsAndLength(cx, string, &mut length as *mut _ as *_); + slice::raw::buf_as_slice(chars, length as uint, |char_vec| { + if char_vec.iter().any(|&c| c > 0xFF) { + // XXX Throw + Err(()) + } else { + Ok(ByteString::new(char_vec.iter().map(|&c| c as u8).collect())) + } + }) + } + } +} + impl<T: Reflectable> ToJSValConvertible for JS<T> { fn to_jsval(&self, cx: *JSContext) -> JSVal { let obj = self.reflector().get_jsobject(); diff --git a/src/components/script/dom/bindings/str.rs b/src/components/script/dom/bindings/str.rs new file mode 100644 index 00000000000..b7978b4737b --- /dev/null +++ b/src/components/script/dom/bindings/str.rs @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +pub struct ByteString(Vec<u8>); + +impl ByteString { + pub fn new(value: Vec<u8>) -> ByteString { + ByteString(value) + } + + pub fn as_slice<'a>(&'a self) -> &'a [u8] { + let ByteString(ref vector) = *self; + vector.as_slice() + } +} diff --git a/src/components/script/dom/testbinding.rs b/src/components/script/dom/testbinding.rs index 76056272338..5d2620263a7 100644 --- a/src/components/script/dom/testbinding.rs +++ b/src/components/script/dom/testbinding.rs @@ -7,6 +7,7 @@ use dom::bindings::codegen::TestBindingBinding; use dom::bindings::codegen::UnionTypes::HTMLElementOrLong; use self::TestBindingBinding::TestEnum; use self::TestBindingBinding::TestEnumValues::_empty; +use dom::bindings::str::ByteString; use dom::bindings::utils::{Reflector, Reflectable}; use dom::blob::Blob; use dom::window::Window; @@ -46,6 +47,8 @@ impl TestBinding { pub fn SetDoubleAttribute(&self, _: f64) {} pub fn StringAttribute(&self) -> DOMString { ~"" } pub fn SetStringAttribute(&self, _: DOMString) {} + pub fn ByteStringAttribute(&self) -> ByteString { ByteString::new(vec!()) } + pub fn SetByteStringAttribute(&self, _: ByteString) {} pub fn EnumAttribute(&self) -> TestEnum { _empty } pub fn SetEnumAttribute(&self, _: TestEnum) {} pub fn InterfaceAttribute(&self) -> JS<Blob> { Blob::new(&self.window) } @@ -75,6 +78,8 @@ impl TestBinding { pub fn SetFloatAttributeNullable(&self, _: Option<f32>) {} pub fn GetDoubleAttributeNullable(&self) -> Option<f64> { Some(0.) } pub fn SetDoubleAttributeNullable(&self, _: Option<f64>) {} + pub fn GetByteStringAttributeNullable(&self) -> Option<ByteString> { Some(ByteString::new(vec!())) } + pub fn SetByteStringAttributeNullable(&self, _: Option<ByteString>) {} pub fn GetStringAttributeNullable(&self) -> Option<DOMString> { Some(~"") } pub fn SetStringAttributeNullable(&self, _: Option<DOMString>) {} pub fn GetEnumAttributeNullable(&self) -> Option<TestEnum> { Some(_empty) } @@ -93,6 +98,7 @@ impl TestBinding { pub fn PassFloat(&self, _: f32) {} pub fn PassDouble(&self, _: f64) {} pub fn PassString(&self, _: DOMString) {} + pub fn PassByteString(&self, _: ByteString) {} pub fn PassEnum(&self, _: TestEnum) {} pub fn PassInterface(&self, _: &JS<Blob>) {} pub fn PassUnion(&self, _: HTMLElementOrLong) {} @@ -110,6 +116,7 @@ impl TestBinding { pub fn PassNullableFloat(&self, _: Option<f32>) {} pub fn PassNullableDouble(&self, _: Option<f64>) {} pub fn PassNullableString(&self, _: Option<DOMString>) {} + pub fn PassNullableByteString(&self, _: Option<ByteString>) {} // pub fn PassNullableEnum(&self, _: Option<TestEnum>) {} pub fn PassNullableInterface(&self, _: Option<JS<Blob>>) {} pub fn PassNullableUnion(&self, _: Option<HTMLElementOrLong>) {} @@ -127,6 +134,7 @@ impl TestBinding { pub fn PassOptionalFloat(&self, _: Option<f32>) {} pub fn PassOptionalDouble(&self, _: Option<f64>) {} pub fn PassOptionalString(&self, _: Option<DOMString>) {} + pub fn PassOptionalByteString(&self, _: Option<ByteString>) {} pub fn PassOptionalEnum(&self, _: Option<TestEnum>) {} pub fn PassOptionalInterface(&self, _: Option<JS<Blob>>) {} pub fn PassOptionalUnion(&self, _: Option<HTMLElementOrLong>) {} @@ -144,6 +152,7 @@ impl TestBinding { pub fn PassOptionalNullableFloat(&self, _: Option<Option<f32>>) {} pub fn PassOptionalNullableDouble(&self, _: Option<Option<f64>>) {} pub fn PassOptionalNullableString(&self, _: Option<Option<DOMString>>) {} + pub fn PassOptionalNullableByteString(&self, _: Option<Option<ByteString>>) {} // pub fn PassOptionalNullableEnum(&self, _: Option<Option<TestEnum>>) {} pub fn PassOptionalNullableInterface(&self, _: Option<Option<JS<Blob>>>) {} pub fn PassOptionalNullableUnion(&self, _: Option<Option<HTMLElementOrLong>>) {} @@ -172,6 +181,7 @@ impl TestBinding { pub fn PassOptionalNullableFloatWithDefault(&self, _: Option<f32>) {} pub fn PassOptionalNullableDoubleWithDefault(&self, _: Option<f64>) {} pub fn PassOptionalNullableStringWithDefault(&self, _: Option<DOMString>) {} + pub fn PassOptionalNullableByteStringWithDefault(&self, _: Option<ByteString>) {} // pub fn PassOptionalNullableEnumWithDefault(&self, _: Option<TestEnum>) {} pub fn PassOptionalNullableInterfaceWithDefault(&self, _: Option<JS<Blob>>) {} pub fn PassOptionalNullableUnionWithDefault(&self, _: Option<HTMLElementOrLong>) {} diff --git a/src/components/script/dom/webidls/TestBinding.webidl b/src/components/script/dom/webidls/TestBinding.webidl index 5749214fba3..89325125da2 100644 --- a/src/components/script/dom/webidls/TestBinding.webidl +++ b/src/components/script/dom/webidls/TestBinding.webidl @@ -66,6 +66,7 @@ interface TestBinding { attribute float floatAttribute; attribute double doubleAttribute; attribute DOMString stringAttribute; + attribute ByteString byteStringAttribute; attribute TestEnum enumAttribute; attribute Blob interfaceAttribute; // attribute (HTMLElement or long) unionAttribute; @@ -83,6 +84,7 @@ interface TestBinding { attribute float? floatAttributeNullable; attribute double? doubleAttributeNullable; attribute DOMString? stringAttributeNullable; + attribute ByteString? byteStringAttributeNullable; readonly attribute TestEnum? enumAttributeNullable; attribute Blob? interfaceAttributeNullable; // attribute (HTMLElement or long)? unionAttributeNullable; @@ -99,6 +101,7 @@ interface TestBinding { void passFloat(float arg); void passDouble(double arg); void passString(DOMString arg); + void passByteString(ByteString arg); void passEnum(TestEnum arg); void passInterface(Blob arg); void passUnion((HTMLElement or long) arg); @@ -116,6 +119,7 @@ interface TestBinding { void passNullableFloat(float? arg); void passNullableDouble(double? arg); void passNullableString(DOMString? arg); + void passNullableByteString(ByteString? arg); // void passNullableEnum(TestEnum? arg); void passNullableInterface(Blob? arg); void passNullableUnion((HTMLElement or long)? arg); @@ -132,6 +136,7 @@ interface TestBinding { void passOptionalFloat(optional float arg); void passOptionalDouble(optional double arg); void passOptionalString(optional DOMString arg); + void passOptionalByteString(optional ByteString arg); void passOptionalEnum(optional TestEnum arg); void passOptionalInterface(optional Blob arg); void passOptionalUnion(optional (HTMLElement or long) arg); @@ -149,6 +154,7 @@ interface TestBinding { void passOptionalNullableFloat(optional float? arg); void passOptionalNullableDouble(optional double? arg); void passOptionalNullableString(optional DOMString? arg); + void passOptionalNullableByteString(optional ByteString? arg); // void passOptionalNullableEnum(optional TestEnum? arg); void passOptionalNullableInterface(optional Blob? arg); void passOptionalNullableUnion(optional (HTMLElement or long)? arg); @@ -176,6 +182,7 @@ interface TestBinding { void passOptionalNullableLongLongWithDefault(optional long long? arg = null); void passOptionalNullableUnsignedLongLongWithDefault(optional unsigned long long? arg = null); void passOptionalNullableStringWithDefault(optional DOMString? arg = null); + void passOptionalNullableByteStringWithDefault(optional ByteString? arg = null); // void passOptionalNullableEnumWithDefault(optional TestEnum? arg = null); void passOptionalNullableInterfaceWithDefault(optional Blob? arg = null); void passOptionalNullableUnionWithDefault(optional (HTMLElement or long)? arg = null); diff --git a/src/components/script/script.rs b/src/components/script/script.rs index 022b3b5e1a5..eb3832a65dd 100644 --- a/src/components/script/script.rs +++ b/src/components/script/script.rs @@ -42,6 +42,7 @@ pub mod dom { pub mod error; pub mod conversions; pub mod proxyhandler; + pub mod str; pub mod trace; pub mod codegen { pub use self::BindingDeclarations::*; |