<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#include "../StroikaPreComp.h"

#include "../Characters/Format.h"
#include "../Characters/String_Constant.h"
#include "../Characters/ToString.h"
#include "../Containers/Bijection.h"
#include "../DataExchange/Variant/CharacterDelimitedLines/Reader.h"
#include "../Debug/Trace.h"
#if qPlatform_Windows
#include "../Execution/Platform/Windows/Exception.h"
#endif
#include "../IO/FileSystem/FileInputStream.h"
#include "../IO/FileSystem/PathName.h"

#include "InternetMediaTypeRegistry.h"

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::DataExchange;
using namespace Stroika::Foundation::Execution;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

using FileSuffixType = InternetMediaTypeRegistry::FileSuffixType;

#if qPlatform_Windows
using Stroika::Foundation::Execution::Platform::Windows::ThrowIfNotERROR_SUCCESS;
#endif

#if qPlatform_Linux
// not sure what platforms have this
namespace {
    Mapping<FileSuffixType, InternetMediaType> GetGlobsFile_ ()
    {
        auto readGlobsFile = []() -> Mapping<FileSuffixType, InternetMediaType> {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
            Debug::TraceContextBumper ctx{L"{}readGlobsFile"};
#endif
            Mapping<FileSuffixType, InternetMediaType> results{};
            for (Sequence<String> line : DataExchange::Variant::CharacterDelimitedLines::Reader{{':'}}.ReadMatrix (IO::FileSystem::FileInputStream::New (L"/usr/share/mime/globs"))) {
                if (line.length () == 2) {
                    String glob = line[1];
                    if (glob.StartsWith ('*')) {
                        glob = glob.SubString (1);
                    }
                    results.Add (glob, InternetMediaType{line[0]});
                }
            }
#if USE_NOISY_TRACE_IN_THIS_MODULE_
            DbgTrace (L"returning %s", Characters::ToString (results).c_str ());
#endif
            return results;
        };
        static const Mapping<FileSuffixType, InternetMediaType> kData_ = readGlobsFile ();
        return kData_;
    }
}
#endif

