Newer
Older
libj / modules / j / base / src / env.cpp
#include <cerrno>
#include <cstring>

#include <j/lang/env.hpp>

namespace j
{
    namespace lang
    {
        namespace Env
        {

            /**
             * 指定された環境変数の値を取得します。
             * name に = が含まれている場合、= の前までをキーとして
             * 環境変数を検索します。
             *
             * @param name 環境変数名
             * @return 値
             */
            String get(const String &name)
            {
                String keyName = name;
                int eqPos = keyName.indexOf('=');
                if (eqPos >= 0)
                {
                    keyName = std::move(keyName.substring(0, eqPos));
                }
#if (IS_WINDOWS)
                constexpr DWORD J_ENV_BUFFER_MAX = 32767; // Windows の環境変数の最大長は 327676
                unique_ptr<char[]> buff = make_unique<char[]>(J_ENV_BUFFER_MAX);
                DWORD ret = GetEnvironmentVariable(keyName, &buff[0], J_ENV_BUFFER_MAX);
                if (ret != 0)
                {
                    return String(buff.get());
                }
                return String();
#else
                return String(getenv(keyName));
#endif
            }

            /**
             * 指定された name の環境変数が存在しない場合、環境変数 name に指定された値 value を設定します。
             * overwrite が true の場合、その値を value に変更します。
             * false の場合、name の値を変更せず true を返します。
             * name に '=' 文字が含まれている場合、設定に失敗し false を返します。
             *
             * @param name 環境変数名
             * @param value 値
             * @param overwrite true/false (上書きする/しない)
             * @return true/false (設定成功/失敗)
             */
            bool set(const String &name, const String &value, bool overwrite)
            {
#if (IS_WINDOWS)
                int eqPos = name.indexOf('=');
                if (eqPos >= 0)
                {
                    return false;
                }
                char buff[1];
                DWORD ret = GetEnvironmentVariable(name, buff, 1);
                if ((!overwrite) && (ret != 0))
                { // 既に環境変数が存在し、overwrite が false のため成功
                    return true;
                }
                ret = SetEnvironmentVariable(name, value);
                return (ret != 0);
#else
                int overwriteFlag = overwrite ? 1 : 0;
                int ret = setenv(name, value, overwriteFlag);
                return (ret == 0);
#endif
            }

            /**
             * 変数 name の環境変数を削除します。
             *
             * @param name 環境変数名
             * @return true/false (成功/失敗)
             */
            bool unset(const String &name)
            {
#if (IS_WINDOWS)
                BOOL ret = SetEnvironmentVariable(name, NULL);
                return (ret != 0);
#else
                int ret = unsetenv(name);
                return (ret == 0);
#endif
            }

        } // namespace Errno
    } // namespace lang
} // namespace j