/** * Construct a data entry. * * @param name A name used for diagnostics. * @param data The data for this entry. * @param charset The character encoding for this entry. */ public DataEntry(String name, byte[] data, String charset) { this.name = name; this.data = data.clone(); this.charset = charset; // The key always ends with \n, typically \r\n this.keyEnd = SwordUtil.findByte(this.data, SEPARATOR); }
/** * Get the position of the second \n in the data. This represents the end of the link and the * start of the rest of the data. * * @return the end of the link or -1 if not found. */ private int getLinkEnd() { if (linkEnd == 0) { linkEnd = SwordUtil.findByte(data, keyEnd + 1, SEPARATOR); if (linkEnd == -1) { linkEnd = data.length - 1; } } return linkEnd; }
/** * Get the key from this DataEntry. * * @return the key */ public String getKey() { if (key == null) { if (keyEnd < 0) { log.error("Failed to find key. name='{}'", name); return ""; } // The key may have whitespace, including \r on the end, // that is not actually part of the key. key = SwordUtil.decode(name, data, keyEnd, charset).trim(); // for some weird reason plain text dictionaries // all get \ added to the ends of the index entries. if (key.endsWith("\\")) { key = key.substring(0, key.length() - 1); } } return key; }
/** * Get the block start and entry position. * * @return the index of the block */ public DataIndex getBlockIndex() { int start = keyEnd + 1; return new DataIndex( SwordUtil.decodeLittleEndian32(data, start), SwordUtil.decodeLittleEndian32(data, start + 4)); }
/** * Get the raw text from this entry. * * @param cipherKey the key, if any, to (un)lock the text * @return the raw text */ public String getRawText(byte[] cipherKey) { int textStart = keyEnd + 1; cipher(cipherKey, textStart); return SwordUtil.decode(name, data, textStart, data.length - textStart, charset).trim(); }
/** * Get the link target for this entry. One entry can be chained to another. If the entry is not * linked then it is an error to call this method. * * @return the key to look up * @see #isLinkEntry() */ public String getLinkTarget() { // 6 represents the length of "@LINK" + 1 to skip the last separator. int linkStart = keyEnd + 6; int len = getLinkEnd() - linkStart + 1; return SwordUtil.decode(name, data, linkStart, len, charset).trim(); }