Chromium Code Reviews| Index: runtime/vm/dart_api_impl.cc |
| =================================================================== |
| --- runtime/vm/dart_api_impl.cc (revision 25704) |
| +++ runtime/vm/dart_api_impl.cc (working copy) |
| @@ -2136,6 +2136,20 @@ |
| return Api::NewError("Invalid length passed in to access array elements"); \ |
| +static Dart_Handle CopyBytes(const TypedData& array, |
| + intptr_t offset, |
| + uint8_t* native_array, |
| + intptr_t length) { |
| + ASSERT(array.IsTypedData()); |
| + ASSERT(array.ElementSizeInBytes() == 1); |
| + NoGCScope no_gc; |
| + memmove(native_array, |
| + reinterpret_cast<uint8_t*>(array.DataAddr(offset)), |
| + length); |
| + return Api::Success(); |
| +} |
| + |
| + |
| DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, |
| intptr_t offset, |
| uint8_t* native_array, |
| @@ -2146,16 +2160,34 @@ |
| if (obj.IsTypedData()) { |
| const TypedData& array = TypedData::Cast(obj); |
| if (array.ElementSizeInBytes() == 1) { |
| - if (Utils::RangeCheck(offset, length, array.Length())) { |
| - NoGCScope no_gc; |
| - memmove(native_array, |
| - reinterpret_cast<uint8_t*>(array.DataAddr(offset)), |
| - length); |
| - return Api::Success(); |
| + if (!Utils::RangeCheck(offset, length, array.Length())) { |
| + return Api::NewError( |
| + "Invalid length passed in to access list elements"); |
| } |
| - return Api::NewError("Invalid length passed in to access list elements"); |
| + return CopyBytes(array, offset, native_array, length); |
| } |
| } |
| + if (RawObject::IsTypedDataViewClassId(obj.GetClassId())) { |
| + const Instance& view = Instance::Cast(obj); |
| + if (TypedDataView::ElementSizeInBytes(view) == 1) { |
| + intptr_t view_length = Smi::Value(TypedDataView::Length(view)); |
| + if (!Utils::RangeCheck(offset, length, view_length)) { |
| + return Api::NewError( |
| + "Invalid length passed in to access list elements"); |
| + } |
| + const Instance& data = Instance::Handle(TypedDataView::Data(view)); |
| + if (data.IsTypedData()) { |
|
Ivan Posva
2013/08/05 03:45:00
How can this ever not be a typed data? I would exp
Florian Schneider
2013/08/05 08:38:09
Not sure: the view constructor takes just a ByteBu
|
| + const TypedData& array = TypedData::Cast(data); |
| + if (array.ElementSizeInBytes() == 1) { |
| + intptr_t data_offset = |
| + Smi::Value(TypedDataView::OffsetInBytes(view)) + offset; |
| + // Range check already performed on the view object. |
| + ASSERT(Utils::RangeCheck(data_offset, length, array.Length())); |
| + return CopyBytes(array, data_offset, native_array, length); |
| + } |
| + } |
| + } |
| + } |
| if (obj.IsArray()) { |
| GET_LIST_ELEMENT_AS_BYTES(isolate, |
| Array, |
| @@ -2193,6 +2225,7 @@ |
| const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
| args.SetAt(0, instance); // Set up the receiver as the first argument. |
| for (int i = 0; i < length; i++) { |
| + HANDLESCOPE(isolate); |
| intobj = Integer::New(offset + i); |
| args.SetAt(1, intobj); |
| result = DartEntry::InvokeFunction(function, args); |