#if qPlatform_Windows
namespace {
    // Based on code from HealthFrame. MAYBE someday do more generic version of this - as helper
    // @see https://stroika.atlassian.net/browse/STK-575
    struct OptionsFileHelper_ {
        OptionsFileHelper_ (HKEY hkey)
            : fKey (hkey)
        {
            Assert (nullptr != INVALID_HANDLE_VALUE);
            if (hkey == INVALID_HANDLE_VALUE or hkey == nullptr)
                [[UNLIKELY_ATTR]]
                {
                    Execution::Throw (SystemErrorException<> (ERROR_INVALID_HANDLE, system_category ()), "OptionsFileHelper::CTOR - bad handle");
                }
        }
        OptionsFileHelper_ (HKEY parentKey, const String& path, REGSAM samDesired = KEY_READ | KEY_WRITE)
            : fKey (OpenWithCreateAlongPath (parentKey, path, samDesired))
        {
            if (parentKey == INVALID_HANDLE_VALUE or parentKey == nullptr)
                [[UNLIKELY_ATTR]]
                {
                    Execution::Throw (SystemErrorException<> (ERROR_INVALID_HANDLE, system_category ()), "OptionsFileHelper::CTOR - bad handle");
                }
        }
        OptionsFileHelper_ ()                          = delete;
        OptionsFileHelper_ (const OptionsFileHelper_&) = delete;
        const OptionsFileHelper_& operator= (const OptionsFileHelper_&) const = delete;
        ~OptionsFileHelper_ ()
        {
            Assert (nullptr != INVALID_HANDLE_VALUE);
            Assert (fKey != nullptr);
            Assert (fKey != INVALID_HANDLE_VALUE);
            ::RegCloseKey (fKey);
        }
        /*
         * Walk the given path (in segments) - and make sure each exists, and create each segment if it doesn't
         * exist.Finally - do a regular registry open with access permissions 'samDesired'.< / p>
         */
        static HKEY OpenWithCreateAlongPath (HKEY parentKey, const String& path, REGSAM samDesired = KEY_READ | KEY_WRITE)
        {
            Debug::TraceContextBumper trcCtx{Stroika_Foundation_Debug_OptionalizeTraceArgs (L"OptionsFileHelper::OpenWithCreateAlongPath", L"parentKey=%p, path='%s'", parentKey, path.c_str ())};
            Require (parentKey != nullptr);
            size_t prevPos = 0;
            HKEY   curPar  = parentKey;
            for (;;) {
                size_t    endPos    = path.find ('\\', prevPos);
                SDKString segName   = path.AsSDKString ().substr (prevPos, endPos == SDKString::npos ? endPos : (endPos - prevPos));
                REGSAM    createSAM = (endPos == SDKString::npos) ? samDesired : KEY_READ;
                HKEY      newKey    = static_cast<HKEY> (INVALID_HANDLE_VALUE);

                ThrowIfNotERROR_SUCCESS (::RegCreateKeyEx (curPar, segName.c_str (), 0, REG_NONE, REG_OPTION_NON_VOLATILE, createSAM, nullptr, &newKey, nullptr));
                if (curPar != parentKey) {
                    ::RegCloseKey (curPar);
                }<commit_msg>cosmetic<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2019.  All rights reserved
 */
#include "../StroikaPreComp.h"

#include "../Characters/Format.h"
#include "../Characters/String_Constant.h"
#include "../Characters/ToString.h"
#include "../Containers/Bijection.h"
#include "../DataExchange/Variant/CharacterDelimitedLines/Reader.h"
#include "../Debug/Trace.h"
#if qPlatform_Windows
#include "../Execution/Platform/Windows/Exception.h"
#endif
#include "../IO/FileSystem/FileInputStream.h"
#include "../IO/FileSystem/PathName.h"

#include "InternetMediaTypeRegistry.h"

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::DataExchange;
using namespace Stroika::Foundation::Execution;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

using FileSuffixType = InternetMediaTypeRegistry::FileSuffixType;

#if qPlatform_Windows
using Stroika::Foundation::Execution::Platform::Windows::ThrowIfNotERROR_SUCCESS;
#endif

#if qPlatform_Linux
// not sure what platforms have this
namespace {
    Mapping<FileSuffixType, InternetMediaType> GetGlobsFile_ ()
    {
        auto readGlobsFile = []() -> Mapping<FileSuffixType, InternetMediaType> {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
            Debug::TraceContextBumper ctx{L"{}readGlobsFile"};
#endif
            Mapping<FileSuffixType, InternetMediaType> results{};
            for (Sequence<String> line : DataExchange::Variant::CharacterDelimitedLines::Reader{{':'}}.ReadMatrix (IO::FileSystem::FileInputStream::New (L"/usr/share/mime/globs"))) {
                if (line.length () == 2) {
                    String glob = line[1];
                    if (glob.StartsWith ('*')) {
                        glob = glob.SubString (1);
                    }
                    results.Add (glob, InternetMediaType{line[0]});
                }
            }
#if USE_NOISY_TRACE_IN_THIS_MODULE_
            DbgTrace (L"returning %s", Characters::ToString (results).c_str ());
#endif
            return results;
        };
        static const Mapping<FileSuffixType, InternetMediaType> kData_ = readGlobsFile ();
        return kData_;
    }
}
#endif

#if qPlatform_Windows
namespace {
    // Based on code from HealthFrame. MAYBE someday do more generic version of this - as helper
    // @see https://stroika.atlassian.net/browse/STK-575
    struct OptionsFileHelper_ {
        OptionsFileHelper_ (HKEY hkey)
            : fKey (hkey)
        {
            Assert (nullptr != INVALID_HANDLE_VALUE);
            if (hkey == INVALID_HANDLE_VALUE or hkey == nullptr)
                [[UNLIKELY_ATTR]]
                {
                    Execution::Throw (SystemErrorException<> (ERROR_INVALID_HANDLE, system_category ()), "OptionsFileHelper::CTOR - bad handle");
                }
        }
        OptionsFileHelper_ (HKEY parentKey, const String& path, REGSAM samDesired = KEY_READ | KEY_WRITE)
            : fKey (OpenWithCreateAlongPath (parentKey, path, samDesired))
        {
            if (parentKey == INVALID_HANDLE_VALUE or parentKey == nullptr)
                [[UNLIKELY_ATTR]]
                {
                    Execution::Throw (SystemErrorException<> (ERROR_INVALID_HANDLE, system_category ()), "OptionsFileHelper::CTOR - bad handle");
                }
        }
        OptionsFileHelper_ ()                          = delete;
        OptionsFileHelper_ (const OptionsFileHelper_&) = delete;
        const OptionsFileHelper_& operator= (const OptionsFileHelper_&) const = delete;
        ~OptionsFileHelper_ ()
        {
            Assert (nullptr != INVALID_HANDLE_VALUE);
            Assert (fKey != nullptr);
            Assert (fKey != INVALID_HANDLE_VALUE);
            ::RegCloseKey (fKey);
        }
        /*
         * Walk the given path (in segments) - and make sure each exists, and create each segment if it doesn't
         * exist.Finally - do a regular registry open with access permissions 'samDesired'.< / p>
         */
        static HKEY OpenWithCreateAlongPath (HKEY parentKey, const String& path, REGSAM samDesired = KEY_READ | KEY_WRITE)
        {
#if USE_NOISY_TRACE_IN_THIS_MODULE_
            Debug::TraceContextBumper trcCtx{Stroika_Foundation_Debug_OptionalizeTraceArgs (L"{}::OptionsFileHelper_::OpenWithCreateAlongPath", L"parentKey=%p, path='%s'", parentKey, path.c_str ())};
#endif
            Require (parentKey != nullptr);
            size_t prevPos = 0;
            HKEY   curPar  = parentKey;
            for (;;) {
                size_t    endPos    = path.find ('\\', prevPos);
                SDKString segName   = path.AsSDKString ().substr (prevPos, endPos == SDKString::npos ? endPos : (endPos - prevPos));
                REGSAM    createSAM = (endPos == SDKString::npos) ? samDesired : KEY_READ;
                HKEY      newKey    = static_cast<HKEY> (INVALID_HANDLE_VALUE);

                ThrowIfNotERROR_SUCCESS (::RegCreateKeyEx (curPar, segName.c_str (), 0, REG_NONE, REG_OPTION_NON_VOLATILE, createSAM, nullptr, &newKey, nullptr));
                if (curPar != parentKey) {
                    ::RegCloseKey (curPar);
                }
{'fraction_non_alphanumeric': 0.11118527700963098, 'fraction_numerical': 0.0034328215886335464, 'mean_word_length': 2.6115702479338845, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2499999', 'n_tokens_mistral': 3070, 'n_tokens_neox': 2918, 'n_words': 665}