<commit_before>/*
 * Copyright 2015 - 2017 <EMAIL>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
#pragma once

#include <ox/std/std.hpp>
#include "pathiterator.hpp"
#include "filestore.hpp"

namespace ox {

enum FsType {
	OxFS_16 = 1,
	OxFS_32 = 2,
	OxFS_64 = 3
};

enum FileType {
	FileType_NormalFile = 1,
	FileType_Directory  = 2
};

struct FileStat {
	uint64_t inode;
	uint64_t size;
	uint8_t  fileType;
};

template<typename String>
struct DirectoryListing {
	String name;
	FileStat stat;

	DirectoryListing(const char *name) {
		this->name = name;
	}
};

template<typename InodeId_t>
struct __attribute__((packed)) DirectoryEntry {
	InodeId_t inode;

	char *getName() {
		return (char*) (this + 1);
	}

	void setName(const char *name) {
		auto data = getName();
		auto nameLen = ox_strlen(name);
		ox_memcpy(data, name, nameLen);
		data[nameLen] = 0;
	}

	static uint64_t spaceNeeded(const char *fileName) {
		return sizeof(DirectoryEntry) + ox_strlen(fileName) + 1;
	}

	/**
	 * The size in bytes.
	 */
	uint64_t size() {
		return spaceNeeded(getName());
	}
};

template<typename InodeId_t, typename FsSize_t>
struct __attribute__((packed)) Directory {
	/**
	 * Number of bytes after this Directory struct.
	 */
	FsSize_t size = 0;
	FsSize_t children = 0;

	DirectoryEntry<InodeId_t> *files() {
		return size ? (DirectoryEntry<InodeId_t>*) (this + 1) : nullptr;
	}

	uint64_t getFileInode(const char *name, uint64_t buffSize);

	int getChildrenInodes(InodeId_t *inodes, size_t inodesLen);

	int rmFile(const char *name);

	int copy(Directory<uint64_t, uint64_t> *dirOut);

	template<typename List>
	int ls(List *list);
};

template<typename InodeId_t, typename FsSize_t>
uint64_t Directory<InodeId_t, FsSize_t>::getFileInode(const char *name, uint64_t buffSize) {
	uint64_t inode = 0;
	auto current = files();
	if (current) {
		for (uint64_t i = 0; ox_strcmp(current->getName(), name) != 0;) {
			i += current->size();
			if (i < this->size) {
				current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
			} else {
				current = nullptr;
				break;
			}
		}
		if (current) {
			inode = current->inode;
		}
	}
	return inode;
}

template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::getChildrenInodes(InodeId_t *inodes, size_t inodesLen) {
	if (inodesLen >= this->children) {
		auto current = files();
		if (current) {
			for (uint64_t i = 0; i < this->children; i++) {
				inodes[i] = current->inode;
				current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
			}
			return 0;
		} else {
			return 1;
		}
	} else {
		return 2;
	}
}

template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::rmFile(const char *name) {
	int err = 1;
	auto current = files();
	if (current) {
		for (uint64_t i = 0; i < this->size;) {
			i += current->size();
			if (ox_strcmp(current->getName(), name) == 0) {
				auto dest = (uint8_t*) current;
				auto src = dest + current->size();
				ox_memcpy(dest, src, this->size - i);
				this->size -= current->size();
				this->children--;
				err = 0;
				break;
			}
			current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
		}
	}
	return err;
}

template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::copy(Directory<uint64_t, uint64_t> *dirOut) {
	auto current = files();
	auto dirBuff = (uint8_t*) dirOut;
	dirBuff += sizeof(Directory<uint64_t, uint64_t>);
	dirOut->size = this->size;
	dirOut->children = this->children;
	if (current) {
		for (uint64_t i = 0; i < this->children; i++) {
			auto entry = (DirectoryEntry<uint64_t>*) dirBuff;
			entry->inode = current->inode;
			entry->setName(current->getName());

			current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
			dirBuff += entry->size();
		}
		return 0;
	} else {
		return 1;
	}
}

