/** Gets the <tt>HasFields</tt> type for C++. */ public CharSequence getCPPFieldType() { Type t = getType(); String prefix = ""; if (t.isArrayType()) { prefix = "(ValueType)-"; t = t.getArrayType(); } if (t == BOOLEAN) return prefix + "ValueType_Bool"; if (t == BOOLNULL) return prefix + "ValueType_BoolNull"; if (t == INETADDR) return prefix + "ValueType_VRTObject"; if (t == UUID) return prefix + "ValueType_VRTObject"; if (t == BYTE) return prefix + "ValueType_Int8"; if (t == SHORT) return prefix + "ValueType_Int16"; if (t == INT) return prefix + "ValueType_Int32"; if (t == LONG) return prefix + "ValueType_Int64"; if (t == FLOAT) return prefix + "ValueType_Float"; if (t == DOUBLE) return prefix + "ValueType_Double"; if (t == UTCTIME) return prefix + "ValueType_VRTObject"; if (t == GPSTIME) return prefix + "ValueType_VRTObject"; if (t.isAsciiType()) return prefix + "ValueType_String"; if (t.isUTF8Type()) return prefix + "ValueType_WString"; if (t.isAsciiTypeStr()) return prefix + "ValueType_String"; if (t.isUTF8TypeStr()) return prefix + "ValueType_WString"; if (t.isMetadataType()) return prefix + "ValueType_VRTObject"; if (t instanceof Record) return prefix + "ValueType_VRTObject"; if (t instanceof Enumeration) return prefix + "ValueType_Int8"; throw new RuntimeException("Unsupported type " + t.getTypeName()); }
/** Returns the function call to pack a given type. */ private String getPackFuncJava(Type t, Object off, Object len) { String prefix = (record != packetType) ? "pack" : "packPayload"; if (t == BOOLEAN) return prefix + "Boolean(" + off + ", val)"; if (t == BOOLNULL) return prefix + "Boolean(" + off + ", val)"; if (t == INETADDR) return prefix + "InetAddr(" + off + ", val)"; if (t == UUID) return prefix + "UUID(" + off + ", val)"; if (t == BYTE) return prefix + "Byte(" + off + ", val)"; if (t == SHORT) return prefix + "Short(" + off + ", val)"; if (t == INT) return prefix + "Int(" + off + ", val)"; if (t == LONG) return prefix + "Long(" + off + ", val)"; if (t == FLOAT) return prefix + "Float(" + off + ", val)"; if (t == DOUBLE) return prefix + "Double(" + off + ", val)"; if (t == UTCTIME) return prefix + "TimeStamp(" + off + ", val, nxm.vrt.lib.TimeStamp.IntegerMode.UTC)"; if (t == GPSTIME) return prefix + "TimeStamp(" + off + ", val, nxm.vrt.lib.TimeStamp.IntegerMode.GPS)"; if (t.isAsciiType()) return prefix + "Ascii(" + off + ", val, " + len + ")"; if (t.isUTF8Type()) return prefix + "UTF8(" + off + ", val, " + len + ")"; if (t.isAsciiTypeStr()) return prefix + "Ascii(" + off + ", val, " + len + ")"; if (t.isUTF8TypeStr()) return prefix + "UTF8(" + off + ", val, " + len + ")"; if (t.isMetadataType()) return prefix + "Metadata(" + off + ", val, " + len + ")"; if (t instanceof Record) return prefix + "Record(" + off + ", val)"; if (t instanceof Enumeration) return prefix + "Byte(" + off + ", " + t.getTypeJavaGet() + ".getValue(val))"; throw new RuntimeException("Unsupported type " + t.getTypeName()); }
/** Returns the function call to unpack a given type. */ private String getUnpackFuncCPP(Type t, Object off, Object len) { String prefix = (record != packetType) ? "unpack" : "unpackPayload"; if (t == BOOLEAN) return prefix + "Boolean(" + off + ")"; if (t == BOOLNULL) return prefix + "Boolean(" + off + ")"; if (t == INETADDR) return prefix + "InetAddr(" + off + ")"; if (t == UUID) return prefix + "UUID(" + off + ")"; if (t == BYTE) return prefix + "Byte(" + off + ")"; if (t == SHORT) return prefix + "Short(" + off + ")"; if (t == INT) return prefix + "Int(" + off + ")"; if (t == LONG) return prefix + "Long(" + off + ")"; if (t == FLOAT) return prefix + "Float(" + off + ")"; if (t == DOUBLE) return prefix + "Double(" + off + ")"; if (t == UTCTIME) return prefix + "TimeStamp(" + off + ", IntegerMode_UTC)"; if (t == GPSTIME) return prefix + "TimeStamp(" + off + ", IntegerMode_GPS)"; if (t.isAsciiType()) return prefix + "Ascii(" + off + ", " + len + ")"; if (t.isUTF8Type()) return prefix + "UTF8(" + off + ", " + len + ")"; if (t.isAsciiTypeStr()) return prefix + "Ascii(" + off + ", " + len + ")"; if (t.isUTF8TypeStr()) return prefix + "UTF8(" + off + ", " + len + ")"; if (t.isMetadataType()) return prefix + "Metadata(" + off + ", " + len + ")"; if (t instanceof Record) return prefix + "Record(" + off + ", r)"; // <-- special handling if (t instanceof Enumeration) return "(" + t.getTypeJavaGet() + ")" + prefix + "Byte(" + off + ")"; throw new RuntimeException("Unsupported type " + t.getTypeName()); }
/** Is the given type a native type in C++ (or an array of native types)? */ private boolean isCPPNativeType(Type t) { if (t.isArrayType()) return isCPPNativeType(t.getArrayType()); if (t == BOOLEAN) return true; if (t == BOOLNULL) return true; if (t == BYTE) return true; if (t == SHORT) return true; if (t == INT) return true; if (t == LONG) return true; if (t == FLOAT) return true; if (t == DOUBLE) return true; if (t.isAsciiType()) return true; // string if (t.isUTF8Type()) return true; // wstring if (t.isAsciiTypeStr()) return true; // string if (t.isUTF8TypeStr()) return true; // wstring if (t instanceof Enumeration) return true; // int8_t return false; }
/** Write the set method. */ private void writeJavaSet( PrintStream out, String permission, String html, String size, String limit, String len, String indent) { html = html.replace("\n", "\n * "); Type t = getType(); int b = t.getTypeBytes(); // === DOCS === out.println(indent + " "); out.println(indent + " /** Set " + html + " "); if ((units != null) && (units.length() > 0)) { out.println(indent + " * <br> Units: <i>" + units + "</i>"); } if ((range != null) && (range.length() > 0)) { out.println(indent + " * <br> Range: <tt>" + range + "</tt>"); } if (t.isArrayType() || t.isStringType()) { out.println(indent + " * <br> Size: <tt>" + size + "</tt>"); } if (t.isStringType()) { out.println(indent + " * @param val The new value to write to the packet."); if (t.isAsciiType()) { out.println( indent + " * Any non-ASCII characters in the string (numeric value >0x7F) or ASCII"); out.println( indent + " * control characters (numeric value <0x20, 0x7F) will be replaced with \'?\'."); } if (b >= 0) { out.println( indent + " * If the string is longer than the size allotted, it will be"); out.println(indent + " * truncated without warning. "); } } else { out.println(indent + " * @param val The new value to write to the packet."); } if (t.isArrayType()) { out.println( indent + " * @throws java.lang.IllegalArgumentException If the length of <tt>val</tt> is invalid"); } out.println(indent + " */"); // === CODE === if (!t.isArrayType()) { out.println( indent + " " + permission + " void set" + methodName + " (" + t.getTypeJavaSet() + " val) {"); if (b < 0) { if (limit != null) { out.println(indent + " int limit = " + limit + ";"); out.println(indent + " int length = " + len + ";"); out.println(indent + " int len = (length > limit)? ((limit + 3) & 0x7FFFFFFC)"); out.println( indent + " : ((length + 3) & 0x7FFFFFFC); // length to next multiple of 4"); out.println(indent + " setPayloadLength(" + offset + " + len);"); } else { out.println( indent + " int len = (" + len + " + 3) & 0x7FFFFFFC; // length to next multiple of 4"); out.println(indent + " setPayloadLength(" + offset + " + len);"); } len = "len"; } out.println(indent + " " + getPackFuncJava(t, offset, len) + ";"); out.println(indent + " }"); } else { Type arrayType = t.getArrayType(); int count = t.getArrayLength(); int bytes = arrayType.getTypeBytes(); String singleName = notPlural(methodName); String getCount = "get" + singleName + "Count()"; out.println( indent + " " + permission + " void setAll" + methodName + " (" + arrayType.getTypeJavaGet() + " ... val) {"); if (t.getArrayType() == BYTE) { out.println(indent + " // Use fast method for packing an array of bytes"); out.println(indent + " packPayloadBytes(" + offset + ", val, " + getCount + ");"); } else { if (count >= 0) { out.println(indent + " if (val.length != " + b + ") {"); out.println( indent + " throw new java.lang.IllegalArgumentException(\"Invalid array length \"+val.length+\" for " + name + "\");"); out.println(indent + " }"); } else { out.println(indent + " set" + singleName + "Count(val.length);"); } out.println(indent + " for (int i = 0; i < val.length; i++) {"); out.println(indent + " set" + singleName + "(i, val[i]);"); out.println(indent + " }"); } out.println(indent + " }"); out.println(indent + " "); out.println(indent + " /** Set item in " + html + " "); out.println(indent + " * @param i The index."); out.println(indent + " * @param val The new value."); out.println( indent + " * @throws java.lang.IllegalArgumentException if <tt>i</tt> is greater than or equal to " + getCount + ""); out.println(indent + " */"); out.println( indent + " " + permission + " void set" + singleName + " (int i, " + arrayType.getTypeJavaSet() + " val) {"); out.println(indent + " if ((i < 0) || (i > " + getCount + ")) {"); out.println( indent + " throw new java.lang.IllegalArgumentException(\"Invalid index \"+i+\" into " + name + "\");"); out.println(indent + " }"); out.println(indent + " int off = " + offset + " + (" + bytes + " * i);"); out.println(indent + " " + getPackFuncJava(arrayType, "off", bytes) + ";"); out.println(indent + " }"); if (count < 0) { out.println(indent + " "); out.println(indent + " /** Set length of " + html + " "); out.println(indent + " * @param length The number of entries."); out.println( indent + " * @throws java.lang.IllegalArgumentException if <tt>length</tt> is negative"); out.println(indent + " */"); out.println(indent + " " + permission + " void set" + singleName + "Count (int length) {"); out.println(indent + " if (length < 0) {"); out.println( indent + " throw new java.lang.IllegalArgumentException(\"Illegal length \"+length+\" for " + name + "\");"); out.println(indent + " }"); out.println( indent + " int len = ((length * " + bytes + ") + 3) & 0x7FFFFFFC; // length to next multiple of 4"); out.println(indent + " setPayloadLength(" + offset + " + len);"); out.println(indent + " }"); } } }
private CodeParams getCodeParams(boolean isJava) { // ignore the pad bytes Type t = getType(); int b = getType().getTypeBytes(); String lenGet; String lenSet; String limit; String size; if (b >= 0) { lenGet = Integer.toString(b); lenSet = Integer.toString(b); limit = null; size = Integer.toString(b); } else if (b != Type.STAR_LENGTH) { if (t.isStringType()) { lenGet = "getPayloadLength()-" + offset; lenSet = Integer.toString(b); limit = null; size = "0 to " + (-b - 1) + " octets"; } else { throw new RuntimeException( "The array syntax [0" + b + "] is only applicable to ascii and utf8 fields."); } } else if (t.isAsciiType() || t.isAsciiTypeStr()) { lenGet = "getPayloadLength()-" + offset; lenSet = "val.length()"; limit = "MAX_PAYLOAD_LENGTH-" + offset; size = "variable"; } else if (t.isStringType()) { lenGet = "getPayloadLength()-" + offset; lenSet = (isJava) ? "nxm.vrt.lib.VRTMath.lengthUTF8(val)" : "vrt::VRTMath::lengthUTF8(val)"; limit = "MAX_PAYLOAD_LENGTH-" + offset; size = "variable"; } else if (t.isMetadataType()) { lenGet = "getPayloadLength()-" + offset; lenSet = "val.getLengthInBytes()"; limit = null; size = "variable"; } else if (t.isArrayType()) { int bytes = t.getArrayType().getTypeBytes(); if (bytes == 0) { lenGet = "getPayloadLength()-" + offset; lenSet = "val.length"; limit = null; size = "variable"; } else if (bytes > 0) { lenGet = "(getPayloadLength()-" + offset + ")/" + bytes; lenSet = "val.length"; limit = null; size = "variable"; } else { throw new RuntimeException( "Could not determine length of " + t.getTypeName() + " for " + this); } } else { throw new RuntimeException( "Could not determine length of " + t.getTypeName() + " for " + this); } String html = toHtmlDoc(descr, "").trim(); if (html.length() == 0) { html = methodName; } if (!html.endsWith(".")) { html += "."; } if (Character.isUpperCase(html.charAt(0)) && Character.isLowerCase(html.charAt(1))) { html = html.substring(0, 1).toLowerCase() + html.substring(1); } return new CodeParams(html, size, limit, lenGet, lenSet); }
/** Write the set method. */ private void writeCPPSet( PrintStream hdr, PrintStream cpp, String permission, String html, String size, String limit, String len, String indent, Type t) { html = html.replace("\n", "\n * "); int b = t.getTypeBytes(); // === DOCS === hdr.println(indent + " "); hdr.println(indent + " /** Set " + html + " "); if ((units != null) && (units.length() > 0)) { hdr.println(indent + " * <br> Units: <i>" + units + "</i>"); } if ((range != null) && (range.length() > 0)) { hdr.println(indent + " * <br> Range: <tt>" + range + "</tt>"); } if (t.isArrayType() || t.isStringType()) { hdr.println(indent + " * <br> Size: <tt>" + size + "</tt>"); } if (t.isStringType()) { hdr.println(indent + " * @param val The new value to write to the packet."); if (t.isAsciiType()) { hdr.println( indent + " * Any non-ASCII characters in the string (numeric value >0x7F) or ASCII"); hdr.println( indent + " * control characters (numeric value <0x20, 0x7F) will be replaced with \'?\'."); } if (b >= 0) { hdr.println( indent + " * If the string is longer than the size allotted, it will be"); hdr.println(indent + " * truncated without warning. "); } } else { hdr.println(indent + " * @param val The new value to write to the packet."); } if (t.isArrayType()) { hdr.println(indent + " * @throws VRTException If the length of <tt>val</tt> is invalid"); } hdr.println(indent + " */"); // === CODE === if (!t.isArrayType()) { hdr.println( indent + " " + permission + ": inline void set" + methodName + " (" + t.getTypeCPPSet() + " val) {"); if (b < 0) { if (limit != null) { hdr.println(indent + " int32_t limit = " + limit + ";"); hdr.println(indent + " int32_t length = " + len + ";"); hdr.println( indent + " int32_t len = (length > limit)? ((limit + 3) & 0x7FFFFFFC)"); hdr.println( indent + " : ((length + 3) & 0x7FFFFFFC); // length to next multiple of 4"); hdr.println(indent + " setPayloadLength(" + offset + " + len);"); } else { hdr.println( indent + " int32_t len = (" + len + " + 3) & 0x7FFFFFFC; // length to next multiple of 4"); hdr.println(indent + " setPayloadLength(" + offset + " + len);"); } len = "len"; } hdr.println(indent + " " + getPackFuncCPP(t, offset, len) + ";"); hdr.println(indent + " }"); } else { Type arrayType = t.getArrayType(); int count = t.getArrayLength(); int bytes = arrayType.getTypeBytes(); String singleName = notPlural(methodName); String getCount = "get" + singleName + "Count()"; hdr.println( indent + " " + permission + ": void setAll" + methodName + " (const vector<" + arrayType.getTypeCPPGet() + "> &val);"); hdr.println(indent + " "); hdr.println(indent + " /** Set method used by the HasFields functions. */"); hdr.println(indent + " private: void _setAll" + methodName + " (const Value *val);"); hdr.println(indent + " "); hdr.println(indent + " /** Set item in " + html + " "); hdr.println(indent + " * @param i The index."); hdr.println(indent + " * @param val The new value."); hdr.println( indent + " * @throws VRTException if <tt>i</tt> is greater than or equal to " + getCount + ""); hdr.println(indent + " */"); hdr.println( indent + " " + permission + ": void set" + singleName + " (int32_t i, " + arrayType.getTypeCPPSet() + " val);"); if (count < 0) { hdr.println(indent + " "); hdr.println(indent + " /** Set length of " + html + " "); hdr.println(indent + " * @param length The number of entries."); hdr.println(indent + " * @throws VRTException if <tt>length</tt> is negative"); hdr.println(indent + " */"); hdr.println( indent + " " + permission + ": void set" + singleName + "Count (int32_t length);"); } cpp.println( indent + "void " + record.name + "::setAll" + methodName + " (const vector<" + arrayType.getTypeCPPGet() + "> &val) {"); if (t.getArrayType() == BYTE) { cpp.println(indent + " // Use fast method for packing an array of bytes"); cpp.println(indent + " packPayloadBytes(" + offset + ", val, " + getCount + ");"); } else { if (count >= 0) { cpp.println(indent + " if (val.size() != " + b + ") {"); cpp.println( indent + " throw VRTException(\"Invalid array length %d for " + name + "\", val.size());"); cpp.println(indent + " }"); } else { cpp.println(indent + " set" + singleName + "Count(val.size());"); } cpp.println(indent + " for (size_t i = 0; i < val.size(); i++) {"); cpp.println(indent + " set" + singleName + "(i, val[i]);"); cpp.println(indent + " }"); } cpp.println(indent + "}"); cpp.println(indent + ""); cpp.println( indent + "void " + record.name + "::set" + singleName + " (int32_t i, " + arrayType.getTypeCPPSet() + " val) {"); cpp.println(indent + " if ((i < 0) || (i > " + getCount + ")) {"); cpp.println(indent + " throw VRTException(\"Invalid index %d into " + name + "\", i);"); cpp.println(indent + " }"); cpp.println(indent + " int32_t off = " + offset + " + (" + bytes + " * i);"); cpp.println(indent + " " + getPackFuncCPP(arrayType, "off", bytes) + ";"); cpp.println(indent + "}"); if (count < 0) { cpp.println(indent + ""); cpp.println( indent + "void " + record.name + "::set" + singleName + "Count (int32_t length) {"); cpp.println(indent + " if (length < 0) {"); cpp.println( indent + " throw VRTException(\"Illegal length %d for " + name + "\", length);"); cpp.println(indent + " }"); cpp.println( indent + " int32_t len = ((length * " + bytes + ") + 3) & 0x7FFFFFFC; // length to next multiple of 4"); cpp.println(indent + " setPayloadLength(" + offset + " + len);"); cpp.println(indent + "}"); } cpp.println(indent + ""); cpp.println( indent + "void " + record.name + "::_setAll" + methodName + " (const Value* val) {"); if (count >= 0) { cpp.println(indent + " if (val->size() != " + b + ") {"); cpp.println( indent + " throw VRTException(\"Invalid array length %d for " + name + "\", val->size());"); cpp.println(indent + " }"); } else { cpp.println(indent + " set" + singleName + "Count(val->size());"); } cpp.println(indent + " for (size_t i = 0; i < val->size(); i++) {"); cpp.println(indent + " Value *v = val->at(i);"); if (isCPPNativeType(t)) { cpp.println( indent + " set" + singleName + "(i, v->as<" + arrayType.getTypeCPPGet() + ">());"); } else { cpp.println( indent + " set" + singleName + "(i, *v->cast<" + arrayType.getTypeCPPGet() + "*>());"); } cpp.println(indent + " delete v;"); cpp.println(indent + " }"); cpp.println(indent + "}"); cpp.println(indent + ""); } }