Last active
February 4, 2021 16:52
-
-
Save juanplopes/ba6923ff1ae84d9c27f1 to your computer and use it in GitHub Desktop.
CharSequence with timeout (useful to timeout a backtracking regex)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Objects; | |
public class TimeoutString implements CharSequence { | |
private final CharSequence child; | |
private final long target; | |
private TimeoutString(CharSequence child, long target) { | |
this.child = child; | |
this.target = target; | |
} | |
public static TimeoutString wrap(CharSequence child, long timeout) { | |
return new TimeoutString(child, System.nanoTime() + timeout * 1000000); | |
} | |
public static CharSequence unwrap(CharSequence seq) { | |
while (seq instanceof TimeoutString) | |
seq = ((TimeoutString) seq).child; | |
return seq; | |
} | |
@SuppressWarnings("StringBufferReplaceableByString") | |
public static String unwrapToString(CharSequence seq) { | |
seq = unwrap(seq); | |
if (seq instanceof String || seq == null) | |
return (String) seq; | |
return String.valueOf(seq); | |
} | |
private void checkTarget() { | |
if (System.nanoTime() > target) | |
throw new IllegalStateException("String operation timeout."); | |
} | |
@Override | |
public int length() { | |
checkTarget(); | |
return child.length(); | |
} | |
@Override | |
public char charAt(int i) { | |
checkTarget(); | |
return child.charAt(i); | |
} | |
@Override | |
public CharSequence subSequence(int a, int b) { | |
checkTarget(); | |
return new TimeoutString(child.subSequence(a, b), target); | |
} | |
@Override | |
public String toString() { | |
return String.valueOf(child); | |
} | |
@Override | |
public boolean equals(Object o) { | |
if (this == o) return true; | |
if (!(o instanceof TimeoutString)) return false; | |
TimeoutString that = (TimeoutString) o; | |
return Objects.equals(this.child, that.child); | |
} | |
@Override | |
public int hashCode() { | |
return Objects.hash(this.child); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Good work, this is very useful.