<commit_before>//Copyright 2015 <NAME>
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

// Contact :
// Email             : <EMAIL>
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

/*!
	\file FileWindows.inl
	\brief
	\author
	Created			: <NAME>
	Last modified	: <NAME>
	\version 1.0
	\date
	Created			: 20th November 2015
	Last Modified	: 15th January 2016
*/

namespace Solaire { namespace File {

    namespace Implementation {

        const char* const makeCString(const StringConstant& aString, char* aPath) {
            const int32_t size = aString.size();
            aPath[size] = '\0';
            if(aString.isContiguous()) {
                std::memcpy(aPath, &aString[0], size);
            }else {
                for(int32_t i = 0; i < size; ++i) aPath[i] = aString[i];
            }
            return aPath;
        }

         bool openFile(const StringConstant& aFilename, HANDLE& aHandle, const int32_t aFlags) {
            char filename[MAX_PATH_LENGTH + 1];
            Implementation::makeCString(aFilename, filename);
            const HANDLE handle = CreateFileA(
                filename,
                aFlags,
                0,
                nullptr,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                nullptr
            );

            return handle != INVALID_HANDLE_VALUE;
        }

         bool openRFile(const StringConstant& aFilename, HANDLE& aHandle) {
            return openFile(aFilename, aHandle, GENERIC_READ);
        }

         bool openWFile(const StringConstant& aFilename, HANDLE& aHandle) {
            return openFile(aFilename, aHandle, GENERIC_WRITE);
        }

         bool openRWFile(const StringConstant& aFilename, HANDLE& aHandle) {
            return openFile(aFilename, aHandle, GENERIC_READ | GENERIC_WRITE);
        }

        bool closeFile(HANDLE& aHandle) {
            return CloseHandle(aHandle);
        }
    }

    AttributeFlags SOLAIRE_EXPORT_CALL getAttributes(const StringConstant& aFilename) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        const char* const filename = Implementation::makeCString(aFilename, buffer);

        const DWORD attributes = GetFileAttributesA(filename);
        DWORD binaryType;
        const BOOL executable = GetBinaryTypeA(filename, &binaryType);

        AttributeFlags tmp = FLAG_NONE;
        if(attributes & FILE_ATTRIBUTE_HIDDEN) tmp |= FLAG_HIDDEN;
        if(attributes & FILE_ATTRIBUTE_DIRECTORY) tmp |= FLAG_DIRECTORY;
        else tmp |= FLAG_FILE;
        if(attributes & FILE_ATTRIBUTE_READONLY) tmp |= FLAG_READ;
        else tmp |= FLAG_READ | FLAG_WRITE;
        if(executable) tmp |= FLAG_EXECUTABLE;
        if(tmp != FLAG_NONE) tmp |= FLAG_EXISTS;

        return tmp;
    }

    bool SOLAIRE_EXPORT_CALL createFile(const StringConstant& aFilename, const AttributeFlags aAttributes) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        const char* const filename = Implementation::makeCString(aFilename, buffer);

        DWORD access = 0;
        if (aAttributes & FLAG_READ) access |= GENERIC_READ;
        if (aAttributes & FLAG_WRITE) access |= GENERIC_WRITE;

        DWORD flags = 0;
        if (aAttributes & FLAG_HIDDEN) flags |= FILE_ATTRIBUTE_HIDDEN;
        if ((aAttributes & FLAG_READ) != 0 && (aAttributes & FLAG_WRITE) == 0) flags |= FILE_ATTRIBUTE_READONLY;
        if (flags == 0) flags = FILE_ATTRIBUTE_NORMAL;

        const HANDLE handle = CreateFileA(
            filename,
            access,
            0,
            nullptr,
            CREATE_NEW,
            flags,
            nullptr
        );

