ResultList constructor

ResultList(
  1. Version version,
  2. Edge? solution,
  3. MinimalEncoder context
)

Implementation

ResultList(Version version, Edge? solution, MinimalEncoder context)
    : super(context) {
  int length = 0;
  Edge? current = solution;
  bool containsECI = false;

  while (current != null) {
    length += current.characterLength;
    final previous = current.previous;

    final needECI = current.mode == Mode.BYTE &&
            (previous == null &&
                current.charsetEncoderIndex !=
                    0) || // at the beginning and charset is not ISO-8859-1
        (previous != null &&
            current.charsetEncoderIndex != previous.charsetEncoderIndex);

    if (needECI) {
      containsECI = true;
    }

    if (previous == null || previous.mode != current.mode || needECI) {
      list.insert(
        0,
        ResultNode(
          current.mode,
          current.fromPosition,
          current.charsetEncoderIndex,
          length,
          this,
        ),
      );
      length = 0;
    }

    if (needECI) {
      list.insert(
        0,
        ResultNode(
          Mode.ECI,
          current.fromPosition,
          current.charsetEncoderIndex,
          0,
          this,
        ),
      );
    }
    current = previous;
  }

  // prepend FNC1 if needed. If the bits contain an ECI then the FNC1 must be preceeded by an ECI.
  // If there is no ECI at the beginning then we put an ECI to the default charset (ISO-8859-1)
  if (context.isGS1) {
    ResultNode first = list[0];
    if (first.mode != Mode.ECI && containsECI) {
      // prepend a default character set ECI
      list.insert(0, ResultNode(Mode.ECI, 0, 0, 0, this));
    }
    first = list[0];
    // prepend or insert a FNC1_FIRST_POSITION after the ECI (if any)
    list.insert(
      first.mode != Mode.ECI ? 0 : 1,
      ResultNode(Mode.FNC1_FIRST_POSITION, 0, 0, 0, this),
    );
  }

  // set version to smallest version into which the bits fit.
  int versionNumber = version.versionNumber;
  int lowerLimit;
  int upperLimit;
  switch (MinimalEncoder.getVersionSize(version)) {
    case VersionSize.SMALL:
      lowerLimit = 1;
      upperLimit = 9;
      break;
    case VersionSize.MEDIUM:
      lowerLimit = 10;
      upperLimit = 26;
      break;
    case VersionSize.LARGE:
    default:
      lowerLimit = 27;
      upperLimit = 40;
      break;
  }
  final size = getSize(version);
  // increase version if needed
  while (versionNumber < upperLimit &&
      !Encoder.willFit(
        size,
        Version.getVersionForNumber(versionNumber),
        context.ecLevel,
      )) {
    versionNumber++;
  }
  // shrink version if possible
  while (versionNumber > lowerLimit &&
      Encoder.willFit(
        size,
        Version.getVersionForNumber(versionNumber - 1),
        context.ecLevel,
      )) {
    versionNumber--;
  }
  this.version = Version.getVersionForNumber(versionNumber);
}