package com.intellij.flex.uiDesigner.abc;
import com.intellij.util.ArrayUtil;
import static com.intellij.flex.uiDesigner.abc.ActionBlockConstants.*;
final class Scanner {
private Scanner() {
}
public static int[] scanIntConstants(DataBuffer in) {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 1; i < size; i++) {
positions[i] = in.position();
in.readU32();
}
return positions;
}
public static int[] scanDoubleConstants(DataBuffer in) {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 1; i < size; i++) {
positions[i] = in.position();
in.readDouble();
}
return positions;
}
public static int[] scanStrConstants(DataBuffer in) {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 1; i < size; i++) {
positions[i] = in.position();
int length = in.readU32();
in.skip(length);
}
return positions;
}
public static int[] scanNsConstants(DataBuffer in) {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 1; i < size; i++) {
positions[i] = in.position();
in.skip(1); // kind byte
in.readU32();
}
return positions;
}
public static int[] scanNsSetConstants(DataBuffer in) {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 1; i < size; i++) {
positions[i] = in.position();
in.skipEntries(in.readU32());
}
return positions;
}
public static int[] scanMultinameConstants(DataBuffer in) {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 1; i < size; i++) {
positions[i] = in.position();
int kind = in.readU8(); // kind byte
switch (kind) {
case CONSTANT_Qname:
case CONSTANT_QnameA:
in.readU32();
in.readU32();
break;
case CONSTANT_RTQname:
case CONSTANT_RTQnameA:
in.readU32();
break;
case CONSTANT_Multiname:
case CONSTANT_MultinameA:
in.readU32();
in.readU32();
break;
case CONSTANT_RTQnameL:
case CONSTANT_RTQnameLA:
break;
case CONSTANT_MultinameL:
case CONSTANT_MultinameLA:
in.readU32();
break;
case CONSTANT_TypeName:
in.readU32(); // name index
in.skipEntries(in.readU32());
break;
default:
throw new DecoderException("Invalid constant type: " + kind);
}
}
return positions;
}
public static int[] scanMethods(DataBuffer in) {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 0; i < size; i++) {
positions[i] = in.position();
int paramCount = in.readU32();
in.readU32(); // ret type
in.skipEntries(paramCount);
in.readU32(); //name_index
int flags = in.readU8();
long optionalCount = ((flags & METHOD_HasOptional) != 0) ? in.readU32() : 0;
for (long q = 0; q < optionalCount; ++q) {
in.readU32();
in.readU8();
}
long paramNameCount = ((flags & METHOD_HasParamNames) != 0) ? paramCount : 0;
for (long q = 0; q < paramNameCount; ++q) {
in.readU32();
}
}
return positions;
}
public static int[] scanMetadata(DataBuffer in) {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 0; i < size; i++) {
positions[i] = in.position();
in.readU32();
in.skipEntries(in.readU32() * 2);
}
return positions;
}
public static int[] scanScripts(DataBuffer in) throws DecoderException {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 0; i < size; i++) {
positions[i] = in.position();
in.readU32();
scanTraits(in);
}
return positions;
}
public static int[] scanMethodBodies(DataBuffer in) throws DecoderException {
int size = in.readU32();
if (size == 0) {
return ArrayUtil.EMPTY_INT_ARRAY;
}
int[] positions = new int[size];
for (int i = 0; i < size; i++) {
positions[i] = in.position();
in.skipEntries(5);
long codeLength = in.readU32();
in.skip((int)codeLength);
scanExceptions(in);
scanTraits(in);
}
return positions;
}
private static void scanExceptions(DataBuffer in) {
in.skipEntries(in.readU32() * 5);
}
static void scanTraits(DataBuffer in) throws DecoderException {
int size = in.readU32();
for (int i = 0; i < size; i++) {
in.readU32();
int kind = in.readU8();
switch (kind & 0x0f) {
case TRAIT_Var:
case TRAIT_Const: {
in.skipEntries(2);
int valueId = in.readU32();
if (valueId > 0) {
in.readU8();
}
break;
}
case TRAIT_Method:
case TRAIT_Getter:
case TRAIT_Setter:
in.skipEntries(2);
break;
case TRAIT_Class:
case TRAIT_Function:
in.skipEntries(2);
break;
default:
throw new DecoderException("Invalid trait type: " + kind);
}
if (((kind >> 4) & TRAIT_FLAG_metadata) != 0) {
in.skipEntries(in.readU32());
}
}
}
}