        if(handle != INVALID_HANDLE_VALUE) {
            CloseHandle(handle);
            return true;
        }else {
            return false;
        }
    }

    bool SOLAIRE_EXPORT_CALL createDirectory(const StringConstant& aFilename) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        return CreateDirectoryA(Implementation::makeCString(aFilename, buffer), nullptr) > 0;
    }

    bool SOLAIRE_EXPORT_CALL deleteFile(const StringConstant& aFilename) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        return DeleteFileA(Implementation::makeCString(aFilename, buffer)) > 0;
    }

    bool SOLAIRE_EXPORT_CALL deleteDirectory(const StringConstant& aFilename) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        return DeleteFileA(Implementation::makeCString(aFilename, buffer)) > 0;
    }

    STLString SOLAIRE_EXPORT_CALL getParent(const StringConstant& aFilename) throw() {
        const int32_t length = aFilename.size();
        const int32_t seperator = aFilename.findLastOf(FILE_SEPERATOR);

        STLString path;
        if(seperator != length) for(int32_t i = 0; i <= seperator; ++i) path.pushBack(aFilename[i]);
        return path;
    }

    STLString SOLAIRE_EXPORT_CALL getName(const StringConstant& aFilename) throw() {
        const int32_t length = aFilename.size();
        const int32_t seperator = aFilename.findLastOf(FILE_SEPERATOR);
        const int32_t end = aFilename.findLastOf('.');

        if(seperator == length) {
            return STLString();
        } else {
            STLString tmp;
            for(int32_t i = seperator + 1; i < end; ++i) tmp.pushBack(aFilename[i]);
            return tmp;
        }
    }

    STLString SOLAIRE_EXPORT_CALL getExtension(const StringConstant& aFilename) throw() {
        const int32_t length = aFilename.size();
        const int32_t seperator = aFilename.findLastOf('.');

        if(seperator == length) {
            return STLString();
        } else {
            STLString tmp;
            for(int32_t i = 0; i <= seperator; ++i) tmp.pushBack(aFilename[i]);
            return tmp;
        }
    }

    int32_t SOLAIRE_EXPORT_CALL size(const StringConstant& aFilename) throw() {
        HANDLE handle;
        if(! Implementation::openRFile(aFilename, handle)) return 0;
        const int32_t size = GetFileSize(handle, nullptr);
        Implementation::closeFile(handle);
        return size;
    }

    bool SOLAIRE_EXPORT_CALL getFileList(const StringConstant& aDirectory, Stack<STLString>& aFiles) throw() {
        WIN32_FIND_DATAA findData;
        HANDLE handle = INVALID_HANDLE_VALUE;

        char directory[MAX_PATH_LENGTH + 1];<commit_msg>Fixed spacing<commit_after>//Copyright 2015 <NAME>
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.

// Contact :
// Email             : <EMAIL>
// GitHub repository : https://github.com/SolaireLibrary/SolaireCPP

/*!
	\file FileWindows.inl
	\brief
	\author
	Created			: <NAME>
	Last modified	: <NAME>
	\version 1.0
	\date
	Created			: 20th November 2015
	Last Modified	: 15th January 2016
*/

namespace Solaire { namespace File {

    namespace Implementation {

        const char* const makeCString(const StringConstant& aString, char* aPath) {
            const int32_t size = aString.size();
            aPath[size] = '\0';
            if(aString.isContiguous()) {
                std::memcpy(aPath, &aString[0], size);
            }else {
                for(int32_t i = 0; i < size; ++i) aPath[i] = aString[i];
            }
            return aPath;
        }

         bool openFile(const StringConstant& aFilename, HANDLE& aHandle, const int32_t aFlags) {
            char filename[MAX_PATH_LENGTH + 1];
            Implementation::makeCString(aFilename, filename);
            const HANDLE handle = CreateFileA(
                filename,
                aFlags,
                0,
                nullptr,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                nullptr
            );

            return handle != INVALID_HANDLE_VALUE;
        }

         bool openRFile(const StringConstant& aFilename, HANDLE& aHandle) {
            return openFile(aFilename, aHandle, GENERIC_READ);
        }

         bool openWFile(const StringConstant& aFilename, HANDLE& aHandle) {
            return openFile(aFilename, aHandle, GENERIC_WRITE);
        }

         bool openRWFile(const StringConstant& aFilename, HANDLE& aHandle) {
            return openFile(aFilename, aHandle, GENERIC_READ | GENERIC_WRITE);
        }

        bool closeFile(HANDLE& aHandle) {
            return CloseHandle(aHandle);
        }
    }

    AttributeFlags SOLAIRE_EXPORT_CALL getAttributes(const StringConstant& aFilename) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        const char* const filename = Implementation::makeCString(aFilename, buffer);

        const DWORD attributes = GetFileAttributesA(filename);
        DWORD binaryType;
        const BOOL executable = GetBinaryTypeA(filename, &binaryType);

        AttributeFlags tmp = FLAG_NONE;
        if(attributes & FILE_ATTRIBUTE_HIDDEN) tmp |= FLAG_HIDDEN;
        if(attributes & FILE_ATTRIBUTE_DIRECTORY) tmp |= FLAG_DIRECTORY;
        else tmp |= FLAG_FILE;
        if(attributes & FILE_ATTRIBUTE_READONLY) tmp |= FLAG_READ;
        else tmp |= FLAG_READ | FLAG_WRITE;
        if(executable) tmp |= FLAG_EXECUTABLE;
        if(tmp != FLAG_NONE) tmp |= FLAG_EXISTS;

        return tmp;
    }

    bool SOLAIRE_EXPORT_CALL createFile(const StringConstant& aFilename, const AttributeFlags aAttributes) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        const char* const filename = Implementation::makeCString(aFilename, buffer);

        DWORD access = 0;
        if(aAttributes & FLAG_READ) access |= GENERIC_READ;
        if(aAttributes & FLAG_WRITE) access |= GENERIC_WRITE;

        DWORD flags = 0;
        if(aAttributes & FLAG_HIDDEN) flags |= FILE_ATTRIBUTE_HIDDEN;
        if((aAttributes & FLAG_READ) != 0 && (aAttributes & FLAG_WRITE) == 0) flags |= FILE_ATTRIBUTE_READONLY;
        if(flags == 0) flags = FILE_ATTRIBUTE_NORMAL;

        const HANDLE handle = CreateFileA(
            filename,
            access,
            0,
            nullptr,
            CREATE_NEW,
            flags,
            nullptr
        );

        if(handle != INVALID_HANDLE_VALUE) {
            CloseHandle(handle);
            return true;
        }else {
            return false;
        }
    }

    bool SOLAIRE_EXPORT_CALL createDirectory(const StringConstant& aFilename) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        return CreateDirectoryA(Implementation::makeCString(aFilename, buffer), nullptr) > 0;
    }

    bool SOLAIRE_EXPORT_CALL deleteFile(const StringConstant& aFilename) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        return DeleteFileA(Implementation::makeCString(aFilename, buffer)) > 0;
    }

    bool SOLAIRE_EXPORT_CALL deleteDirectory(const StringConstant& aFilename) throw() {
        char buffer[MAX_PATH_LENGTH + 1];
        return DeleteFileA(Implementation::makeCString(aFilename, buffer)) > 0;
    }

    STLString SOLAIRE_EXPORT_CALL getParent(const StringConstant& aFilename) throw() {
        const int32_t length = aFilename.size();
        const int32_t seperator = aFilename.findLastOf(FILE_SEPERATOR);

        STLString path;
        if(seperator != length) for(int32_t i = 0; i <= seperator; ++i) path.pushBack(aFilename[i]);
        return path;
    }

    STLString SOLAIRE_EXPORT_CALL getName(const StringConstant& aFilename) throw() {
        const int32_t length = aFilename.size();
        const int32_t seperator = aFilename.findLastOf(FILE_SEPERATOR);
        const int32_t end = aFilename.findLastOf('.');

        if(seperator == length) {
            return STLString();
        }else {
            STLString tmp;
            for(int32_t i = seperator + 1; i < end; ++i) tmp.pushBack(aFilename[i]);
            return tmp;
        }
    }

    STLString SOLAIRE_EXPORT_CALL getExtension(const StringConstant& aFilename) throw() {
        const int32_t length = aFilename.size();
        const int32_t seperator = aFilename.findLastOf('.');

        if(seperator == length) {
            return STLString();
        }else {
            STLString tmp;
            for(int32_t i = 0; i <= seperator; ++i) tmp.pushBack(aFilename[i]);
            return tmp;
        }
    }

    int32_t SOLAIRE_EXPORT_CALL size(const StringConstant& aFilename) throw() {
        HANDLE handle;
        if(! Implementation::openRFile(aFilename, handle)) return 0;
        const int32_t size = GetFileSize(handle, nullptr);
        Implementation::closeFile(handle);
        return size;
    }

    bool SOLAIRE_EXPORT_CALL getFileList(const StringConstant& aDirectory, Stack<STLString>& aFiles) throw() {
        WIN32_FIND_DATAA findData;
        HANDLE handle = INVALID_HANDLE_VALUE;

        char directory[MAX_PATH_LENGTH + 1];
{'fraction_non_alphanumeric': 0.09257487673853852, 'fraction_numerical': 0.011479873427036574, 'mean_word_length': 2.464185572266123, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 19, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, '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': '111357', 'n_tokens_mistral': 4157, 'n_tokens_neox': 3855, 'n_words': 1005}