Skip to content

Instantly share code, notes, and snippets.

@Bambofy
Created April 21, 2019 10:25
Show Gist options
  • Save Bambofy/c9398b45b40afdad016740353d988bd9 to your computer and use it in GitHub Desktop.
Save Bambofy/c9398b45b40afdad016740353d988bd9 to your computer and use it in GitHub Desktop.
#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