📄 variable.java
字号:
* Returns Object of specified Code derived from specified Object * If code is not NONE, the new Object will be of type CodeExpression. * If code is NONE and the specified Object was CodeExpression, * the new Object will be a String with expression text. * @param value specified Object * @param code code of new Object. * @return Object of specified Code derived from specified Object */ public static Object withCode(Object value, CodeExpression.Code code) { if (code == CodeExpression.Code.NONE) return value instanceof CodeExpression ? value.toString() : value; if (value instanceof CodeExpression && ((CodeExpression)value).getCode() == code) return value; String expr; if (value instanceof Object[]) { StringBuilder sb = new StringBuilder(); for (Object o: (Object[])value) { if (o == null) continue; if (sb.length() > 0) sb.append(' '); sb.append(o.toString()); } expr = sb.toString(); } else { expr = value.toString(); } return CodeExpression.valueOf(expr, code); } /** * Checks invariant of this Variable. * @param paramAllowed true if paramerer flag is allowed on this Variable * @param inheritAllowed true if inherit flag is allowed on this Variable * @throws AssertionError or NullPointerException if invariant is broken. */ public void check(boolean paramAllowed, boolean inheritAllowed) { assert key != null; assert value != null; assert type == getObjectType(value); assert descriptor != null; if (descriptor.isParam()) assert paramAllowed && isAttribute(); if (descriptor.isInherit()) assert inheritAllowed; } private static byte getObjectType(Object value) { byte type; if (value instanceof Object[]) { Byte typeByte = validClasses.get(value.getClass().getComponentType()); if (typeByte == null) throw new IllegalArgumentException(value.getClass().toString()); type = (byte)(typeByte.byteValue()|ARRAY); if (!validValue(type, value)) throw new IllegalArgumentException(value.toString()); } else { Byte typeByte = validClasses.get(value.getClass()); if (typeByte == null) throw new IllegalArgumentException(value.getClass().toString()); type = typeByte.byteValue(); } return type; } private static boolean validValue(byte type, Object value) { if ((type & ARRAY) == 0) return value != null; type = (byte)(type & ~ARRAY); if (type == CODE) return false; Object[] valueArr = (Object[])value; if (type >= STRING && type <= BOOLEAN) { for (Object o: valueArr) { if (o == null) return false; } } return true; } /** * Returns true if the value is array, * @return true if the value is array, */ public boolean isArray() { return (type & ARRAY) != 0; } /** * Get the number of entries stored in this Variable. * For non-arrayed Variables, this is 1. * @return the number of entries stored in this Variable. */ public int getLength() { return (type & ARRAY) != 0 ? ((Object[])value).length : 1; } /** * Returns thread-independent value of this Variable. * @return thread-independent value of this variable. */ public Object getObject() { return (type & ARRAY) != 0 ? ((Object[])value).clone() : value; } /** * Write this Variable to IdWriter. * @param writer where to write. */ public void write(IdWriter writer) throws IOException { writer.writeVariableKey(key); writer.writeTextDescriptor(descriptor); writeObject(writer, value, type); } private static void writeObject(IdWriter writer, Object obj, byte type) throws IOException { writer.writeByte(type); if (obj instanceof Object[]) { Object[] array = (Object[])obj; writer.writeInt(array.length); for (Object o: array) { writer.writeBoolean(o != null); if (o != null) writeObj(writer, o, type); } } else { writeObj(writer, obj, type); } } private static void writeObj(IdWriter writer, Object obj, byte type) throws IOException { switch (type & ~ARRAY) { case LIBRARY: writer.writeLibId((LibId)obj); break; case CELL: writer.writeNodeProtoId((CellId)obj); break; case EXPORT: writer.writePortProtoId((ExportId)obj); break; case STRING: writer.writeString((String)obj); break; case CODE: ((CodeExpression)obj).write(writer); break; case DOUBLE: writer.writeDouble(((Double)obj).doubleValue()); break; case FLOAT: writer.writeFloat(((Float)obj).floatValue()); break; case LONG: writer.writeLong(((Long)obj).longValue()); break; case INTEGER: writer.writeInt(((Integer)obj).intValue()); break; case SHORT: writer.writeShort(((Short)obj).shortValue()); break; case BYTE: writer.writeByte(((Byte)obj).byteValue()); break; case BOOLEAN: writer.writeBoolean(((Boolean)obj).booleanValue()); break; case EPOINT: writer.writePoint((EPoint)obj); break; case TOOL: writer.writeTool((Tool)obj); break; case TECHNOLOGY: writer.writeTechId((TechId)obj); break; case PRIM_NODE: writer.writeNodeProtoId((PrimitiveNodeId)obj); break; case ARC_PROTO: writer.writeArcProtoId((ArcProtoId)obj); break; } } /** * Read Variable from IdReader. * @param reader from to read. * @return Variable read */ public static Variable read(IdReader reader) throws IOException { Variable.Key varKey = reader.readVariableKey(); TextDescriptor td = reader.readTextDescriptor(); Object value = readObject(reader); return Variable.newInstance(varKey, value, td); } private static Object readObject(IdReader reader) throws IOException { int type = reader.readByte(); Object value; if ((type & ARRAY) != 0) { int length = reader.readInt(); type &= ~ARRAY; Object[] array; switch (type) { case LIBRARY: array = new LibId[length]; break; case CELL: array = new CellId[length]; break; case EXPORT: array = new ExportId[length]; break; case STRING: array = new String[length]; break; case DOUBLE: array = new Double[length]; break; case FLOAT: array = new Float[length]; break; case LONG: array = new Long[length]; break; case INTEGER: array = new Integer[length]; break; case SHORT: array = new Short[length]; break; case BYTE: array = new Byte[length]; break; case BOOLEAN: array = new Boolean[length]; break; case EPOINT: array = new EPoint[length]; break; case TOOL: array = new Tool[length]; break; case TECHNOLOGY: array = new TechId[length]; break; case PRIM_NODE: array = new PrimitiveNodeId[length]; break; case ARC_PROTO: array = new ArcProtoId[length]; break; case CODE: default: throw new IOException("type"); } for (int i = 0; i < length; i++) { boolean hasElem = reader.readBoolean(); if (hasElem) array[i] = readObj(reader, type); } value = array; } else { value = readObj(reader, type); } return value; } private static Object readObj(IdReader reader, int type) throws IOException { switch (type) { case LIBRARY: return reader.readLibId(); case CELL: return reader.readNodeProtoId(); case EXPORT: return reader.readPortProtoId(); case STRING: return reader.readString(); case CODE: return CodeExpression.read(reader); case DOUBLE: return Double.valueOf(reader.readDouble()); case FLOAT: return Float.valueOf(reader.readFloat()); case LONG: return Long.valueOf(reader.readLong()); case INTEGER: return Integer.valueOf(reader.readInt()); case SHORT: return Short.valueOf(reader.readShort()); case BYTE: return Byte.valueOf(reader.readByte()); case BOOLEAN: return Boolean.valueOf(reader.readBoolean()); case EPOINT: return reader.readPoint(); case TOOL: return reader.readTool(); case TECHNOLOGY: return reader.readTechId(); case PRIM_NODE: return reader.readNodeProtoId(); case ARC_PROTO: return reader.readArcProtoId(); default: throw new IllegalArgumentException(); } } /** * Returns Variable which differs from this Variable by value. * @param value value of new Variable. * @return Variable which differs from this Variable by value. * @throws NullPointerException if value is null. * @throws IllegalArgumentException if value has invalid type */ public Variable withObject(Object value) { if (this.value.equals(value)) return this; if ((type & ARRAY) != 0 && value instanceof Object[] && Arrays.equals((Object[])this.value, (Object[])value) && this.value.getClass().getComponentType() == value.getClass().getComponentType()) return this; return newInstance(this.key, value, this.descriptor); } /** * Returns Variable which differs from this Variable by text value. * If this Variable is Code Varibale its Code type is preserved * @param text text value of new Variable. * @return Variable which differs from this Variable by value. * @throws NullPointerException if value is null. * @throws IllegalArgumentException if value has invalid type */ public Variable withText(String text) { if (value instanceof CodeExpression) { CodeExpression ce = (CodeExpression)value; if (ce.getExpr().equals(text)) return this; return new Variable(this.key, CodeExpression.valueOf(text, ce.getCode()), this.descriptor, this.type); } if (value.equals(text)) return this; return new Variable(this.key, text, this.descriptor, STRING); } /** * Returns Variable which differs from this Variable by code. * @param code code of new Variable. * @return Variable which differs from this Variable by code */ public Variable withCode(CodeExpression.Code code) { if (getCode() == code) return this; return withObject(withCode(value, code)); } /** * Returns Variable which differs from this Variable by renamed Ids. * @param idMapper a mapper from old Ids to new Ids. * @return Variable which differs from this Variable by renamed Ids. */ public Variable withRenamedIds(IdMapper idMapper) { Object newValue = withRenamedIds(idMapper, value, type); return newValue != value ? withObject(newValue) : this; } private static Object withRenamedIds(IdMapper idMapper, Object value, byte type) { Object newValue = value; switch (type) { case LIBRARY: newValue = idMapper.get((LibId)value); break; case CELL: newValue = idMapper.get((CellId)value); break; case EXPORT: newValue = idMapper.get((ExportId)value); break; case LIBRARY|ARRAY:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -