001package org.unix4j.unix.wc;
002
003import org.unix4j.line.Line;
004
005/**
006 * Constants for different count types.
007 */
008enum CounterType {
009        Lines {
010                @Override
011                public boolean isOptionSet(WcArguments args) {
012                        return args.isLines();
013                }
014
015                @Override
016                public int count(Line line) {
017                        return 1;
018                }
019        },
020        Words {
021                @Override
022                public boolean isOptionSet(WcArguments args) {
023                        return args.isWords();
024                }
025
026                @Override
027                public int count(Line line) {
028                        int words = 0;
029                        int wordlen = 0;
030                        final int len = line.getContentLength();
031                        for (int i = 0; i < len; i++) {
032                                final char ch = line.charAt(i);
033                                if (Character.isWhitespace(ch)) {
034                                        if (wordlen > 0) {
035                                                words++;
036                                        }
037                                        wordlen = 0;
038                                } else {
039                                        wordlen++;
040                                }
041                        }
042                        return wordlen > 0 ? words + 1 : words;
043                }
044        },
045        Chars {
046                @Override
047                public boolean isOptionSet(WcArguments args) {
048                        return args.isChars();
049                }
050
051                @Override
052                public int count(Line line) {
053                        return line.length();
054                }
055        };
056
057        /**
058         * Returns true if the option relevant for this count type is set in
059         * {@code args}.
060         * 
061         * @param args
062         *            the arguments with the count options
063         * @return true if this count type option is set
064         */
065        abstract public boolean isOptionSet(WcArguments args);
066
067        /**
068         * Returns the count by which a counter should be incremented given the
069         * specified {@code line}. For instance, the method returns 1 if this type
070         * specifies that lines are counted, and it returns the number of words or
071         * characters in the line if the count type refers to words or chars,
072         * respectively.
073         * 
074         * @param line
075         *            the line to analyse
076         * @return the increment to add to the counter for this count type and the
077         *         specified line
078         */
079        abstract public int count(Line line);
080}