package com.subgraph.orchid.circuits.hs; import com.subgraph.orchid.TorParsingException; import com.subgraph.orchid.data.HexDigest; import com.subgraph.orchid.directory.parsing.BasicDocumentParsingResult; import com.subgraph.orchid.directory.parsing.DocumentFieldParser; import com.subgraph.orchid.directory.parsing.DocumentParser; import com.subgraph.orchid.directory.parsing.DocumentParsingHandler; import com.subgraph.orchid.directory.parsing.DocumentParsingResult; import com.subgraph.orchid.directory.parsing.DocumentParsingResultHandler; public class IntroductionPointParser implements DocumentParser<IntroductionPoint>{ private final DocumentFieldParser fieldParser; private DocumentParsingResultHandler<IntroductionPoint> resultHandler; private IntroductionPoint currentIntroductionPoint; public IntroductionPointParser(DocumentFieldParser fieldParser) { this.fieldParser = fieldParser; this.fieldParser.setHandler(createParsingHandler()); } public boolean parse(DocumentParsingResultHandler<IntroductionPoint> resultHandler) { this.resultHandler = resultHandler; try { fieldParser.processDocument(); return true; } catch(TorParsingException e) { resultHandler.parsingError(e.getMessage()); return false; } } public DocumentParsingResult<IntroductionPoint> parse() { final BasicDocumentParsingResult<IntroductionPoint> result = new BasicDocumentParsingResult<IntroductionPoint>(); parse(result); return result; } private DocumentParsingHandler createParsingHandler() { return new DocumentParsingHandler() { public void parseKeywordLine() { processKeywordLine(); } public void endOfDocument() { validateAndReportIntroductionPoint(currentIntroductionPoint); } }; } private void resetIntroductionPoint(HexDigest identity) { validateAndReportIntroductionPoint(currentIntroductionPoint); currentIntroductionPoint = new IntroductionPoint(identity); } private void validateAndReportIntroductionPoint(IntroductionPoint introductionPoint) { if(introductionPoint == null) { return; } if(introductionPoint.isValidDocument()) { resultHandler.documentParsed(introductionPoint); } else { resultHandler.documentInvalid(introductionPoint, "Invalid introduction point"); } } private void processKeywordLine() { final IntroductionPointKeyword keyword = IntroductionPointKeyword.findKeyword(fieldParser.getCurrentKeyword()); if(!keyword.equals(IntroductionPointKeyword.UNKNOWN_KEYWORD)) { processKeyword(keyword); } } private void processKeyword(IntroductionPointKeyword keyword) { switch(keyword) { case INTRO_AUTHENTICATION: break; case INTRODUCTION_POINT: resetIntroductionPoint(fieldParser.parseBase32Digest()); break; case IP_ADDRESS: if(currentIntroductionPoint != null) { currentIntroductionPoint.setAddress(fieldParser.parseAddress()); } break; case ONION_KEY: if(currentIntroductionPoint != null) { currentIntroductionPoint.setOnionKey(fieldParser.parsePublicKey()); } break; case ONION_PORT: if(currentIntroductionPoint != null) { currentIntroductionPoint.setOnionPort(fieldParser.parsePort()); } break; case SERVICE_KEY: if(currentIntroductionPoint != null) { currentIntroductionPoint.setServiceKey(fieldParser.parsePublicKey()); } break; case SERVICE_AUTHENTICATION: break; case UNKNOWN_KEYWORD: break; } } }