shamblett / cbor

A CBOR implementation for Dart
MIT License
36 stars 16 forks source link

Please provide transition examples from 4.1 to 5.0 #41

Closed CodeSpartan closed 2 years ago

CodeSpartan commented 2 years ago

An example of code that I had:

import 'package:cbor/cbor.dart' as cbor_lib;

class MsgReader {
  static final cbor = cbor_lib.Cbor();

  static List<dynamic> readReceivedData(Uint8List list) {
    cbor.clearDecodeStack();
    cbor.decodeFromList(list);
    debugPrint(cbor.decodedToJSON());
    return cbor.getDecodedData()!;
  }

  static void readSpawnYourPlayer(Uint8List list) {
    var data = readReceivedData(list).first;
    var playerName = data['Name'];
  }
}

All of those functions are gone. I'm trying to figure out how to decode a Uint8List into a map with property names as keys and I can't.

shamblett commented 2 years ago

@nicbn could you help here at all?

nicbn commented 2 years ago

For your case:

Using simple API (import simple.dart): cbor.decode(bytes) as Map, where bytes is List<int> and the Map entries will have their types defined by the items (String, int, etc)

Using complex API (import cbor.dart): cbor.decode(bytes) as CborMap and the map entries will be CborValue, use toString to transform them to strings.

I'll provide guide on transitioning to the repo later, but as a general rule the simple API will suffice for most use cases and acts like dart:convert json.

CodeSpartan commented 2 years ago

@nicbn thanks for the explanation. But now that I'm decoding it, something is broken in the decoder. It decodes some integers incorrectly when they're part of a large message.

Here's what I send from the Go server: {"Loot":[{"ItemId":39,"Dropped":1643106728.338353,"Private":0,"OwnerIds":[0,1,2],"UniqueId":134257389},{"ItemId":41,"Dropped":1643106728.338353,"Private":300,"OwnerIds":[3,4,5],"UniqueId":1266695221}],"Paths":[{"Id":28},{"Id":27},{"Id":9},{"Id":69}],"RoomId":6,"Battles":[],"Creatures":[{"CreId":69123,"CrePreset":6},{"CreId":63254,"CrePreset":6},{"CreId":31318,"CrePreset":7},{"Sex":true,"Icon":"femprotag.png","Name":"Лэнс","CreId":136661,"NameAcc":"Лэнса","NameDat":"Лэнсу"}]}

In all of this message, the CreId of the first element in the Creatures array will always decode incorrectly. Examples: 33726 gets decoded as -31810, 39019 gets decoded as -26517.

I've reverted 4.1 to confirm that 5.0 is causing the issue, and indeed it is.

nicbn commented 2 years ago

Thanks for reporting, will take a look

CodeSpartan commented 2 years ago

After giving it some thought, my best theory is that the decoder treats values between 32767 (max value of int16) and 65535 as a signed int16 (whereas in reality I'm guessing it's serialized as an uint16), which results in the reversal of the number into the negatives. But it's not the correct behavior.

And the context of "it happens in a large message" and "it's always the first value of an array", etc is completely irrelevant. It's just where I stumble on it due to how my program works.

nicbn commented 2 years ago

Found the issue, int16 and int32 are being treated as 2-complement. Will submit a patch.

shamblett commented 2 years ago

A fix has now been applied that should correct this issue, the package has been re published at version 5.0.1, please re test.

CodeSpartan commented 2 years ago

Works now, thanks.