| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:collection'; |
| import 'dart:convert'; |
| import 'dart:math'; |
| import 'dart:typed_data'; |
| |
| import 'package:collection/collection.dart'; |
| import 'package:crypto/crypto.dart'; |
| |
| import 'document/values/converter.dart'; |
| |
| // TODO: consider short function names and importing with prefix. |
| |
| /// Concatenate two byte arrays. |
| Uint8List concatUint8Lists(Uint8List a, Uint8List b) { |
| return Uint8List(a.length + b.length)..setAll(0, a)..setAll(a.length, b); |
| } |
| |
| // TODO: consider using Iterable instead of List. |
| /// Concatenate list of byte arrays. |
| Uint8List concatListOfUint8Lists(List<Uint8List> list) { |
| int sumLength = 0; |
| for (final x in list) { |
| sumLength += x.length; |
| } |
| final result = Uint8List(sumLength); |
| int pos = 0; |
| for (final x in list) { |
| result.setAll(pos, x); |
| pos += x.length; |
| } |
| return result; |
| } |
| |
| /// Returns a _view_ of a region of [x] starting at [start] (inclusive) and |
| /// ending at [end] (exclusive). |
| Uint8List getSublistView(Uint8List x, {int start = 0, int end}) { |
| end ??= x.length; |
| return UnmodifiableUint8ListView( |
| x.buffer.asUint8List(x.offsetInBytes + start, end - start)); |
| } |
| |
| /// Returns a Uint8List created from the utf8 encoding of [string]. |
| /// [string] must be non-null. |
| Uint8List getUint8ListFromString(String string) { |
| return Uint8List.fromList(utf8.encode(string)); |
| } |
| |
| /// Returns a Uint8List created from the binary encoding of [number]. |
| Uint8List getUint8ListFromNumber(num number) { |
| IntConverter converter = IntConverter(); |
| return converter.serialize(number); |
| } |
| |
| /// Returns a new HashMap with Uint8Lists as a keys. |
| /// Note: The type T is enforced only at compile time. |
| HashMap<Uint8List, T> newUint8ListMap<T>() { |
| const listEquality = ListEquality<int>(); |
| return HashMap<Uint8List, T>( |
| equals: listEquality.equals, hashCode: listEquality.hash); |
| } |
| |
| /// Returns true if `a` and `b` are equal. |
| /// Returns false otherwise. |
| bool uint8ListsAreEqual(Uint8List a, Uint8List b) { |
| if (a == b) { |
| return true; |
| } |
| const listEquality = ListEquality<int>(); |
| return listEquality.equals(a, b); |
| } |
| |
| /// Compares lists `a` and `b`. |
| /// Returns 0 if the content of the two list is equal. |
| /// Returns a number less than 0 if `a` is short or lexicographical before `b`. |
| /// Returns a number greater than 0 otherwise. |
| int _compareLists(List a, List b) { |
| final minLength = min(a.length, b.length); |
| for (int i = 0; i < minLength; i++) { |
| if (a[i] != b[i]) { |
| return a[i] - b[i]; |
| } |
| } |
| // Missing parts come before present ones. |
| return a.length.compareTo(b.length); |
| } |
| |
| /// Returns a new ordered HashMap with Uint8Lists as a keys. |
| /// Note: The type T is enforced only at compile time. |
| SplayTreeMap<Uint8List, T> newUint8ListOrderedMap<T>() { |
| return SplayTreeMap<Uint8List, T>(_compareLists); |
| } |
| |
| /// Returns a 20 bytes long hash of [data]. |
| Uint8List hash(Uint8List data) { |
| final iterable = sha256.convert(data).bytes.getRange(0, 20); |
| return Uint8List.fromList(List.from(iterable)); |
| } |
| |
| final _random = Random.secure(); |
| |
| /// Returns a list of random bytes of a given [length]. |
| Uint8List randomUint8List(int length) { |
| final result = Uint8List(length); |
| for (int i = 0; i < length; i++) { |
| result[i] = _random.nextInt(256); |
| } |
| return result; |
| } |
| |
| /// Checks if [keyPrefix] is the prefix of the [key]. |
| /// Both [keyPrefix] and [key] must not be null. |
| bool hasPrefix(Uint8List key, Uint8List keyPrefix) { |
| if (keyPrefix.length > key.length) { |
| return false; |
| } |
| for (int i = 0; i < keyPrefix.length; i++) { |
| if (key[i] != keyPrefix[i]) { |
| return false; |
| } |
| } |
| return true; |
| } |