template<typename InodeId_t, typename FsSize_t>
template<typename List>
int Directory<InodeId_t, FsSize_t>::ls(List *list) {
	auto current = files();
	if (current) {
		for (uint64_t i = 0; i < this->children; i++) {
			list->push_back(current->getName());
			list->at(i).stat.inode = current->inode;
			current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
		}
		return 0;
	} else {
		return 1;
	}<commit_msg>Add default constructor for DirectoryListing<commit_after>/*
 * Copyright 2015 - 2017 <EMAIL>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
#pragma once

#include <ox/std/std.hpp>
#include "pathiterator.hpp"
#include "filestore.hpp"

namespace ox {

enum FsType {
	OxFS_16 = 1,
	OxFS_32 = 2,
	OxFS_64 = 3
};

enum FileType {
	FileType_NormalFile = 1,
	FileType_Directory  = 2
};

struct FileStat {
	uint64_t inode;
	uint64_t size;
	uint8_t  fileType;
};

template<typename String>
struct DirectoryListing {
	String name;
	FileStat stat;

	DirectoryListing() = default;

	DirectoryListing(const char *name) {
		this->name = name;
	}
};

template<typename InodeId_t>
struct __attribute__((packed)) DirectoryEntry {
	InodeId_t inode;

	char *getName() {
		return (char*) (this + 1);
	}

	void setName(const char *name) {
		auto data = getName();
		auto nameLen = ox_strlen(name);
		ox_memcpy(data, name, nameLen);
		data[nameLen] = 0;
	}

	static uint64_t spaceNeeded(const char *fileName) {
		return sizeof(DirectoryEntry) + ox_strlen(fileName) + 1;
	}

	/**
	 * The size in bytes.
	 */
	uint64_t size() {
		return spaceNeeded(getName());
	}
};

template<typename InodeId_t, typename FsSize_t>
struct __attribute__((packed)) Directory {
	/**
	 * Number of bytes after this Directory struct.
	 */
	FsSize_t size = 0;
	FsSize_t children = 0;

	DirectoryEntry<InodeId_t> *files() {
		return size ? (DirectoryEntry<InodeId_t>*) (this + 1) : nullptr;
	}

	uint64_t getFileInode(const char *name, uint64_t buffSize);

	int getChildrenInodes(InodeId_t *inodes, size_t inodesLen);

	int rmFile(const char *name);

	int copy(Directory<uint64_t, uint64_t> *dirOut);

	template<typename List>
	int ls(List *list);
};

template<typename InodeId_t, typename FsSize_t>
uint64_t Directory<InodeId_t, FsSize_t>::getFileInode(const char *name, uint64_t buffSize) {
	uint64_t inode = 0;
	auto current = files();
	if (current) {
		for (uint64_t i = 0; ox_strcmp(current->getName(), name) != 0;) {
			i += current->size();
			if (i < this->size) {
				current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
			} else {
				current = nullptr;
				break;
			}
		}
		if (current) {
			inode = current->inode;
		}
	}
	return inode;
}

template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::getChildrenInodes(InodeId_t *inodes, size_t inodesLen) {
	if (inodesLen >= this->children) {
		auto current = files();
		if (current) {
			for (uint64_t i = 0; i < this->children; i++) {
				inodes[i] = current->inode;
				current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
			}
			return 0;
		} else {
			return 1;
		}
	} else {
		return 2;
	}
}

template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::rmFile(const char *name) {
	int err = 1;
	auto current = files();
	if (current) {
		for (uint64_t i = 0; i < this->size;) {
			i += current->size();
			if (ox_strcmp(current->getName(), name) == 0) {
				auto dest = (uint8_t*) current;
				auto src = dest + current->size();
				ox_memcpy(dest, src, this->size - i);
				this->size -= current->size();
				this->children--;
				err = 0;
				break;
			}
			current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
		}
	}
	return err;
}

template<typename InodeId_t, typename FsSize_t>
int Directory<InodeId_t, FsSize_t>::copy(Directory<uint64_t, uint64_t> *dirOut) {
	auto current = files();
	auto dirBuff = (uint8_t*) dirOut;
	dirBuff += sizeof(Directory<uint64_t, uint64_t>);
	dirOut->size = this->size;
	dirOut->children = this->children;
	if (current) {
		for (uint64_t i = 0; i < this->children; i++) {
			auto entry = (DirectoryEntry<uint64_t>*) dirBuff;
			entry->inode = current->inode;
			entry->setName(current->getName());

			current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
			dirBuff += entry->size();
		}
		return 0;
	} else {
		return 1;
	}
}

template<typename InodeId_t, typename FsSize_t>
template<typename List>
int Directory<InodeId_t, FsSize_t>::ls(List *list) {
	auto current = files();
	if (current) {
		for (uint64_t i = 0; i < this->children; i++) {
			list->push_back(current->getName());
			(*list)[i].stat.inode = current->inode;
			current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
		}
		return 0;
	} else {
		return 1;
	}
{'fraction_non_alphanumeric': 0.15141079760053322, 'fraction_numerical': 0.021328593645856476, 'mean_word_length': 4.032420346562326, 'pattern_counts': {'":': 0, '<': 69, '<?xml version=': 0, '>': 132, 'https://': 0, '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': '3691250', 'n_tokens_mistral': 3745, 'n_tokens_neox': 3335, 'n_words': 820}