Skip to content

Commit

Permalink
V3.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mrtnetwork committed Oct 1, 2024
1 parent 85e82b6 commit 559a6bf
Show file tree
Hide file tree
Showing 15 changed files with 83 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## 3.4.0

- Stellar Address Support: Add support for stellar Contract address.
- Fix incorrect CBOR encoding of large negative integers.

## 3.3.0

Expand Down
2 changes: 2 additions & 0 deletions lib/cbor/cbor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ library cbor;
export 'core/cbor.dart';

export 'types/types.dart';

export 'exception/exception.dart';
11 changes: 7 additions & 4 deletions lib/cbor/core/cbor.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:blockchain_utils/cbor/exception/exception.dart';
import 'package:blockchain_utils/utils/utils.dart';
import 'package:blockchain_utils/cbor/types/types.dart';
import 'package:blockchain_utils/cbor/utils/cbor_utils.dart';
import 'package:blockchain_utils/exception/exception.dart';

/// An abstract class representing a CBOR (Concise Binary Object Representation) object.
/// CBOR objects can hold various data types and optional tags, providing a flexible way
Expand Down Expand Up @@ -49,12 +49,15 @@ abstract class CborObject {
} else if (value is List<List<int>>) {
return CborDynamicBytesValue(value);
} else if (value is Map) {
return CborMapValue.fixedLength(value);
return CborMapValue.fixedLength({
for (final i in value.entries)
CborObject.fromDynamic(i.key): CborObject.fromDynamic(i.value)
});
} else if (value is List<dynamic>) {
return CborListValue.fixedLength(
value.map((e) => CborObject.fromDynamic(e)).toList());
}
throw UnimplementedError("does not supported");
throw const CborException("does not supported");
}
}

Expand All @@ -73,7 +76,7 @@ abstract class CborNumeric implements CborObject {
} else if (val is CborSafeIntValue) {
return val.value;
}
throw const ArgumentException("invalid cbornumeric");
throw const CborException("invalid cbornumeric");
}

/// Convert the CborNumeric object to an integer.
Expand Down
6 changes: 6 additions & 0 deletions lib/cbor/exception/exception.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import 'package:blockchain_utils/exception/exceptions.dart';

