001package gudusoft.gsqlparser.dlineage.graph.utils;
002
003import java.io.IOException;
004import java.io.StringWriter;
005import java.io.Writer;
006import java.util.Locale;
007
008public abstract class StringTranslator {
009
010    protected static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
011
012    public StringTranslator() {
013    }
014
015    public abstract int translate(CharSequence input, int index, Writer out) throws IOException;
016
017    public final String translate(CharSequence input) {
018        if (input == null) {
019            return null;
020        }
021        try (StringWriter writer = new StringWriter(input.length() * 2)) {
022            translate(input, writer);
023            return writer.toString();
024        } catch (IOException e) {
025            throw new RuntimeException(e);
026        }
027    }
028
029    public final void translate(CharSequence input, Writer out) throws IOException {
030        if (out == null) {
031            throw new IllegalArgumentException("The Writer must not be null");
032        }
033        if (input == null) return;
034
035        int currentPos = 0;
036        final int inputLength = input.length();
037
038        while (currentPos < inputLength) {
039            int consumedChars = translate(input, currentPos, out);
040
041            if (consumedChars == 0) {
042                char currentChar = input.charAt(currentPos++);
043                out.write(currentChar);
044
045                // 处理高/低代理对
046                if (Character.isHighSurrogate(currentChar) && currentPos < inputLength) {
047                    char nextChar = input.charAt(currentPos);
048                    if (Character.isLowSurrogate(nextChar)) {
049                        out.write(nextChar);
050                        currentPos++;
051                    }
052                }
053            } else {
054                for (int i = 0; i < consumedChars; i++) {
055                    currentPos += Character.charCount(Character.codePointAt(input, currentPos));
056                }
057            }
058        }
059    }
060
061    public final StringTranslator with(StringTranslator... translators) {
062        StringTranslator[] combined = new StringTranslator[translators.length + 1];
063        combined[0] = this;
064        System.arraycopy(translators, 0, combined, 1, translators.length);
065        return new Translators(combined);
066    }
067
068    public static String hex(int codepoint) {
069        return Integer.toHexString(codepoint).toUpperCase(Locale.ENGLISH);
070    }
071}