/** * Create a HeaderCard from its component parts * * @param key Keyword (null for a COMMENT) * @param value Value * @param comment Comment * @param nullable Is this a nullable value card? * @exception HeaderCardException for any invalid keyword or value */ public HeaderCard(String key, String value, String comment, boolean nullable) throws HeaderCardException { if (comment != null && comment.startsWith("ntf::")) { String ckey = comment.substring(5); // Get rid of ntf:: prefix comment = HeaderCommentsMap.getComment(ckey); } if (key == null && value != null) { throw new HeaderCardException("Null keyword with non-null value"); } if (key != null && key.length() > MAX_KEYWORD_LENGTH) { if (!FitsFactory.getUseHierarch() || !key.substring(0, 9).equals("HIERARCH.")) { throw new HeaderCardException("Keyword too long"); } } if (value != null) { value = value.replaceAll(" *$", ""); if (value.length() > MAX_VALUE_LENGTH) { throw new HeaderCardException("Value too long"); } if (value.startsWith("'")) { if (value.charAt(value.length() - 1) != '\'') { throw new HeaderCardException("Missing end quote in string value"); } value = value.substring(1, value.length() - 1).trim(); } } this.key = key; this.value = value; this.comment = comment; this.nullable = nullable; isString = true; }
/** * Create a HeaderCard from a FITS card image * * @param card the 80 character card image */ public HeaderCard(String card) { key = null; value = null; comment = null; isString = false; if (card.length() > 80) { card = card.substring(0, 80); } if (FitsFactory.getUseHierarch() && card.length() > 9 && card.substring(0, 9).equals("HIERARCH ")) { hierarchCard(card); return; } // We are going to assume that the value has no blanks in // it unless it is enclosed in quotes. Also, we assume that // a / terminates the string (except inside quotes) // treat short lines as special keywords if (card.length() < 9) { key = card; return; } // extract the key key = card.substring(0, 8).trim(); // if it is an empty key, assume the remainder of the card is a comment if (key.length() == 0) { key = ""; comment = card.substring(8); return; } // Non-key/value pair lines are treated as keyed comments if (key.equals("COMMENT") || key.equals("HISTORY") || !card.substring(8, 10).equals("= ")) { comment = card.substring(8).trim(); return; } // extract the value/comment part of the string String valueAndComment = card.substring(10).trim(); // If there is no value/comment part, we are done. if (valueAndComment.length() == 0) { value = ""; return; } int vend = -1; boolean quote = false; // If we have a ' then find the matching '. if (valueAndComment.charAt(0) == '\'') { int offset = 1; while (offset < valueAndComment.length()) { // look for next single-quote character vend = valueAndComment.indexOf("'", offset); // if the quote character is the last character on the line... if (vend == valueAndComment.length() - 1) { break; } // if we did not find a matching single-quote... if (vend == -1) { // pretend this is a comment card key = null; comment = card; return; } // if this is not an escaped single-quote, we are done if (valueAndComment.charAt(vend + 1) != '\'') { break; } // skip past escaped single-quote offset = vend + 2; } // break apart character string value = valueAndComment.substring(1, vend).trim(); value = value.replace("''", "'"); if (vend + 1 >= valueAndComment.length()) { comment = null; } else { comment = valueAndComment.substring(vend + 1).trim(); if (comment.charAt(0) == '/') { if (comment.length() > 1) { comment = comment.substring(1); } else { comment = ""; } } if (comment.length() == 0) { comment = null; } } isString = true; } else { // look for a / to terminate the field. int slashLoc = valueAndComment.indexOf('/'); if (slashLoc != -1) { comment = valueAndComment.substring(slashLoc + 1).trim(); value = valueAndComment.substring(0, slashLoc).trim(); } else { value = valueAndComment; } } }