class CborException extends BlockchainUtilsException {
const CborException(String message, {Map<String, dynamic>? details})
: super(message, details: details);
}
6 changes: 3 additions & 3 deletions lib/cbor/types/bytes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ class CborBytesValue implements CborObject {
/// It accepts the bytes value.
CborBytesValue(List<int> value) : value = value.asImmutableBytes;

/// The value as a List<int>.
@override
final List<int> value;

/// Encode the value into CBOR bytes
Expand Down Expand Up @@ -51,6 +49,8 @@ class CborDynamicBytesValue implements CborObject {

@override
final List<List<int>> value;
// @override
// List<List<int>> get value => _value;

/// Encode the value into CBOR bytes
@override
Expand Down Expand Up @@ -82,7 +82,7 @@ class CborDynamicBytesValue implements CborObject {
operator ==(other) {
if (other is! CborDynamicBytesValue) return false;

return value == other.value;
return CompareUtils.iterableIsEqual(value, other.value);
}

/// ovveride hash code
Expand Down
2 changes: 1 addition & 1 deletion lib/cbor/types/cbor_tag.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CborTagValue<T> implements CborObject {
List<int> encode() {
final bytes = CborBytesTracker();
bytes.pushTags(tags);
final obj = CborObject.fromDynamic(value).encode();
final obj = CborObject.fromDynamic(_value).encode();
bytes.pushBytes(obj);
return bytes.toBytes();
}
Expand Down
4 changes: 1 addition & 3 deletions lib/cbor/types/decimal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ class CborDecimalFracValue implements CborObject {

/// Create a CborBigFloatValue from two CborNumeric values representing the exponent and mantissa.
factory CborDecimalFracValue.fromCborNumeric(
CborNumeric exponent,
CborNumeric mantissa,
) {
CborNumeric exponent, CborNumeric mantissa) {
return CborDecimalFracValue(CborNumeric.getCborNumericValue(exponent),
CborNumeric.getCborNumericValue(mantissa));
}
Expand Down
10 changes: 7 additions & 3 deletions lib/cbor/types/int.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:blockchain_utils/cbor/core/cbor.dart';
import 'package:blockchain_utils/cbor/exception/exception.dart';
import 'package:blockchain_utils/cbor/utils/dynamic_bytes.dart';
import 'package:blockchain_utils/cbor/core/tags.dart';
import 'package:blockchain_utils/utils/utils.dart';
Expand All @@ -20,10 +21,13 @@ class CborIntValue implements CborNumeric {
List<int> encode() {
final bytes = CborBytesTracker();
if (value.bitLength > 31 && value.isNegative) {
final value = (~BigInt.parse(this.value.toString())).toInt();
bytes.pushInt(MajorTags.negInt, value);
final value = (~BigInt.parse(this.value.toString()));
if (!value.isValidInt) {
throw CborException("Value is to large for encoding as CborInteger",
details: {"value": this.value.toString()});
}
bytes.pushInt(MajorTags.negInt, value.toInt());
} else {
// print("is here lower!");
bytes.pushInt(value.isNegative ? MajorTags.negInt : MajorTags.posInt,
value.isNegative ? ~value : value);
}
Expand Down
10 changes: 2 additions & 8 deletions lib/cbor/types/list.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:blockchain_utils/helper/helper.dart';
import 'package:blockchain_utils/utils/utils.dart';
import 'package:blockchain_utils/cbor/utils/dynamic_bytes.dart';
import 'package:blockchain_utils/cbor/core/tags.dart';
Expand All @@ -9,18 +8,13 @@ class CborListValue<T> implements CborObject {
/// Constructor for creating a CborListValue instance with the provided parameters.
/// It accepts the List of all cbor encodable value.
///
CborListValue.fixedLength(List<T> value)
: value = value.immutable,
_isFixedLength = true;
CborListValue.fixedLength(this.value) : _isFixedLength = true;

/// Constructor for creating a CborListValue instance with the provided parameters.
/// It accepts the List of all cbor encodable value.
/// this method encode values with indefinite tag.
CborListValue.dynamicLength(List<T> value)
: value = value.immutable,
_isFixedLength = false;
CborListValue.dynamicLength(this.value) : _isFixedLength = false;

/// value as List
@override
final List<T> value;

Expand Down
9 changes: 2 additions & 7 deletions lib/cbor/types/map.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'package:blockchain_utils/helper/helper.dart';
import 'package:blockchain_utils/utils/utils.dart';
import 'package:blockchain_utils/cbor/utils/dynamic_bytes.dart';
import 'package:blockchain_utils/cbor/core/tags.dart';
Expand All @@ -8,16 +7,12 @@ import 'package:blockchain_utils/cbor/core/cbor.dart';
class CborMapValue<K, V> implements CborObject {
/// Constructor for creating a CborMapValue instance with the provided parameters.
/// It accepts the Map with all cbor encodable key and value.
CborMapValue.fixedLength(Map<K, V> value)
: value = value.immutable,
_isFixedLength = true;
CborMapValue.fixedLength(this.value) : _isFixedLength = true;

/// Constructor for creating a CborMapValue instance with the provided parameters.
/// It accepts the Map with all cbor encodable key and value.
/// this method encode values with indefinite tag.
CborMapValue.dynamicLength(Map<K, V> value)
: value = value.immutable,
_isFixedLength = false;
CborMapValue.dynamicLength(this.value) : _isFixedLength = false;

/// value as Map
@override
Expand Down
2 changes: 1 addition & 1 deletion lib/cbor/types/set.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:blockchain_utils/cbor/core/cbor.dart';
class CborSetValue<T> implements CborObject {
/// Constructor for creating a CborSetValue instance with the provided parameters.
/// It accepts a set of all encodable cbor object.
CborSetValue(Set<T> value) : value = Set.unmodifiable(value);
CborSetValue(this.value);

/// value as set
@override
Expand Down
1 change: 0 additions & 1 deletion lib/cbor/types/string.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ class CborIndefiniteStringValue extends CborString {
/// It accepts a List<String> value.
CborIndefiniteStringValue(List<String> value) : value = value.immutable;

/// value as List<String>
@override
final List<String> value;

Expand Down
14 changes: 7 additions & 7 deletions lib/cbor/utils/cbor_utils.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'dart:typed_data';
import 'package:blockchain_utils/cbor/core/cbor.dart';
import 'package:blockchain_utils/cbor/exception/exception.dart';
import 'package:blockchain_utils/cbor/types/types.dart';
import 'package:blockchain_utils/cbor/utils/float_utils.dart';
import 'package:blockchain_utils/cbor/core/tags.dart';
import 'package:blockchain_utils/exception/exception.dart';
import 'package:blockchain_utils/utils/utils.dart';

class CborUtils {
Expand All @@ -23,7 +23,7 @@ class CborUtils {
// Split the string into the date and offset parts
final parts = dateTimeString.split('+');
if (parts.length != 2) {
throw MessageException("Invalid format: $dateTimeString");
throw CborException("Invalid RFC3339 format: $dateTimeString");
}
final datePart = DateTime.parse(parts[0]);
return datePart;
Expand Down Expand Up @@ -66,11 +66,11 @@ class CborUtils {
}
return _decodeArray(cborBytes, i, info, tags);
default:
throw ArgumentException(
throw CborException(
"invalid or unsuported cbor tag major: $majorTag ");
}
}
throw const ArgumentException("invalid or unsuported cbor tag");
throw const CborException("invalid or unsuported cbor tag");
}

static Tuple<List<int>, int> _parsBytes(int info, List<int> cborBytes) {
Expand All @@ -96,7 +96,7 @@ class CborUtils {
}
return Tuple(decode, len + 1);
} else {
throw ArgumentException('Invalid additional info for int: $info');
throw CborException('Invalid additional info for int: $info');
}
}

Expand Down Expand Up @@ -254,7 +254,7 @@ class CborUtils {
List<CborObject> objects, List<int> tags) {
objects = objects.whereType<CborNumeric>().toList();
if (objects.length != 2) {
throw const MessageException("invalid bigFloat array length");
throw const CborException("invalid bigFloat array length");
}
if (BytesUtils.bytesEqual(tags, CborTags.decimalFrac)) {
tags.clear();
Expand Down Expand Up @@ -313,7 +313,7 @@ class CborUtils {
offset = offset + 8;
break;
default:
throw const MessageException("Invalid simpleOrFloatTags");
throw const CborException("Invalid simpleOrFloatTags");
}
if (BytesUtils.bytesEqual(tags, CborTags.dateEpoch)) {
final dt = DateTime.fromMillisecondsSinceEpoch((val * 1000).round());
Expand Down
10 changes: 5 additions & 5 deletions lib/cbor/utils/float_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import 'dart:math' as math;
import 'dart:typed_data';

import 'package:blockchain_utils/cbor/core/tags.dart';
import 'package:blockchain_utils/exception/exception.dart';
import 'package:blockchain_utils/cbor/exception/exception.dart';
import 'package:blockchain_utils/utils/utils.dart';

// Enum representing different floating-point formats and their characteristics.
Expand Down Expand Up @@ -60,7 +60,7 @@ class FloatLength {
if (index >= 0 && index < values.length) {
return values[index];
}
throw MessageException('Index out of bounds', details: {"input": index});
throw CborException('Index out of bounds', details: {"input": index});
}
}

Expand Down Expand Up @@ -242,13 +242,13 @@ class FloatUtils {
switch (decodFloatType) {
case FloatLength.bytes16:
if (!isLessThan16) {
throw const ArgumentException("overflow bytes");
throw const CborException("overflow bytes");
}
bytes = _encodeFloat16(endianness);
break;
case FloatLength.bytes32:
if (!isLessThan32) {
throw const ArgumentException("overflow bytes");
throw const CborException("overflow bytes");
}
bytes = _encodeFloat32(endianness);
break;
Expand All @@ -262,7 +262,7 @@ class FloatUtils {
/// Decode a 16-bit floating-point value from a byte array and return it as a double.
static double floatFromBytes16(List<int> bytes) {
if (bytes.length != 2) {
throw const ArgumentException(
throw const CborException(
'Input byte array must be exactly 2 bytes long for Float16');
}

Expand Down
39 changes: 38 additions & 1 deletion lib/utils/compare/compare.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,49 @@ class CompareUtils {

/// Compare the individual byte values in 'a' and 'b'.
for (int index = 0; index < a.length; index += 1) {
if (a.elementAt(index) != b.elementAt(index)) {
final valueA = a.elementAt(index);
final valueB = b.elementAt(index);
if (valueA is Map && valueB is Map) {
// Recursively compare maps
if (!mapIsEqual(valueA, valueB)) return false;
} else if (valueA is Iterable && valueB is Iterable) {
// Recursively compare iterables
if (!iterableIsEqual(valueA, valueB)) return false;
} else if (valueA != valueB) {
return false;
}
}

/// If no differences were found, the lists are equal.
return true;
}

static bool mapIsEqual<K, V>(Map<K, V>? a, Map<K, V>? b) {
// Handle null comparison
if (a == null) return b == null;
if (b == null || a.length != b.length) return false;

// Check if 'a' and 'b' are identical objects
if (identical(a, b)) return true;

// Compare the entries in 'a' and 'b'
for (final key in a.keys) {
if (!b.containsKey(key)) return false;

final valueA = a[key];
final valueB = b[key];

if (valueA is Map && valueB is Map) {
// Recursively compare maps
if (!mapIsEqual(valueA, valueB)) return false;
} else if (valueA is Iterable && valueB is Iterable) {
// Recursively compare iterables
if (!iterableIsEqual(valueA, valueB)) return false;
} else if (valueA != valueB) {
return false;
}
}

return true;
}
}

0 comments on commit 559a6bf

Please sign in to comment.