// =========================================================== //
//                                                             //
//   File      : sized_cstr.h                                  //
//   Purpose   : helper class to reduce calls to strlen()      //
//                                                             //
//   Coded by Ralf Westram (coder@reallysoft.de) in May 2018   //
//   http://www.arb-home.de/                                   //
//                                                             //
// =========================================================== //

#ifndef SIZED_CSTR_H
#define SIZED_CSTR_H

#ifndef ARB_ASSERT_H
#include "arb_assert.h"
#endif
#ifndef _GLIBCXX_LIMITS
#include <limits>
#endif
#ifndef _GLIBCXX_CSTDLIB
#include <cstdlib>
#endif

#define UNKNOWN_LENGTH std::numeric_limits<size_t>::max()

class SizedCstr {
    const char     *cstr;
    mutable size_t  len;

public:
    SizedCstr()                               : cstr(NULp), len(UNKNOWN_LENGTH) {}
    explicit SizedCstr(const char *str)       : cstr(str),  len(UNKNOWN_LENGTH) {}
    SizedCstr(const char *str, size_t length) : cstr(str),  len(length)  {
        arb_assert(strlen(str) >= length); // allow to truncate buffer by specifying a smaller length
    }

    bool isNull() const { return cstr == NULp; }
    bool isSet() const { return !isNull(); }

    operator const char*() const { arb_assert(isSet()); return cstr; }

    size_t get_length() const {
        arb_assert(isSet());
        if (len == UNKNOWN_LENGTH) len = strlen(cstr);
        return len;
    }
};

#undef UNKNOWN_LENGTH

#else
#error sized_cstr.h included twice
#endif // SIZED_CSTR_H
