result static method

Map<String, dynamic> result(
  1. String action,
  2. Map<String, dynamic> raw, {
  3. List<String> allowedRecordTypes = const ['text', 'uri'],
  4. int recordLimit = maxRecords,
  5. int byteLimit = maxMessageBytes,
})

Implementation

static Map<String, dynamic> result(
  String action,
  Map<String, dynamic> raw, {
  List<String> allowedRecordTypes = const ['text', 'uri'],
  int recordLimit = maxRecords,
  int byteLimit = maxMessageBytes,
}) {
  if (action == 'nfc.getState') {
    final supported = raw['supported'];
    final enabled = raw['enabled'];
    if (supported is! bool || enabled is! bool || (!supported && enabled)) {
      throw const FormatException('Invalid NFC availability result.');
    }
    return {'supported': supported, 'enabled': enabled};
  }
  if (action != 'nfc.read' ||
      recordLimit < 1 ||
      recordLimit > maxRecords ||
      byteLimit < 1 ||
      byteLimit > maxMessageBytes) {
    throw const FormatException('Invalid NFC result limits.');
  }
  final allowed = recordTypes(allowedRecordTypes);
  final records = raw['records'];
  if (records is! List || records.isEmpty || records.length > recordLimit) {
    throw const FormatException('Invalid NFC record count.');
  }
  var totalBytes = 0;
  final normalized = <Map<String, dynamic>>[];
  for (final record in records) {
    if (record is! Map || !allowed.contains(record['type'])) {
      throw const FormatException('Unsupported NFC record type.');
    }
    if (record['type'] == 'text') {
      final text = _text(record['text'], maxTextBytes);
      final language = record['language'];
      if (language is! String ||
          language.length > 63 ||
          !RegExp(r'^[a-zA-Z0-9-]*$').hasMatch(language)) {
        throw const FormatException('Invalid NFC text language.');
      }
      totalBytes += utf8.encode(text).length + language.length;
      normalized.add({'type': 'text', 'text': text, 'language': language});
    } else {
      final uri = _text(record['uri'], maxUriBytes);
      final parsed = Uri.tryParse(uri);
      if (parsed == null ||
          parsed.scheme != 'https' ||
          parsed.host.isEmpty ||
          parsed.userInfo.isNotEmpty ||
          RegExp(r'\s|[\\\x00-\x1f\x7f-\x9f]').hasMatch(uri) ||
          RegExp(
            r'%(?:0[0-9a-f]|1[0-9a-f]|7f)',
            caseSensitive: false,
          ).hasMatch(uri)) {
        throw const FormatException('Expected an absolute HTTPS NFC URI.');
      }
      totalBytes += utf8.encode(uri).length;
      normalized.add({'type': 'uri', 'uri': uri});
    }
    if (totalBytes > byteLimit) {
      throw const FormatException(
        'NFC record data exceeds accepted byte limits.',
      );
    }
  }
  return {'records': normalized};
}