Package mireka.address.parser

Source Code of mireka.address.parser.AddressLiteralParser

package mireka.address.parser;

import java.text.ParseException;

import mireka.address.parser.Ipv4Parser.Ipv4;
import mireka.address.parser.Ipv6Parser.Ipv6;
import mireka.address.parser.ast.AddressLiteralRemotePartAST;
import mireka.address.parser.ast.Ipv4RemotePartAST;
import mireka.address.parser.ast.Ipv6RemotePartAST;
import mireka.address.parser.base.CharParser;
import mireka.address.parser.base.CharScanner;

/**
* AddressLiteralParser parses the remote part of an SMTP mailbox (after the
* '@').
*/
public class AddressLiteralParser extends CharParser {

    public AddressLiteralParser(CharScanner charScanner) {
        super(charScanner);
    }

    public AddressLiteralRemotePartAST parse() throws ParseException {
        AddressLiteralRemotePartAST remotePartAST =
                parseAddressLiteralRemotePart();
        scanner.pushBack(currentToken);
        decorateWithInetAddress(remotePartAST);
        return remotePartAST;
    }

    private AddressLiteralRemotePartAST parseAddressLiteralRemotePart()
            throws ParseException {
        pushPosition();
        pushSpelling();

        accept('[');

        scanner.pushBack(currentToken);
        AddressLiteralTagScanner addressLiteralTagScanner =
                new AddressLiteralTagScanner(scanner);
        AddressLiteralTagToken tagToken = addressLiteralTagScanner.scan();
        addressLiteralTagScanner.finish();
        currentToken = scanner.scan();
        spelling.append(tagToken.spelling);
        switch (tagToken.kind) {
        case DIGIT:
            Ipv4 ipv4AST = parseIpv4AddressLiteral();
            accept(']');
            return new Ipv4RemotePartAST(popPosition(), popSpelling(), ipv4AST);
        case IPv6:
            accept(':');
            Ipv6 ipv6AST = parseIpv6AddressLiteral();
            accept(']');
            return new Ipv6RemotePartAST(popPosition(), popSpelling(), ipv6AST);
        case STANDARDIZED_TAG:
            throw tagToken
                    .syntaxException("IPv4 address literal or 'IPv6' tag");
        default:
            throw new RuntimeException("Assertion failed");
        }
    }

    private Ipv4 parseIpv4AddressLiteral() throws ParseException {
        scanner.pushBack(currentToken);
        Ipv4 ipv4 = new Ipv4Parser(scanner).parseLeft();
        currentToken = scanner.scan();
        spelling.append(ipv4.spelling);
        return ipv4;
    }

    private Ipv6 parseIpv6AddressLiteral() throws ParseException {
        scanner.pushBack(currentToken);
        Ipv6 ipv6 = new Ipv6Parser(scanner).parseLeft();
        currentToken = scanner.scan();
        spelling.append(ipv6.spelling);
        return ipv6;
    }

    private void decorateWithInetAddress(AddressLiteralRemotePartAST remotePartAST) {
        if (remotePartAST instanceof Ipv4RemotePartAST) {
            Ipv4RemotePartAST ipv4RemotePartAST = (Ipv4RemotePartAST) remotePartAST;
            remotePartAST.addressBytes = ipv4RemotePartAST.ipv4.addressBytes;
            remotePartAST.address = ipv4RemotePartAST.ipv4.address;
        } else if (remotePartAST instanceof Ipv6RemotePartAST) {
            Ipv6RemotePartAST ipv6RemotePartAST = (Ipv6RemotePartAST) remotePartAST;
            remotePartAST.addressBytes = ipv6RemotePartAST.ipv6.addressBytes;
            remotePartAST.address = ipv6RemotePartAST.ipv6.address;
        } else {
            throw new RuntimeException("Assertion failed");
        }
    }

}
TOP

Related Classes of mireka.address.parser.AddressLiteralParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.