aboutsummaryrefslogtreecommitdiffstats
path: root/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/template/Token.java
blob: a83dab72025e3396b2038e6282227544452493db (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.node.admin.task.util.template;

import com.yahoo.vespa.hosted.node.admin.task.util.text.Cursor;
import com.yahoo.vespa.hosted.node.admin.task.util.text.CursorRange;

import java.util.Optional;

/**
 * @author hakonhall
 */
class Token {
    static final char NEGATE_CHAR = '!';
    static final char REMOVE_NEWLINE_CHAR = '-';
    static final char VARIABLE_DIRECTIVE_CHAR = '=';

    static Optional<String> skipId(Cursor cursor) {
        if (cursor.eot() || !isIdStart(cursor.getChar())) return Optional.empty();

        Cursor start = new Cursor(cursor);
        cursor.increment();

        while (!cursor.eot() && isIdPart(cursor.getChar()))
            cursor.increment();

        return Optional.of(new CursorRange(start, cursor).string());
    }

    /** A delimiter either starts a directive (e.g. %{) or ends it (e.g. }). */
    static String verifyDelimiter(String delimiter) {
        if (!isAsciiToken(delimiter)) {
            throw new IllegalArgumentException("Invalid delimiter: '" + delimiter + "'");
        }
        return delimiter;
    }

    /** Returns true for a non-empty string with only ASCII token characters. */
    private static boolean isAsciiToken(String string) {
        if (string.isEmpty()) return false;
        for (char c : string.toCharArray()) {
            if (!isAsciiTokenChar(c)) return false;
        }
        return true;
    }

    /** Returns true if char is a printable ASCII character except space (isgraph(3)). */
    private static boolean isAsciiTokenChar(char c) {
        // 0x1F unit separator
        // 0x20 space
        // 0x21 !
        // ...
        // 0x7E ~
        // 0x7F del
        return 0x20 < c && c < 0x7F;
    }

    // Our identifiers are equivalent to a Java identifiers.
    private static boolean isIdStart(char c) { return Character.isJavaIdentifierStart(c); }
    private static boolean isIdPart(char c) { return Character.isJavaIdentifierPart(c); }
}