fromBytes static method

SVCBResponseRecord fromBytes({
  1. required String name,
  2. required int ttl,
  3. required Uint8List bytes,
  4. required int offset,
  5. required int length,
})

Implementation

static SVCBResponseRecord fromBytes({
    required String name,
    required int ttl,
    required Uint8List bytes,
    required int offset,
    required int length }) {

    if (length < 3 || (offset + length) > bytes.length) {
        throw FormatException('Invalid SVCB record: too short or out of range');
    }

    final int priority = (bytes[offset] << 8) | bytes[offset + 1];
    final (int newOffset, String target) = DNSHelper.parseDomainName(bytes, offset + 2);
    final Map<int, Uint8List> encoded = { };

    int pOffset = newOffset;
    while (pOffset < offset + length) {
        if (pOffset + 4 > bytes.length) {
            break;
        }

        final int key = (bytes[pOffset] << 8) | bytes[pOffset + 1];
        final int valueLen = (bytes[pOffset + 2] << 8) | bytes[pOffset + 3];
        pOffset += 4;

        if (pOffset + valueLen > bytes.length) {
            break;
        }

        final value = bytes.sublist(pOffset, pOffset + valueLen);
        encoded[key] = value;
        pOffset += valueLen;
    }

    final Map<String, String> decoded = { };
    for (final entry in encoded.entries) {
        final key = entry.key;
        final value = entry.value;

        // Ejemplos comunes
        switch (key) {
            case 1:
                decoded['alpn'] = utf8.decode(value, allowMalformed: true);
                break;
            case 3:
                decoded['port'] = value.fold(0, (a, b) => (a << 8) + b).toString();
                break;
            case 4:
                decoded['ipv4hint'] = value.map((b) => b.toString()).join('.');
                break;
            case 6:
                decoded['ipv6hint'] = value
                    .buffer.asUint8List()
                    .map((b) => b.toRadixString(16).padLeft(2, '0'))
                    .join(':')
                    .replaceAll(RegExp(r'(:0+)+(:|$)'), '::');
                break;
            default:
                decoded[key.toString()] = value.map((b) => b.toRadixString(16).padLeft(2, '0')).join('');
        }
    }

    return SVCBResponseRecord(
        name: name,
        ttl: ttl,
        priority: priority,
        target: target,
        params: decoded);
}