package com.subgraph.orchid.directory.parsing;
import com.subgraph.orchid.TorParsingException;
import com.subgraph.orchid.crypto.TorMessageDigest;
import com.subgraph.orchid.crypto.TorPublicKey;
import com.subgraph.orchid.crypto.TorSignature;
import com.subgraph.orchid.data.HexDigest;
import com.subgraph.orchid.data.IPv4Address;
import com.subgraph.orchid.data.Timestamp;
/**
* This helper class is used by document parsing classes to extract individual
* fields from a directory document. The DocumentFieldParser also manages the
* InputStream which is the source of the document to parse. Parsing classes
* are implemented by creating an instance of the DocumentParsingHandler interface.
*
*/
public interface DocumentFieldParser {
/**
* Run the document parser. The {@link #setHandler(DocumentParsingHandler)} method must be
* called before calling this method to set a <code>DocumentParsingHandler</code> for processing
* this document.
*
* @throws TorParsingException If a parsing error occurs while processing the document.
*/
void processDocument();
/**
* Returns the number of unprocessed argument items on the current keyword line.
*
* @return The number of remaining arguments.
*/
int argumentsRemaining();
/**
* Extract the next argument item and return it as a String
*
* @return The next argument as a String
* @throws TorParsingException If no arguments are remaining on the current keyword line.
*/
String parseString();
/**
* Take all remaining arguments on the current keyword line and return them as a single space
* delimited String. If no arguments are remaining, then an empty String is returned.
*
* @return The remaining arguments on the current keyword line concatenated together.
*/
String parseConcatenatedString();
/**
* Extract the next argument and interpret it as an integer boolean value. The legal values
* are '1' for true or '0' for false.
* @return Return the next argument interpreted as a boolean value.
* @throws TorParsingException If no arguments are remaining or if the current argument cannot be
* parsed as a boolean integer value.
*/
boolean parseBoolean();
/**
* Extract the next argument item and return it as a <code>String</code> if it conforms to
* a legally formed router nickname (dir-spec.txt section 2.3).
*
* A router nickname must be between 1 and 19 alphanumeric characters ([A-Za-z0-9]) to
* be considered valid.
*
* @return The next argument as a <code>String</code> if it is a validly formatted nickname.
* @throws TorParsingException If no arguments are remaining or if the current argument is not
* a valid router nickname.
*/
String parseNickname();
/**
* Extract the next argument and interpret it as an integer.
*
* @return The next argument interpreted as an integer.
* @throws TorParsingException If no arguments are remaining or if the current argument cannot
* be parsed as an integer value.
*/
int parseInteger();
/**
* Parse the <code>item</code> argument as an integer.
*
* @param item A string to parse as an integer.
* @return The integer value of the <code>item</code> argument.
* @throws TorParsingException If the <code>item</code> argument cannot be parsed as an
* integer value.
*/
int parseInteger(String item);
/**
* Extract the next argument and interpret it as a comma separated list of integers.
*
* @return An array of integers.
* @throws TorParsingException If no arguments are remaining or if the current argument cannot
* be parsed as a list of integers.
*/
int[] parseIntegerList();
/**
* Extract the next argument and interpret it as a network port value. A valid port
* value is an integer between 0 and 65535 inclusive.
*
* @return The next argument interpreted as an integer port value.
* @throws TorParsingException If no arguments are remaining or if the current argument cannot
* be parsed as a legal port value.
*/
int parsePort();
/**
* Parse the <code>item</code> arguement as a network port value. A valid port value
* is an integer between 0 and 65535 inclusive.
*
* @param item A string to parse as an integer port value.
* @return The port integer value of the <code>item</code> argument
* @throws TorParsingException If the <code>item</code> argument cannot be parsed as a
* legal port value.
*/
int parsePort(String item);
/**
* Extract the next argument and interpret it as Base64 encoded binary data.
*
* @return The bytes decoded from the Base64 encoded argument.
* @throws TorParsingException If no arguments are remaining or if the current argument cannot
* be parsed as Base64 encoded data.
*/
byte[] parseBase64Data();
/**
* Extract the next two arguments and parse as a timestamp field.
*
* The format of a timestamp is: YYYY-MM-DD HH:MM:SS
*
* @return The parsed <code>Timestamp</code> value.
* @throws TorParsingException If there are not sufficient arguments remaining or if the current
* arguments could not be parsed as a timestamp field.
*/
Timestamp parseTimestamp();
/**
* Extract the next argument and interpret it as a hex encoded digest string.
*
* @return The parsed <code>HexDigest</code> value.
* @throws TorParsingException If no arguments are remaining or if the current argument cannot
* be parsed as a hex encoded digest string.
*/
HexDigest parseHexDigest();
/**
* Extract the next argument and interpret it as a base 32 encoded digest string.
*
* @return The parsed <code>HexDigest</code> value.
* @throws TorParsingException If no arguments are remaining or if the current argument cannot
* be parsed as a base 32 encoded digest string.
*/
HexDigest parseBase32Digest();
/**
* Extract all remaining arguments and interpret the concatenated string as a
* hex encoded fingerprint string.
*
* @return The parsed <code>HexDigest</code> value extracted from the concatenated string.
* @throws TorParsingException If the concatenation of the remaining arguments could not be parsed
* as a hex encoded fingerprint string.
*/
HexDigest parseFingerprint();
/**
* Extract the next argument and interpret it as an IPv4 network address in dotted quad notation.
*
* @return The parsed <code>IPv4Address</code> value.
* @throws TorParsingException If no arguments are remaining or if the current argument cannot
* be parsed as an IPv4 network address.
*/
IPv4Address parseAddress();
/**
* Extract a document object following the current keyword line and interpret it as a PEM
* encoded public key.
*
* @return The extracted <code>TorPublicKey</code> value.
* @throws TorParsingException If no document object is found following the current keyword line,
* or if the document object cannot be parsed as a PEM encoded public key.
*/
TorPublicKey parsePublicKey();
byte[] parseNtorPublicKey();
/**
* Extract a document object following the current keyword line and interpret it as a
* Base64 encoded PKCS1 signature object.
*
* @return The extracted <code>TorSignature</code> value.
* @throws TorParsingException If no document object is found following the current keyword line,
* or if the document object cannot be parsed as a signature.
*/
TorSignature parseSignature();
/**
* Extract a document object following the current keyword line and don't attempt to interpret
* it further.
*
* @return The extracted <code>DocumentObject</code>.
* @throws TorParsingException If no document object is found following the current keyword line.
*/
DocumentObject parseObject();
/**
*
* @return
*/
NameIntegerParameter parseParameter();
/**
* Return the keyword of the current keyword line. The keyword is the first token on the line
* unless the first token is 'opt' and 'opt' recognition is enabled. In this case, the keyword
* is the token immediately following the 'opt' token.
*
* @return The keyword token of the current keyword line.
*/
String getCurrentKeyword();
/**
* Return all lines from the current document as a single String.
*
* @return The raw data from the current document.
*/
String getRawDocument();
/**
* Empty the internal buffer which is capturing the raw data from
* the document which is being parsed.
*/
void resetRawDocument();
/**
* Empty the internal buffer which is capturing raw data from document being parsed and set buffer contents to <tt>initalContent</tt>.
*
* @param initialContent Initial raw document content.
*/
void resetRawDocument(String initialContent);
/**
* Reset the document signing state. Any lines read after calling this method will be included
* in the current signature hash.
*/
void startSignedEntity();
/**
* Set the current keyword line as the last line included in the current signature hash.
*/
void endSignedEntity();
/**
* Tells the parser to not include lines that begin with <code>token</code> in the current
* signature calculation.
*
* @param token The parser will not include lines that begin with <code>token</code> in the
* current signature.
*/
void setSignatureIgnoreToken(String token);
/**
* Return the internal message digest which is being used to calculate the
* signature over the current document.
*
* @return The <code>TorMessageDigest</code> instance or <code>null</code> if
* a signature is not being actively calculated.
*/
TorMessageDigest getSignatureMessageDigest();
TorMessageDigest getSignatureMessageDigest256();
/**
* Verify that current signature hash matches the specified <code>signature</code> signed
* with the public key <code>publicKey</code>
*
* @param publicKey The public key used to verify the signature.
* @param signature The signature to verify against the current signature hash.
* @return <code>true</code>If the <code>signature</code> argument matches the hash currently
* calculated document hash.
*/
boolean verifySignedEntity(TorPublicKey publicKey, TorSignature signature);
/**
* Test that the current keyword line has the correct number of arguments.
*
* @param keyword The name of the current keyword. (used for errors)
* @param argumentCount The expected number of arguments.
* @throws TorParsingException If the number of remaining arguments does not match
* <code>argumentCount</code>.
*/
void verifyExpectedArgumentCount(String keyword, int argumentCount);
/**
* Set a flag so that 'opt' tokens will be recognized at the start of keyword lines. If
* this flag is set, a token string 'opt' at the start of a keyword line will be ignored
* and the token following the 'opt' string will be interpreted as the keyword.
*/
void setRecognizeOpt();
/**
* The default delimiter between keyword line tokens is any whitespace. This method may
* be called to specify a different delimiter policy.
*
* @param delimeter A regular expression which matches the desired delimiter.
*/
void setDelimiter(String delimeter);
/**
* Set the callback handler which is used to process the document. This method must be called
* before calling {@link #processDocument()}.
*
* @param handler The callback handler.
*/
void setHandler(DocumentParsingHandler handler);
/**
* Log the specified message at the debug logging level.
*
* @param message The message to log.
*/
void logDebug(String message);
/**
* Log the specified message at the warn logging level.
*
* @param message The message to log.
*/
void logWarn(String message);
/**
* Log the specified message at the error logging level.
*
* @param message The message to log.
*/
void logError(String message);
}