001 package edu.harvard.deas.hyperenc; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 006 import edu.harvard.deas.hyperenc.util.HexCoder; 007 import edu.harvard.deas.hyperenc.util.Pair; 008 009 /** 010 * Parses plain-text representations of hyper-encryption protocol messages 011 * according to the following specification: 012 * <p> 013 * <b>Master reconciliation message</b>: Each line contains one ID-hash pair. 014 * The integer ID comes first, followed by a single space, followed by the hash, 015 * encoded as a hexadecimal number using digits 0-9 and a-f (case-insensitive). 016 * <p> 017 * <b>Slave reconciliation message</b>: Each line contains one ID-code pair. The 018 * integer ID comes first, followed by a single space, followed by a result 019 * code, which must be one of the following single-character strings: 020 * <ul> 021 * <li>"<b>+</b>" for SlaveRecResult.SUCCESS</li> 022 * <li>"<b>0</b>" for SlaveRecResult.NO_RESULT</li> 023 * <li>"<b>-</b>" for SlaveRecResult.FAILURE</li> 024 * </ul> 025 * @see SlaveRecResult 026 */ 027 public class PlainTextMessageParser extends MessageParser { 028 029 @Override 030 public List<Pair<Integer, byte[]>> parseMRec(String message) 031 throws MessageParseException { 032 List<Pair<Integer,byte[]>> result = new ArrayList<Pair<Integer,byte[]>>(); 033 034 String lines[] = message.split("\\r?\\n"); 035 for (String line : lines) { 036 String tokens[] = line.split(" ", 2); 037 int id; 038 byte[] hash; 039 040 try { 041 id = Integer.parseInt(tokens[0]); 042 } catch (NumberFormatException e) { 043 throw new MessageParseException( 044 "Illegal ID: " + tokens[0], message, e); 045 } 046 047 try { 048 hash = HexCoder.decode(tokens[1].toLowerCase()); 049 } catch (IllegalArgumentException e) { 050 throw new MessageParseException( 051 "Illegal hash string: " + tokens[1], message, e); 052 } 053 054 result.add(new Pair<Integer,byte[]>(id, hash)); 055 } 056 057 return result; 058 } 059 060 @Override 061 public List<Pair<Integer, SlaveRecResult>> parseSRec(String message) 062 throws MessageParseException { 063 List<Pair<Integer,SlaveRecResult>> result = 064 new ArrayList<Pair<Integer,SlaveRecResult>>(); 065 066 String lines[] = message.split("\\r?\\n"); 067 for (String line : lines) { 068 String tokens[] = line.split(" ", 2); 069 int id; 070 SlaveRecResult res; 071 072 try { 073 id = Integer.parseInt(tokens[0]); 074 } catch (NumberFormatException e) { 075 throw new MessageParseException( 076 "Illegal ID: " + tokens[0], message, e); 077 } 078 079 if (tokens[1].equals("+")) 080 res = SlaveRecResult.SUCCESS; 081 else if (tokens[1].equals("0")) 082 res = SlaveRecResult.NO_RESULT; 083 else if (tokens[1].equals("-")) 084 res = SlaveRecResult.FAILURE; 085 else 086 throw new MessageParseException( 087 "Illegal result code: " + tokens[1], message); 088 089 result.add(new Pair<Integer,SlaveRecResult>(id, res)); 090 } 091 092 return result; 093 } 094 095 @Override 096 public String mrecToString(List<Pair<Integer, byte[]>> lst) { 097 String result = ""; 098 099 for (Pair<Integer,byte[]> p : lst) { 100 int id = p.first(); 101 byte[] hash = p.second(); 102 103 String line = id + " " + HexCoder.encode(hash) + "\n"; 104 result += line; 105 } 106 107 return result; 108 } 109 110 /** 111 * {@inheritDoc} 112 * @throws IllegalArgumentException 113 * if a result in <code>lst</code> is not supported by this parser 114 */ 115 @Override 116 public String srecToString(List<Pair<Integer, SlaveRecResult>> lst) { 117 String result = ""; 118 119 for (Pair<Integer,SlaveRecResult> p : lst) { 120 int id = p.first(); 121 SlaveRecResult res = p.second(); 122 String code; 123 124 switch (res) { 125 case SUCCESS: 126 code = "+"; break; 127 case NO_RESULT: 128 code = "0"; break; 129 case FAILURE: 130 code = "-"; break; 131 default: 132 throw new IllegalArgumentException( 133 "Invalid result code " + res.toString()); 134 } 135 136 String line = id + " " + code + "\n"; 137 result += line; 138 } 139 140 return result; 141 } 142 143 }