suneido.util.Util.java Source code

Java tutorial

Introduction

Here is the source code for suneido.util.Util.java

Source

/* Copyright 2008 (c) Suneido Software Corp. All rights reserved.
 * Licensed under GPLv2.
 */

package suneido.util;

import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Lists;

import suneido.runtime.Ops;

/**
 * Miscellaneous functions.
 */
@ThreadSafe
public class Util {
    /** Readline limit for SuFile, SocketClient, and RunPiped.
     * Should be consistent with cSuneido.
     */
    public static final int MAX_LINE = 4000;

    public static boolean isCapitalized(String s) {
        return Character.isUpperCase(s.charAt(0));
    }

    public static String capitalize(String s) {
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }

    public static String uncapitalize(String s) {
        return s.substring(0, 1).toLowerCase() + s.substring(1);
    }

    /** @return original string if sub not found */
    public static String beforeFirst(String s, String sub) {
        int i = s.indexOf(sub);
        return (i == -1) ? s : s.substring(0, i);
    }

    /** @return original string if sub not found */
    public static String beforeLast(String s, String sub) {
        int i = s.lastIndexOf(sub);
        return (i == -1) ? s : s.substring(0, i);
    }

    /** @return "" if sub not found */
    public static String afterFirst(String s, String sub) {
        int i = s.indexOf(sub);
        return (i == -1) ? "" : s.substring(i + sub.length());
    }

    /***
     * Return the contents of a StringBuilder with any trailing returns removed.
     * <p>
     * Used by Readline in SuFile, RunPiped, and SocketClient
     */
    public static String toLine(StringBuilder sb) {
        int n = sb.length();
        while (n > 0 && sb.charAt(n - 1) == '\r')
            --n;
        return sb.substring(0, n);
    }

    @SuppressWarnings("unchecked")
    public static <T> String listToCommas(Collection<T> list) {
        if (list == null || list.isEmpty())
            return "";
        CommaStringBuilder sb = new CommaStringBuilder();
        for (T x : list)
            sb.add(x instanceof List ? listToParens((List<String>) x) : Ops.toStr(x));
        return sb.toString();
    }

    @SuppressWarnings("unchecked")
    public static <T> String displayListToCommas(Collection<T> list) {
        if (list == null || list.isEmpty())
            return "";
        CommaStringBuilder sb = new CommaStringBuilder();
        for (T x : list)
            sb.add(x instanceof List ? displayListToParens((List<String>) x) : Ops.display(x));
        return sb.toString();
    }

    public static <T> String listToParens(Collection<T> list) {
        return "(" + listToCommas(list) + ")";
    }

    public static <T> String displayListToParens(Collection<T> list) {
        return "(" + displayListToCommas(list) + ")";
    }

    public static final Joiner commaJoiner = Joiner.on(",");

    public static final Splitter commaSplitter = Splitter.on(',').trimResults();

    public static Iterable<String> commaSplitter(String s) {
        if (s.isEmpty())
            return Collections.emptyList();
        else
            return commaSplitter.split(s);
    }

    public static List<String> commasToList(String s) {
        return Lists.newArrayList(commaSplitter(s));
    }

    /** NOTE: inefficient space-wise - uses one char (2 bytes) per byte */
    public static String bytesToString(byte[] bytes) {
        return bytesToString(bytes, bytes.length);
    }

    /** NOTE: inefficient space-wise - uses one char (2 bytes) per byte */
    public static String bytesToString(byte[] bytes, int len) {
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; ++i)
            sb.append((char) (bytes[i] & 0xff));
        return sb.toString();
    }

    /** NOTE: inefficient space-wise - uses one char (2 bytes) per byte */
    public static String bytesToString(ByteBuffer buf) {
        StringBuilder sb = new StringBuilder(buf.remaining());
        for (int i = buf.position(); i < buf.limit(); ++i)
            sb.append((char) (buf.get(i) & 0xff));
        return sb.toString();
    }

    public static byte[] stringToBytes(String s) {
        byte[] bytes = new byte[s.length()];
        for (int i = 0; i < s.length(); ++i)
            bytes[i] = (byte) s.charAt(i);
        return bytes;
    }

    /**
     * @return A new list containing all the values from x and y. <b>x is copied as
     *         is</b>, so if it has duplicates they are retained. Duplicates from y
     *         are not retained.
     */
    public static <T> List<T> union(List<T> x, List<T> y) {
        return addAllUnique(new ArrayList<>(x), y);
    }

    public static <T> ImmutableSet<T> setUnion(Collection<T> x, Collection<T> y) {
        Builder<T> builder = new ImmutableSet.Builder<T>();
        if (x != null)
            builder.addAll(x);
        if (y != null)
            builder.addAll(y);
        return builder.build();
    }

    public static <T> ImmutableSet<T> setIntersect(Collection<T> x, Collection<T> y) {
        if (y instanceof Set) {
            Collection<T> tmp = x;
            x = y;
            y = tmp;
        }
        ImmutableSet.Builder<T> builder = ImmutableSet.builder();
        for (T e : y)
            if (x.contains(e))
                builder.add(e);
        return builder.build();
    }

    /** modifies list */
    public static <T> List<T> addAllUnique(List<T> list, List<T> x) {
        for (T s : x)
            if (!list.contains(s))
                list.add(s);
        return list;
    }

    /** modifies list */
    public static <T> List<T> addUnique(List<T> list, T x) {
        if (!list.contains(x))
            list.add(x);
        return list;
    }

    /** returns a new list */
    public static <T> List<T> withoutDups(List<T> x) {
        List<T> result = new ArrayList<>();
        for (T s : x)
            if (!result.contains(s))
                result.add(s);
        return result;
    }

    /** returns a new list */
    public static <T> List<T> difference(List<T> x, List<T> y) {
        List<T> result = new ArrayList<>();
        for (T s : x)
            if (!y.contains(s))
                result.add(s);
        return result;
    }

    public static <T> ImmutableSet<T> setDifference(Collection<T> x, Collection<T> y) {
        ImmutableSet.Builder<T> builder = ImmutableSet.builder();
        for (T s : x)
            if (!y.contains(s))
                builder.add(s);
        return builder.build();
    }

    /** @return A new list */
    public static <T> List<T> intersect(List<T> x, List<T> y) {
        List<T> result = new ArrayList<>();
        for (T s : x)
            if (y.contains(s))
                result.add(s);
        return result;
    }

    /** @return Whether or not the first list starts with the second */
    public static <T> boolean startsWith(List<T> x, List<T> y) {
        if (y == null)
            return true; // to match cSuneido prefix
        if (x == null)
            return false; // to match cSuneido prefix
        if (y.size() > x.size())
            return false;
        for (int i = 0; i < y.size(); ++i)
            if (!x.get(i).equals(y.get(i)))
                return false;
        return true;
    }

    public static <T> boolean startsWithSet(List<T> list, List<T> set) {
        int set_size = set.size();
        if (list.size() < set_size)
            return false;
        for (int i = 0; i < set_size; ++i)
            if (!set.contains(list.get(i)))
                return false;
        return true;
    }

    public static <T> boolean setEquals(Collection<T> x, Collection<T> y) {
        if (y instanceof Set) {
            Collection<T> tmp = x;
            x = y;
            y = tmp;
        }
        int n = 0;
        for (T s : y)
            if (x.contains(s))
                ++n;
        return n == x.size() && n == y.size();
    }

    public static <T> boolean nil(Collection<T> x) {
        return x == null || x.isEmpty();
    }

    /** @return A new list containing the two lists concatenated */
    public static <T> List<T> concat(List<T> x, List<T> y) {
        List<T> result = new ArrayList<>(x);
        result.addAll(y);
        return result;
    }

    /** @return A new list with all occurrences of a value removed */
    public static <T> List<T> without(List<T> list, T x) {
        List<T> result = new ArrayList<>();
        for (T y : list)
            if (x == null ? y != null : !x.equals(y))
                result.add(y);
        return result;
    }

    @SafeVarargs
    public static <T> T[] array(T... values) {
        return values;
    }

    public static <T> List<T> updateAll(List<T> v, Function<T, T> fn) {
        for (int i = 0; i < v.size(); ++i)
            v.set(i, fn.apply(v.get(i)));
        return v;
    }

    /**
     * Based on C++ STL code.
     *
     * @return The <u>first</u> position where value could be inserted without
     *         changing the ordering.
     */
    public static <T extends Comparable<? super T>> int lowerBound(List<T> list, T value) {
        int first = 0;
        int len = list.size();
        while (len > 0) {
            int half = len >> 1;
            int middle = first + half;
            if (list.get(middle).compareTo(value) < 0) {
                first = middle + 1;
                len -= half + 1;
            } else
                len = half;
        }
        return first;
    }

    public static <T> int lowerBound(List<T> list, T value, Comparator<? super T> comp) {
        int first = 0;
        int len = list.size();
        while (len > 0) {
            int half = len >> 1;
            int middle = first + half;
            if (comp.compare(list.get(middle), value) < 0) {
                first = middle + 1;
                len -= half + 1;
            } else
                len = half;
        }
        return first;
    }

    public static <T extends Comparable<? super T>> int lowerBound(T[] list, T value) {
        int first = 0;
        int len = list.length;
        while (len > 0) {
            int half = len >> 1;
            int middle = first + half;
            if (list[middle].compareTo(value) < 0) {
                first = middle + 1;
                len -= half + 1;
            } else
                len = half;
        }
        return first;
    }

    public static <T> int lowerBound(T[] list, T value, Comparator<? super T> cmp) {
        int first = 0;
        int len = list.length;
        while (len > 0) {
            int half = len >> 1;
            int middle = first + half;
            if (cmp.compare(list[middle], value) < 0) {
                first = middle + 1;
                len -= half + 1;
            } else
                len = half;
        }
        return first;
    }

    public static int lowerBound(int[] list, int value, IntComparator cmp) {
        int first = 0;
        int len = list.length;
        while (len > 0) {
            int half = len >> 1;
            int middle = first + half;
            if (cmp.compare(list[middle], value) < 0) {
                first = middle + 1;
                len -= half + 1;
            } else
                len = half;
        }
        return first;
    }

    /**
     * Based on C++ STL code.
     *
     * @return The <u>last</u> position where slot could be inserted without
     *         changing the ordering.
     */
    public static <T extends Comparable<? super T>> int upperBound(List<T> list, T value) {
        int first = 0;
        int len = list.size();
        while (len > 0) {
            int half = len >> 1;
            int middle = first + half;
            if (value.compareTo(list.get(middle)) < 0)
                len = half;
            else {
                first = middle + 1;
                len -= half + 1;
            }
        }
        return first;
    }

    public static <T> int upperBound(List<T> list, T value, Comparator<? super T> comp) {
        int first = 0;
        int len = list.size();
        while (len > 0) {
            int half = len >> 1;
            int middle = first + half;
            if (comp.compare(value, list.get(middle)) < 0)
                len = half;
            else {
                first = middle + 1;
                len -= half + 1;
            }
        }
        return first;
    }

    public static <T> int upperBound(T[] list, T value, Comparator<? super T> comp) {
        int first = 0;
        int len = list.length;
        while (len > 0) {
            int half = len >> 1;
            int middle = first + half;
            if (comp.compare(value, list[middle]) < 0)
                len = half;
            else {
                first = middle + 1;
                len -= half + 1;
            }
        }
        return first;
    }

    public static int upperBound(int[] list, int value, IntComparator cmp) {
        int first = 0;
        int len = list.length;
        while (len > 0) {
            int half = len >> 1;
            int middle = first + half;
            if (cmp.compare(value, list[middle]) < 0)
                len = half;
            else {
                first = middle + 1;
                len -= half + 1;
            }
        }
        return first;
    }

    @GuardedBy("this")
    private static SimpleDateFormat datefmt = new SimpleDateFormat("yyyyMMdd.HHmmssSSS");

    synchronized public static String displayDate(Date date) {
        return date == null ? "null" : datefmt.format(date);
    }

    public static void interruptableSleep(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}