decodeFields static method

ProtoBufferDecoderResult decodeFields(
  1. List<int> bytes,
  2. List<ProtoFieldConfig> tags, {
  3. ProtoSyntax syntax = ProtoSyntax.v3,
})

Implementation

static ProtoBufferDecoderResult decodeFields(
  List<int> bytes,
  List<ProtoFieldConfig> tags, {
  ProtoSyntax syntax = ProtoSyntax.v3,
}) {
  final List<ProtoBufferDecodedField> results = [];
  int index = 0;
  while (index < bytes.length) {
    final decodeTag = decodeVarint32(bytes, index);
    index += decodeTag.consumed;
    final int tag = decodeTag.value;
    final int fieldId = tag >> 3;
    final int wireType = tag & 0x07;
    final type = ProtoWireType.fromValue(wireType);
    final config = tags.firstWhereNullable((e) => e.fieldNumber == fieldId);
    if (config == null) {
      index += type.skip(bytes, index);
      continue;
    }
    final decode = _decode(bytes, config, offset: index);
    index += decode.consumed;
    results.add(decode);
  }
  // results.sort((a, b) {});
  List<ProtoBufferDecodedField> finalResult = [];
  for (final i in tags) {
    final same =
        results.where((e) => e.fieldNumber == i.fieldNumber).toList();
    if (same.isEmpty) continue;
    final haveMulti =
        i.fieldType == ProtoFieldType.repeated ||
        i.fieldType == ProtoFieldType.map;
    if (!haveMulti) {
      finalResult.addAll(same);
      continue;
    }
    finalResult.add(
      ProtoBufferDecodedField(
        value: same.map((e) => e.value).expand((e) => e).toList(),
        config: i,
        consumed: same.fold(0, (p, c) => p + c.consumed),
      ),
    );
  }

  return ProtoBufferDecoderResult(fields: finalResult, syntax: syntax);
}