Created
April 21, 2019 10:25
-
-
Save Bambofy/c9398b45b40afdad016740353d988bd9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <filesystem> | |
#define bits_in_int (sizeof(int) * 8) | |
#define bits_in_char (sizeof(char) * 8) | |
namespace fs = std::experimental::filesystem; | |
char* wchar_to_char(const wchar_t* pwchar) | |
{ | |
// get the number of characters in the string. | |
int currentCharIndex = 0; | |
char currentChar = pwchar[currentCharIndex]; | |
while (currentChar != '\0') | |
{ | |
currentCharIndex++; | |
currentChar = pwchar[currentCharIndex]; | |
} | |
const int charCount = currentCharIndex + 1; | |
// allocate a new block of memory size char (1 byte) instead of wide char (2 bytes) | |
char* filePathC = (char*)malloc(sizeof(char) * charCount); | |
for (int i = 0; i < charCount; i++) | |
{ | |
// convert to char (1 byte) | |
char character = pwchar[i]; | |
*filePathC = character; | |
filePathC += sizeof(char); | |
} | |
filePathC += '\0'; | |
filePathC -= (sizeof(char) * charCount); | |
return filePathC; | |
} | |
void wchar_to_char_free(char* pchar) | |
{ | |
free(pchar); | |
} | |
enum boolean | |
{ | |
TRUE = 1, | |
FALSE = 0, | |
ERROR = -1 | |
}; | |
bool iserror(boolean b) | |
{ | |
if (b == -1) return true; | |
return false; | |
} | |
boolean chars_end_with(char* pchars, const char* pcharext) | |
{ | |
int numberOfChars = strlen(pchars); | |
int numberOfExtChars = strlen(pcharext); | |
if (numberOfExtChars > numberOfChars) | |
{ | |
return boolean::ERROR; | |
} | |
// end of the memory block. | |
char* charsEnding = pchars + (sizeof(char) * numberOfChars); | |
// start of the extension. | |
char* extStart = charsEnding - (sizeof(char) * numberOfExtChars); | |
// are the extensions the same? | |
if (strcmp(extStart, pcharext) == 0) | |
{ | |
return boolean::TRUE; | |
} | |
return boolean::FALSE; | |
} | |
struct DirectoryInformation | |
{ | |
int* IndexMemoryBlock = nullptr; | |
char* FileNamesMemoryBlock = nullptr; | |
int NumberOfFiles = 0; | |
}; | |
DirectoryInformation Directory_ReadDirectory(char* pPath, const char* pExt) | |
{ | |
auto iter = fs::directory_iterator(pPath); | |
const char* extension = pExt; | |
long long numberOfFiles = 0; | |
// raw file names view. | |
char* fileNamesMemoryBlock = (char*)malloc(sizeof(char)); // expanding array of file names. | |
char* fileNamesMemoryBlock_HeadPtr = fileNamesMemoryBlock; // keep track of the end. | |
int* lookupMemoryBlock = (int*)malloc(sizeof(int)); | |
int* lookupMemoryBlock_HeadPtr = lookupMemoryBlock; | |
for (auto directoryEntry : iter) | |
{ | |
const wchar_t* filePathWChar = directoryEntry.path().c_str(); | |
char* filePath = wchar_to_char(filePathWChar); | |
// check that the filepath is a text file. | |
boolean endsWithTxt = chars_end_with(filePath, extension); | |
if (iserror(endsWithTxt)) | |
{ | |
printf("FILE NAME GIVEN IS SMALLER THAN `%s` EXTENSION", extension); | |
wchar_to_char_free(filePath); | |
continue; | |
} | |
else | |
{ | |
if (endsWithTxt) | |
{ | |
numberOfFiles++; | |
int numberOfCharactersInFilePath = strlen(filePath) + 1; // including the \0 null character at the end. | |
unsigned long sizeOfCharacterArray = numberOfCharactersInFilePath * sizeof(char); | |
////////////////////////////////////////////////////////////////// | |
// Add the filename character array to the global memory block. // | |
////////////////////////////////////////////////////////////////// | |
// current size of memory block? | |
unsigned long currentMemoryBlockLength = fileNamesMemoryBlock_HeadPtr - fileNamesMemoryBlock; // in bytes | |
// new size of array? | |
unsigned long newMemoryBlockLength = (currentMemoryBlockLength)+sizeOfCharacterArray; // to bytes | |
fileNamesMemoryBlock = (char*)realloc(fileNamesMemoryBlock, newMemoryBlockLength); // takes bytes | |
fileNamesMemoryBlock_HeadPtr = fileNamesMemoryBlock + newMemoryBlockLength; | |
char* currentFileNameBlockSpace = fileNamesMemoryBlock_HeadPtr - sizeOfCharacterArray; // bits | |
strcpy_s(currentFileNameBlockSpace, numberOfCharactersInFilePath, filePath); // strcpy converts bytes to bits automagically. | |
// pointer values are subtracted using !bits! | |
////////////////////////////////////////////////////////////////// | |
// Add the char** width (unsigned long) address to the offsets. // | |
////////////////////////////////////////////////////////////////// | |
unsigned long sizeOfEntry = sizeof(int); | |
unsigned long currentLookupLength = lookupMemoryBlock_HeadPtr - lookupMemoryBlock; // calculate current length of block | |
unsigned long newLookupLengthInBytes = (currentLookupLength * sizeof(int)) + sizeof(int); // calculate the new length with the new value added. | |
//printf("%i, %i, %i\n", sizeOfEntry, currentLookupLength, newLookupLength); | |
// expand the memory block to allocate the new address value. | |
lookupMemoryBlock = (int*)realloc(lookupMemoryBlock, newLookupLengthInBytes); | |
lookupMemoryBlock_HeadPtr = lookupMemoryBlock + (newLookupLengthInBytes / sizeof(int)); // POINTER = POINTER + 1 is the same as POINTER = POINTER + (bytes in POINTER TYPE) | |
/* | |
printf("Size of lookup block of memory: %i\n", lookupMemoryBlock_HeadPtr - lookupMemoryBlock);*/ | |
int* lookupAddressMemoryBlock = lookupMemoryBlock_HeadPtr - 1;/* | |
printf("%p Start\n", lookupMemoryBlock); | |
printf("%p End\n", lookupMemoryBlock_HeadPtr); | |
printf("%p Placing value At \n\n", lookupAddressMemoryBlock);*/ | |
*lookupAddressMemoryBlock = currentMemoryBlockLength; | |
} | |
} | |
wchar_to_char_free(filePath); | |
} | |
DirectoryInformation dir; | |
dir.FileNamesMemoryBlock = fileNamesMemoryBlock; | |
dir.IndexMemoryBlock = lookupMemoryBlock; | |
dir.NumberOfFiles = numberOfFiles; | |
return dir; | |
//// iterate through filename list (memory block). | |
//for (char* memPosition = fileNamesMemoryBlock; memPosition < fileNamesMemoryBlock_HeadPtr; memPosition++) | |
//{ | |
// char thisChar = *memPosition; | |
// if (thisChar == '\0') | |
// { | |
// printf("\n", thisChar); | |
// } | |
// else | |
// { | |
// printf("%c", thisChar); | |
// } | |
//} | |
//printf("\n\n\n"); | |
//// iterate through lookup memory block | |
//for (int* memPosition = lookupMemoryBlock; memPosition < lookupMemoryBlock_HeadPtr; memPosition++) | |
//{ | |
// int offset = *memPosition; | |
// printf("%ld\n", offset); | |
//} | |
} | |
char* Directory_GetFileName(DirectoryInformation pDir, int pIndex) | |
{ | |
// use the lookup memory block to browse the file list block. | |
int index = pIndex; | |
int* lookupMemoryPosition = pDir.IndexMemoryBlock + (index); | |
int offset = *lookupMemoryPosition; | |
char* filenameMemoryPosition = pDir.FileNamesMemoryBlock + offset; | |
return filenameMemoryPosition; | |
} | |
void Directory_Free(DirectoryInformation pDir) | |
{ | |
free(pDir.FileNamesMemoryBlock); | |
free(pDir.IndexMemoryBlock); | |
} | |
int main() | |
{ | |
char* directoryName = wchar_to_char(fs::current_path().c_str()); | |
DirectoryInformation currentDirectory = Directory_ReadDirectory(directoryName, "txt"); | |
char* firstFileName = Directory_GetFileName(currentDirectory, 0); | |
printf("FileName at Index 0 = %s\n", firstFileName); | |
firstFileName = Directory_GetFileName(currentDirectory, 1); | |
printf("FileName at Index 1 = %s\n", firstFileName); | |
firstFileName = Directory_GetFileName(currentDirectory, 2); | |
printf("FileName at Index 2 = %s\n", firstFileName); | |
Directory_Free(currentDirectory); | |
free(directoryName); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment