#include "escaping.h"

namespace NEscaper {
    TEscaper::TEscaper() {
        used_keys_.fill(0);
    }

    TEscaper::TEscaper(TStringBuf str) : str_{str} {
        used_keys_.fill(0);
    }

    void TEscaper::AddMapping(char key, TStringBuf value) {
        values_[static_cast<ui8>(key)] = value;
        used_keys_[static_cast<ui8>(key)] = 1;
    }

    void TEscaper::SetStr(TStringBuf str) {
        str_ = str;
    }

    IOutputStream &operator<<(IOutputStream &out, const TEscaper &escaper) {
        const char *begin = escaper.str_.Data();
        const char *const end = escaper.str_.end();
        while (begin < end) {
            const char *p = begin;
            while (p < end && !escaper.used_keys_[static_cast<ui8>(*p)]) {
                ++p;
            }
            if (p != begin)
                out << TStringBuf(begin, p - begin);
            if (p == end)
                break;
            out << escaper.values_[static_cast<ui8>(*p)];
            begin = p + 1;
        }
        return out;
    }
}
