blob: b2af5c23ebae8263b6cdd0db4dfac1f1765db08a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 The Regents of the University of California.
* This material was produced under U.S. Government contract W-7405-ENG-36
* for Los Alamos National Laboratory, which is operated by the University
* of California for the U.S. Department of Energy. The U.S. Government has
* rights to use, reproduce, and distribute this software. NEITHER THE
* GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly marked,
* so as not to confuse it with the version available from LANL.
*
* Additionally, this program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* LA-CC 04-115
*******************************************************************************/
package org.eclipse.ptp.debug.core.pdi.model.aif;
import java.util.Random;
import org.eclipse.ptp.debug.core.PDebugUtils;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIF;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeAddress;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeArray;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeBool;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeChar;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeCharPointer;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeClass;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeEnum;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeFloat;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeFunction;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeIncomplete;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeInt;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeNamed;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypePointer;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeReference;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeString;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeStruct;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeUnion;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFTypeVoid;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueAddress;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueArray;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueBool;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueChar;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueCharPointer;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueClass;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueEnum;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueFloat;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueInt;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueNamed;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValuePointer;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueReference;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueString;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueStruct;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueUnion;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueUnknown;
import org.eclipse.ptp.debug.internal.core.pdi.aif.AIFValueVoid;
/**
* @author Clement chu
*
*/
public class AIFFactory {
public static class SimpleByteBuffer {
byte[] bytes;
int pos = 0;
SimpleByteBuffer(byte[] bytes) {
if (bytes == null) {
bytes = new byte[0];
}
this.bytes = bytes;
}
public boolean end() {
return (pos == bytes.length);
}
public byte get() {
return bytes[pos++];
}
public byte get(int pos) {
return bytes[pos];
}
public byte[] getByte() {
return bytes;
}
public int getCapacity() {
return bytes.length;
}
public int getPosition() {
return pos;
}
public void setPos(int pos) {
this.pos = pos;
}
}
public static final char FDS_ARRAY = '[';
public static final char FDS_BOOL = 'b';
public static final char FDS_CHAR = 'c';
public static final char FDS_ENUM = '<';
public static final char FDS_FLOAT = 'f';
public static final char FDS_FUNCTION = '&';
public static final char FDS_INT = 'i';
public static final char FDS_POINTER = '^';
public static final char FDS_STRING = 's';
public static final char FDS_STRUCT_CLASS = '{';
public static final char FDS_UNION = '(';
public static final char FDS_VOID = 'v';
public static final char FDS_REFERENCE = '>';
public static final char FDS_NAMED = '%';
public static final char FDS_ADDRESS = 'a';
public static final char FDS_CHAR_POINTER = 'p';
public static final int FDS_FLOAT_SIZE_POS = 1;
public static final int FDS_VOID_SIZE_POS = 1;
public static final int FDS_INTEGER_SIGN_POS = 1;
public static final int FDS_INTEGER_SIZE_POS = 2;
public static final int FDS_RANGE_DOT_LEN = 2;
public static final String SIGN_OPEN = "[";
public static final String SIGN_CLOSE = "]";
public static final String SIGN_STROKE = "|";
public static final String SIGN_COMMA = ",";
public static final String SIGN_EQUAL = "=";
public static final String SIGN_SEMI_COLON = ";";
public static final String SIGN_COLON = ":";
public static final String SIGN_DOT = ".";
public static final String FDS_STRUCT_END = ";;;}";
public static final String FDS_CLASS_END = "}";
public static final String FDS_UNION_END = ")";
public static final String FDS_ENUM_END = ">";
public static final String FDS_FUNCTION_END = "/";
public static final String FDS_REFERENCE_END = "/";
public static final String FDS_NAMED_END = "/";
public static final int NO_SIZE = 0;
public static final int SIZE_BOOL = 1;
public static final int SIZE_CHAR = 1;
public static final int SIZE_FLOAT = 4;
public static final int SIZE_DOUBLE = 8;
public static final int SIZE_INVALID = 0;
public static final IAIFType UNKNOWNTYPE = new AIFTypeIncomplete();
public static final IAIFValue UNKNOWNVALUE = new AIFValueUnknown(UNKNOWNTYPE);
/**
* @param fmt
* @param start_pos
* @param end_pos
* @return
*/
public static String extractFormat(String fmt, int start_pos, int end_pos) {
return fmt.substring(start_pos, end_pos);
}
/**
* Create an AIF object
*
* @param fds
* @param data
* @param description
* @return
*/
public static IAIF newAIF(String fds, byte[] data, String description) {
return new AIF(fds, data, description);
}
/**
* Create an AIF object
*
* @param aifType
* @param aifValue
* @return
*/
public static IAIF newAIF(IAIFType aifType, IAIFValue aifValue) {
return new AIF(aifType, aifValue);
}
/**
* Create an AIF object
*
* @param fds
* @param data
* @return
*/
public static IAIF newAIF(String fds, byte[] data) {
return new AIF(fds, data);
}
/**
* @param fmt
* @return
*/
public static IAIFType getAIFType(String fmt) {
if (fmt == null || fmt.length() == 0) {
PDebugUtils.println(" ======= null: " + fmt);
return UNKNOWNTYPE;
}
switch (fmt.charAt(0)) {
case FDS_CHAR: //char is signed or unsigned ???
PDebugUtils.println(" ======= character: " + fmt);
return new AIFTypeChar();
case FDS_FLOAT:
int float_size = Character.digit(fmt.charAt(FDS_FLOAT_SIZE_POS), 10);
PDebugUtils.println(" ======= floating: " + fmt + ", size: " + float_size);
return new AIFTypeFloat(float_size);
case FDS_INT: //long and int is same??? long long type
boolean signed = (fmt.charAt(FDS_INTEGER_SIGN_POS) == 's');
int int_size = Character.digit(fmt.charAt(FDS_INTEGER_SIZE_POS), 10);
PDebugUtils.println(" ======= int: " + fmt + ", size: " + int_size);
return new AIFTypeInt(signed, int_size);
case FDS_CHAR_POINTER:
PDebugUtils.println(" ======= char pointer: " + fmt);
return new AIFTypeCharPointer(getAIFType(fmt.substring(1, 3)));
case FDS_STRING:
PDebugUtils.println(" ======= string: " + fmt);
return new AIFTypeString();
case FDS_BOOL:
PDebugUtils.println(" ======= boolean: " + fmt);
return new AIFTypeBool();
case FDS_ENUM:
PDebugUtils.println(" ======= enum: " + fmt);
int enum_end_pos = getEndPosFromLast(fmt, FDS_ENUM_END);
String enum_type = fmt.substring(enum_end_pos+FDS_ENUM_END.length());
return new AIFTypeEnum(extractFormat(fmt, 1, enum_end_pos), getAIFType(enum_type));
case FDS_FUNCTION:
PDebugUtils.println(" ======= function: " + fmt);
int func_end_pos = getEndPosFromLast(fmt, FDS_FUNCTION_END);
String func_type = fmt.substring(func_end_pos+FDS_FUNCTION_END.length());
return new AIFTypeFunction(extractFormat(fmt, 1, func_end_pos), getAIFType(func_type));
case FDS_STRUCT_CLASS: //struct or class
int struct_end_pos = getEndPosFromLast(fmt, FDS_STRUCT_END);
if (fmt.length() == struct_end_pos + FDS_STRUCT_END.length()) {
PDebugUtils.println(" ======= struct " + fmt);
return new AIFTypeStruct(extractFormat(fmt, 1, struct_end_pos));
}
else {
struct_end_pos = getEndPosFromLast(fmt, FDS_CLASS_END);
PDebugUtils.println(" ======= class " + fmt);
return new AIFTypeClass(extractFormat(fmt, 1, struct_end_pos));
}
case FDS_UNION:
PDebugUtils.println(" ======= union: " + fmt);
int union_end_pos = getEndPosFromLast(fmt, FDS_UNION_END);
return new AIFTypeUnion(extractFormat(fmt, 1, union_end_pos));
case FDS_REFERENCE:
PDebugUtils.println(" ======= reference: " + fmt);
int ref_end_pos = getEndPosFromStart(fmt, FDS_REFERENCE_END);
return new AIFTypeReference(extractFormat(fmt, 1, ref_end_pos));
case FDS_ADDRESS:
PDebugUtils.println(" ======= address: " + fmt);
return new AIFTypeAddress(Character.digit(fmt.charAt(1), 10));
case FDS_POINTER:
PDebugUtils.println(" ======= pointer: " + fmt);
return new AIFTypePointer(getAIFType(fmt.substring(1, 3)), getAIFType(fmt.substring(3)));
case FDS_VOID:
PDebugUtils.println(" ======= void: " + fmt);
int void_size = Character.digit(fmt.charAt(FDS_VOID_SIZE_POS), 10);
return new AIFTypeVoid(void_size);
case FDS_ARRAY:
PDebugUtils.println(" ======= array: " + fmt);
int array_end_pos = getEndPosFromStart(fmt, SIGN_CLOSE);
return new AIFTypeArray(extractFormat(fmt, 1, array_end_pos), getAIFType(fmt.substring(array_end_pos+1)));
case FDS_NAMED:
PDebugUtils.println(" ======= named: " + fmt);
int named_end_pos = getEndPosFromStart(fmt, FDS_NAMED_END);
return new AIFTypeNamed(extractFormat(fmt, 1, named_end_pos), getAIFType(fmt.substring(named_end_pos+1)));
default:
PDebugUtils.println(" ======= unknown: " + fmt);
return new AIFTypeIncomplete();
}
}
/**
* @param parent
* @param type
* @param data
* @return
*/
public static IAIFValue getAIFValue(IValueParent parent, IAIFType type, byte[] data) {
if (data == null || data.length < 0) {
return new AIFValueUnknown(type);
}
return getAIFValue(parent, type, new SimpleByteBuffer(data));
}
/**
* @param parent
* @param type
* @param buffer
* @return
*/
public static IAIFValue getAIFValue(IValueParent parent, IAIFType type, SimpleByteBuffer buffer) {
if (buffer.end()) {
return new AIFValueUnknown(type);
} else if (type instanceof IAIFTypeChar) {
return new AIFValueChar((IAIFTypeChar)type, buffer);
} else if (type instanceof IAIFTypeFloat) {
return new AIFValueFloat((IAIFTypeFloat)type, buffer);
} else if (type instanceof IAIFTypeInt) {
return new AIFValueInt((IAIFTypeInt)type, buffer);
} else if (type instanceof IAIFTypeCharPointer) {
return new AIFValueCharPointer((IAIFTypeCharPointer)type, buffer);
} else if (type instanceof IAIFTypeString) {
return new AIFValueString((IAIFTypeString)type, buffer);
} else if (type instanceof IAIFTypeBool) {
return new AIFValueBool((IAIFTypeBool)type, buffer);
} else if (type instanceof IAIFTypeArray) {
return new AIFValueArray((IAIFTypeArray)type, buffer);
} else if (type instanceof IAIFTypeEnum) {
return new AIFValueEnum((IAIFTypeEnum)type, buffer);
} else if (type instanceof IAIFTypeAddress) {
return new AIFValueAddress((IAIFTypeAddress)type, buffer);
} else if (type instanceof IAIFTypePointer) {
return new AIFValuePointer(parent, (IAIFTypePointer)type, buffer);
} else if (type instanceof IAIFTypeNamed) {
return new AIFValueNamed(parent, (IAIFTypeNamed)type, buffer);
} else if (type instanceof IAIFTypeReference) {
return new AIFValueReference(parent, (IAIFTypeReference)type, buffer);
} else if (type instanceof IAIFTypeStruct) {
return new AIFValueStruct(parent, (IAIFTypeStruct)type, buffer);
} else if (type instanceof IAIFTypeUnion) {
return new AIFValueUnion(parent, (IAIFTypeUnion)type, buffer);
} else if (type instanceof IAIFTypeClass) {
return new AIFValueClass(parent, (IAIFTypeClass)type, buffer);
} else if (type instanceof IAIFTypeVoid) {
return new AIFValueVoid((IAIFTypeVoid)type, buffer);
/*
} else if (type instanceof IAIFTypeFunction) {
return new AIFValueFunction((IAIFTypeFunction)type, data);
*/
}
return new AIFValueUnknown(type);
}
/**
* @param format
* @param pos
* @return
*/
public static int getDigitPos(String format, int pos) {
int len = format.length();
while (pos < len) {
char aChar = format.charAt(pos);
if (!Character.isDigit(aChar)) {
break;
}
pos++;
}
return pos;
}
/**
* @param fmt
* @param regex
* @return
*/
public static int getEndPosFromLast(String fmt, String regex) {
return fmt.lastIndexOf(regex);
}
/**
* @param fmt
* @param regex
* @return
*/
public static int getEndPosFromStart(String fmt, String regex) {
return fmt.indexOf(regex);
}
/**
* testing purpose
*/
public static int random_num(int min, int max) {
Random generator = new Random();
long range = (long)max - (long)min + 1;
long fraction = (long)(range * generator.nextDouble());
return (int)(fraction + min);
}
/**
* @return
*/
public static IAIF UNKNOWNAIF() {
return new AIF(UNKNOWNTYPE, UNKNOWNVALUE);
}
}