iProgram
iProgram

Reputation: 6557

Why does ByteData.view(buffer) throw NoSuchMethodError: Class 'String' has no instance method 'asByteData'

I am trying to read UDP data and converting it to a float.

I know I need to

  1. Receive the Datagram from RawDatagramSocket
  2. Get the ByteBuffer from the Datagram
  3. Convert the ByteBuffer to ByteData
  4. use the getFloat32 method on the ByteData

Here is the broken code:

import 'dart:io';
import 'dart:typed_data';
import 'dart:mirrors';

getTypeName(dynamic obj) {
  return reflect(obj).type.reflectedType.toString();
}

void main(List<String> args){
  RawDatagramSocket.bind("192.168.1.1", 4444).then((RawDatagramSocket socket){
    print('Datagram socket ready to receive');
    print('${socket.address.address}:${socket.port}');
    socket.listen((RawSocketEvent e){
      Datagram d = socket.receive();
      if (d == null) return;
      ByteBuffer buffer = getTypeName(d.data.buffer);
      ByteData bdata = new ByteData.view(buffer);
    });
  });
}

Here is the debugging code:

import 'dart:io';
import 'dart:typed_data';
import 'dart:mirrors';

getTypeName(dynamic obj) {
  return reflect(obj).type.reflectedType.toString();
}

void main(List<String> args){
  RawDatagramSocket.bind("192.168.1.1", 4444).then((RawDatagramSocket socket){
    print('Datagram socket ready to receive');
    print('${socket.address.address}:${socket.port}');
    socket.listen((RawSocketEvent e){
      Datagram d = socket.receive();
      if (d == null) return;
      print(d.data);
    });
  });
}

If I initiate netcat using the following command nc -u 192.168.1.1 4444 and send the data '1111', I get the following printed out from the debug code:

[49, 49, 49, 49, 10]

I understand those values are the assai characters of '1111' followed by a carriage return.

The problem is, when I run the 'broken code', I end up getting the following message:

Unhandled exception:
NoSuchMethodError: Class 'String' has no instance method 'asByteData'.
Receiver: "_ByteBuffer"
Tried calling: asByteData(0, null)
#0      Object._noSuchMethod (dart:core-patch/object_patch.dart:43)
#1      Object.noSuchMethod (dart:core-patch/object_patch.dart:47)
#2      new ByteData.view (dart:typed_data:449)
#3      main.<anonymous closure>.<anonymous closure> (file:///Users/iProgram/test.dart:17:25)
#4      _RootZone.runUnaryGuarded (dart:async/zone.dart:1307)
#5      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:330)
#6      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:257)
#7      _StreamController&&_SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:796)
#8      _StreamController._add (dart:async/stream_controller.dart:667)
#9      _StreamController.add (dart:async/stream_controller.dart:613)
#10     new _RawDatagramSocket.<anonymous closure> (dart:io-patch/socket_patch.dart:1699)
#11     _NativeSocket.issueReadEvent.issue (dart:io-patch/socket_patch.dart:760)
#12     _microtaskLoop (dart:async/schedule_microtask.dart:41)
#13     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
#14     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:99)
#15     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:152)

The question is, why am I getting the error Class 'String' has no instance method 'asByteData' when I am not using a string or the asByteData command?

I have been using the following documentation: Dart - ByteData

Thanks

Upvotes: 0

Views: 2768

Answers (1)

Danny Tuppeny
Danny Tuppeny

Reputation: 42353

why am I getting the error Class 'String' has no instance method 'asByteData' when I am not using a string or the asByteData command?

The call stack shows what's happening here:

Tried calling: asByteData(0, null)
#0      Object._noSuchMethod (dart:core-patch/object_patch.dart:43)
#1      Object.noSuchMethod (dart:core-patch/object_patch.dart:47)
#2      new ByteData.view (dart:typed_data:449)

You're calling new ByteData.view which is internally calling asByteData.

The ByteData.view constructor takes a ByteBuffer but you're passing it a string:

ByteBuffer buffer = getTypeName(d.data.buffer);

Although you've written ByteBuffer here, your getTypeName() function is actually returning a String:

return reflect(obj).type.reflectedType.toString();

Upvotes: 2

Related Questions