deserialize method

  1. @override
void deserialize(
  1. RubyExternalScannerState state,
  2. Uint8List data
)
override

Implementation

@override
void deserialize(RubyExternalScannerState state, Uint8List data) {
  state.hasLeadingWhitespace = false;
  state.literalStack.clear();
  state.openHeredocs.clear();
  if (data.isEmpty) return;

  var position = 0;
  int take() {
    if (position >= data.length) {
      throw const FormatException('Truncated Ruby external-scanner state');
    }
    return data[position++];
  }

  final literalDepth = take();
  for (var index = 0; index < literalDepth; index++) {
    final typeIndex = take();
    if (typeIndex >= RubyExternalToken.values.length) {
      throw const FormatException('Invalid Ruby literal token type');
    }
    state.literalStack.add(
      RubyLiteral(
        type: RubyExternalToken.values[typeIndex],
        openDelimiter: take(),
        closeDelimiter: take(),
        nestingDepth: take(),
        allowsInterpolation: take() != 0,
      ),
    );
  }
  final heredocCount = take();
  for (var index = 0; index < heredocCount; index++) {
    final indentationAllowed = take() != 0;
    final allowsInterpolation = take() != 0;
    final started = take() != 0;
    final wordLength = take();
    if (wordLength > data.length - position) {
      throw const FormatException('Truncated Ruby heredoc word');
    }
    state.openHeredocs.add(
      RubyHeredoc(
        word: data.sublist(position, position + wordLength),
        endWordIndentationAllowed: indentationAllowed,
        allowsInterpolation: allowsInterpolation,
        started: started,
      ),
    );
    position += wordLength;
  }
  // The C++ assertion is disabled, so trailing bytes are accepted.
}