001/*
002 * MIT License
003 * 
004 * Copyright (c) 2016 Michael Angstadt
005 * 
006 * Permission is hereby granted, free of charge, to any person obtaining a copy
007 * of this software and associated documentation files (the "Software"), to deal
008 * in the Software without restriction, including without limitation the rights
009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010 * copies of the Software, and to permit persons to whom the Software is
011 * furnished to do so, subject to the following conditions:
012 * 
013 * The above copyright notice and this permission notice shall be included in
014 * all copies or substantial portions of the Software.
015 * 
016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
022 * SOFTWARE.
023 */
024
025package com.github.mangstadt.vinnie;
026
027/**
028 * Contains miscellaneous utility methods.
029 * @author Michael Angstadt
030 */
031public final class Utils {
032        /**
033         * Trims the whitespace off the left side of a string.
034         * @param string the string to trim
035         * @return the trimmed string
036         */
037        public static String ltrim(String string) {
038                int i;
039                for (i = 0; i < string.length() && Character.isWhitespace(string.charAt(i)); i++) {
040                        //do nothing
041                }
042                return string.substring(i);
043        }
044
045        /**
046         * Trims the whitespace off the right side of a string.
047         * @param string the string to trim
048         * @return the trimmed string
049         */
050        public static String rtrim(String string) {
051                int i;
052                for (i = string.length() - 1; i >= 0 && Character.isWhitespace(string.charAt(i)); i--) {
053                        //do nothing
054                }
055                return string.substring(0, i + 1);
056        }
057
058        /**
059         * <p>
060         * Escapes all newline sequences in a string with "\n".
061         * </p>
062         * <p>
063         * This method is 3x faster than a regex when the string has newlines to
064         * escape and 6x faster when it doesn't have newlines to escape.
065         * </p>
066         * @param string the string
067         * @return the escaped string
068         */
069        public static String escapeNewlines(String string) {
070                StringBuilder sb = null;
071                char prev = 0;
072                for (int i = 0; i < string.length(); i++) {
073                        char c = string.charAt(i);
074
075                        if (c == '\r' || c == '\n') {
076                                if (sb == null) {
077                                        sb = new StringBuilder(string.length() * 2);
078                                        sb.append(string, 0, i);
079                                }
080
081                                if (c == '\n' && prev == '\r') {
082                                        /*
083                                         * Do not write a second newline escape sequence if the
084                                         * newline sequence is "\r\n".
085                                         */
086                                } else {
087                                        sb.append("\\n");
088                                }
089                        } else if (sb != null) {
090                                sb.append(c);
091                        }
092
093                        prev = c;
094                }
095                return (sb == null) ? string : sb.toString();
096        }
097
098        private Utils() {
099                //hide default constructor
100        }
101}