diff --git a/CHANGELOG.md b/CHANGELOG.md index 86ff9b1..8668ec6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 3.0.0 + +**Bug fix:** +* [socket_io_common#12](https://github.com/rikulo/socket_io_common/pull/12) Sending buffer data is not working! + + ## 3.0.0-beta.0 **Features:** diff --git a/README.md b/README.md index 4413e75..d10fe46 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Socket.io common parser library for Dart 2 `v3.*` | `v4.7.* ~ v4.*` ## Contributors -- Thanks [@Curvel](https://github.com/Curvel) for https://github.com/rikulo/socket_io_common/pull/4 -- Thanks [@busslina](https://github.com/busslina) for https://github.com/rikulo/socket_io_common/pull/5 -- Thanks [@claudius-kienle](https://github.com/claudius-kienle) for https://github.com/rikulo/socket_io_common/pull/8 + + + + diff --git a/analysis_options.yaml b/analysis_options.yaml index 97d4b47..139d786 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -7,8 +7,7 @@ linter: rules: - cancel_subscriptions - hash_and_equals - - iterable_contains_unrelated_type - - list_remove_unrelated_type + - collection_methods_unrelated_type - test_types_in_equals - unrelated_type_equality_checks - valid_regexps diff --git a/lib/src/engine/parser/commons.dart b/lib/src/engine/parser/commons.dart index 5c4abbc..de27284 100644 --- a/lib/src/engine/parser/commons.dart +++ b/lib/src/engine/parser/commons.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2024 Potix Corporation. All Rights Reserved +// Copyright (C) 2024 Potix Corporation. All Rights Reserved // History: 2024/2/13 1:50 PM // Author: jumperchen @@ -29,4 +29,4 @@ Map PACKET_TYPES_REVERSE = { for (var entry in PacketTypeMap.entries) '${entry.value}': entry.key, }; -const ERROR_PACKET = const {'type': 'error', 'data': 'parser error'}; \ No newline at end of file +const ERROR_PACKET = const {'type': 'error', 'data': 'parser error'}; diff --git a/lib/src/engine/parser/decodePacket.dart b/lib/src/engine/parser/decodePacket.dart index bf5ca2d..5632389 100644 --- a/lib/src/engine/parser/decodePacket.dart +++ b/lib/src/engine/parser/decodePacket.dart @@ -39,4 +39,4 @@ decodePacket(dynamic encodedPacket, binaryType) { } else { return {'type': PACKET_TYPES_REVERSE[type]}; } -} \ No newline at end of file +} diff --git a/lib/src/engine/parser/encodePacket.dart b/lib/src/engine/parser/encodePacket.dart index 33e994d..ae51ace 100644 --- a/lib/src/engine/parser/encodePacket.dart +++ b/lib/src/engine/parser/encodePacket.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2024 Potix Corporation. All Rights Reserved +// Copyright (C) 2024 Potix Corporation. All Rights Reserved // History: 2024/2/13 1:46 PM // Author: jumperchen import 'dart:convert'; @@ -8,7 +8,9 @@ import 'commons.dart'; encodePacket(Packet packet, bool supportsBinary, callback(_)) { if (packet.data is ByteBuffer || packet.data is Uint8List) { - return callback(supportsBinary ? packet.data : 'b' + base64Encode(toBuffer(packet.data, true))); + return callback(supportsBinary + ? packet.data + : 'b' + base64Encode(toBuffer(packet.data, true))); } else { // plain string return callback('${PacketTypeMap[packet.type]}' + (packet.data ?? '')); @@ -49,4 +51,4 @@ class TextEncoder { Uint8List encode(String input) { return Uint8List.fromList(utf8.encode(input)); } -} \ No newline at end of file +} diff --git a/lib/src/parser/is_binary.dart b/lib/src/parser/is_binary.dart index 44be71f..313518c 100644 --- a/lib/src/parser/is_binary.dart +++ b/lib/src/parser/is_binary.dart @@ -15,36 +15,48 @@ bool isBinary(obj) { } bool hasBinary(obj, [bool toJSON = false]) { - if (obj == null || (obj is! Map && obj is! List)) { + if (obj == null) { return false; } - if (obj is List && obj is! ByteBuffer && obj is! Uint8List) { - for (var i = 0, l = obj.length; i < l; i++) { - if (hasBinary(obj[i])) { + + if (obj is List && obj is! TypedData) { + for (var value in obj) { + if (hasBinary(value)) { return true; } } - return false; } + if (isBinary(obj)) { return true; } - if (obj['toJSON'] != null && obj['toJSON'] is Function && toJSON == false) { - return hasBinary(obj.toJSON(), true); + // Check if the object has a toJSON method, regardless of its type (Map, custom object, etc.) + var toJsonMethod = _getToJsonMethod(obj); + if (toJsonMethod != null && toJSON == false) { + return hasBinary(toJsonMethod(), true); } + if (obj is Map) { for (var entry in obj.entries) { if (hasBinary(entry.value)) { return true; } } - } else if (obj is List) { - for (var value in obj) { - if (hasBinary(value)) { - return true; - } - } } + return false; } + +// Helper function to dynamically check if an object has a toJSON method +Function? _getToJsonMethod(obj) { + try { + var toJsonMethod = obj.toJSON; + if (toJsonMethod is Function) { + return toJsonMethod; + } + } catch (e) { + // Catch and ignore errors if the method is not present + } + return null; +} diff --git a/pubspec.yaml b/pubspec.yaml index 8a6fc9c..f57d9e0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: socket_io_common description: Socket.io common parser library. -version: 3.0.0-beta.0 +version: 3.0.0 homepage: https://www.zkoss.org repository: https://github.com/rikulo/socket_io_common issue_tracker: https://github.com/rikulo/socket_io_common/issues @@ -9,4 +9,8 @@ environment: sdk: '>=3.0.0 <4.0.0' dependencies: - logging: '^1.2.0' \ No newline at end of file + logging: '^1.2.0' + +dev_dependencies: + lints: ^4.0.0 + test: ">=1.3.0 <2.0.0" \ No newline at end of file diff --git a/test/isBinary.test.dart b/test/isBinary.test.dart new file mode 100644 index 0000000..208eb5a --- /dev/null +++ b/test/isBinary.test.dart @@ -0,0 +1,97 @@ +import 'dart:typed_data'; + +import 'package:socket_io_common/src/parser/is_binary.dart'; + +createMap(TypedData? byteData) => { + "child": byteData, + }; + +createMapWithArray(TypedData? byteData) => { + "child": [byteData] + }; + +createDeepMap(TypedData? byteData) => { + "child": { + "deep": {"deep": byteData} + }, + }; + +createDeepMapWithArray(TypedData? byteData) => { + "child": { + "deep": { + "deep": [byteData] + } + }, + }; + +createArray(TypedData? byteData) => [byteData]; + +createArrayInArray(TypedData? byteData) => [ + [byteData] + ]; + +createArrayWithMap(TypedData? byteData) => [createMap(byteData)]; + +createArrayWithDeepMap(TypedData? byteData) => [createDeepMap(byteData)]; + +createMapWithToJson(TypedData? byteData) => { + "toJSON": () => {"child": byteData} + }; + +main() { + final byteData = ByteData(1); + + // ------------- + print("With ByteBuffer: ${hasBinary(byteData.buffer)}"); + print("With ByteData: ${hasBinary(byteData)}"); + print("-" * 30); + // ------------- + print("With map and binary: ${hasBinary(createMap(byteData))}"); + print("With map and null: ${hasBinary(createMap(null))}"); + print("-" * 30); + // ------------- + print( + "With map with array and binary: ${hasBinary(createMapWithArray(byteData))}"); + print("With map with array and null: ${hasBinary(createMapWithArray(null))}"); + print("-" * 30); + // ------------- + print("With deep map and binary: ${hasBinary(createDeepMap(byteData))}"); + print("With deep map and null: ${hasBinary(createDeepMap(null))}"); + print("-" * 30); + // ------------- + print( + "With deep map with array and binary: ${hasBinary(createDeepMapWithArray(byteData))}"); + print( + "With deep map with array and null: ${hasBinary(createDeepMapWithArray(null))}"); + print("-" * 30); + // ------------- + print("With array and binary: ${hasBinary(createArray(byteData))}"); + print("With array and null: ${hasBinary(createArray(null))}"); + print("-" * 30); + // ------------- + print( + "With array in array and binary: ${hasBinary(createArrayInArray(byteData))}"); + print("With array in array and null: ${hasBinary(createArrayInArray(null))}"); + print("-" * 30); + // ------------- + print( + "With array with map and binary: ${hasBinary(createArrayWithMap(byteData))}"); + print("With array with map and null: ${hasBinary(createArrayWithMap(null))}"); + print("-" * 30); + // ------------- + print( + "With array with deep map and binary: ${hasBinary(createArrayWithDeepMap(byteData))}"); + print( + "With array with deep map and null: ${hasBinary(createArrayWithDeepMap(null))}"); + print("-" * 30); + // ------------- + print("With toJSON and binary: ${hasBinary(createMapWithToJson(byteData))}"); + print("With toJSON and null: ${hasBinary(createMapWithToJson(null))}"); + print("With toJSON from an Object: ${hasBinary(MyObject())}"); +} + +class MyObject { + Map toJSON() { + return {"child": ByteData(1)}; + } +}