aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/protobuf/json/util.cpp
blob: 0145d6c67492d58496fec871c49f44633a7a0bb3 (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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "util.h" 
 
#include <util/string/ascii.h> 
 
namespace { 
    void ToSnakeCaseImpl(TString* const name, std::function<bool(const char)> requiresUnderscore) { 
        bool requiresChanges = false; 
        size_t size = name->size(); 
        for (size_t i = 0; i < name->size(); i++) { 
            if (IsAsciiUpper(name->at(i))) { 
                requiresChanges = true; 
                if (i > 0 && requiresUnderscore(name->at(i - 1))) { 
                    size++; 
                } 
            } 
        } 
 
        if (!requiresChanges) { 
            return; 
        } 
 
        if (size != name->size()) { 
            TString result; 
            result.reserve(size); 
            for (size_t i = 0; i < name->size(); i++) { 
                const char c = name->at(i); 
                if (IsAsciiUpper(c)) { 
                    if (i > 0 && requiresUnderscore(name->at(i - 1))) { 
                        result += '_'; 
                    } 
                    result += AsciiToLower(c); 
                } else { 
                    result += c; 
                } 
            } 
            *name = std::move(result); 
        } else { 
            name->to_lower(); 
        } 
    } 
} 

namespace NProtobufJson { 
    void ToSnakeCase(TString* const name) { 
        ToSnakeCaseImpl(name, [](const char prev) { return prev != '_'; }); 
    } 
 
    void ToSnakeCaseDense(TString* const name) { 
        ToSnakeCaseImpl(name, [](const char prev) { return prev != '_' && !IsAsciiUpper(prev); }); 
    } 
 
    bool EqualsIgnoringCaseAndUnderscores(TStringBuf s1, TStringBuf s2) {
        size_t i1 = 0, i2 = 0;

        while (i1 < s1.size() && i2 < s2.size()) {
            if (s1[i1] == '_') {
                ++i1;
            } else if (s2[i2] == '_') {
                ++i2;
            } else if (AsciiToUpper(s1[i1]) != AsciiToUpper(s2[i2])) {
                return false;
            } else {
                ++i1, ++i2;
            }
        }

        while (i1 < s1.size() && s1[i1] == '_') {
            ++i1;
        }
        while (i2 < s2.size() && s2[i2] == '_') {
            ++i2;
        }

        return (i1 == s1.size() && i2 == s2.size());
    }
}