#include <iostream>
#include <windows.h>
#include <string.h>
#include <strsafe.h>

#define MAX_INPUT_LENGTH 255

using namespace std;

void printMemory(char* location, long size)
{

	printf("\n\n---------------------location:%p------------------------\n\n", location);

	for (long var = 0; var < size; var++)
	{
		printf("[%x] ", *(unsigned char*)(location++));
	}

	printf("\n\n---------------------over:%p----------------------------\n\n", location);

}

long readFile(const char* path, char** fp)
{
	FILE* f = NULL;
	errno_t err;
	if ((err = fopen_s(&f, path, "rb")) != 0 || f == 0)
	{
		printf("file open error!!\n");
		return 0;
	}

	fseek(f, 0L, SEEK_END);
	long length = ftell(f);
	fseek(f, 0L, SEEK_SET);

	*fp = (char*)malloc(length);

	if (fp == NULL)
	{
		printf("memory error!!");
		return 0;
	}

	fread(*fp, sizeof(char), length, f);

	fclose(f);
	return length;
}


template <class T>
unsigned int stringLen(const T* s)
{
	unsigned int count = 0;
	T text = *(T*)s;
	while (text != '\0')
	{
		text = *(T*)(s += 1);
		count++;
	}
	return count;
}

template <class T>
int endsWith(const T* str, const T* tail) {
	int offset = stringLen(str);
	for (int i = 0, len = stringLen(tail); i < len; i++)
		if (str[offset - len + i] != tail[i])return -1;
	return 1;
}

class queryAnalyser
{
public:
	queryAnalyser();
	~queryAnalyser();
	void setkeyword(char* keyword);
	void setFileType(char* fileType);
	void fileIterator(char* dir);
	void test();

private:
	void analyse();
	long getCodepoint(char keyword);
	void setFilePath(char* path);
	void release();

	const char* filePath = NULL;
	char* fpointer = NULL;
	long fileLength = 0, keywordLength = 0;
	char* keyword = NULL;
	char* fileType = NULL;
};

queryAnalyser::queryAnalyser() {}

void queryAnalyser::release() {
	free(this->fpointer);
	fpointer = NULL;
}

void queryAnalyser::test() {
	cout << "test";
}

void queryAnalyser::setkeyword(char* keyword) {
	this->keywordLength = strlen(keyword) - 2;
	this->keyword = new char[keywordLength+1];

	for (int i = 0; i <= keywordLength - 1; i++)
		this->keyword[i] = this->getCodepoint(keyword[i]);
	this->keyword[keywordLength] = '\0';
}

void queryAnalyser::setFileType(char* fileType) {
	int len = strlen(fileType);
	this->fileType = (char*)malloc(len);
	if (this->fileType == NULL) {
		cout << "cannot allocate new memory";
		exit(0);
	}
	//strcpy_s(this->fileType, len, (const char*) fileType);
	memcpy(this->fileType, fileType, len - 2);
	memcpy((char*)(this->fileType + len - 2), "\0\0", 2);
}
void queryAnalyser::setFilePath(char* path) {
	this->filePath = path;
	this->fileLength = readFile(path, &this->fpointer);
}
long queryAnalyser::getCodepoint(char keyword) {
	char utf8[5];
	int len = WideCharToMultiByte(CP_UTF8, 0, (WCHAR*)&keyword, 1, utf8, 5, NULL, NULL);
	utf8[len] = '\0';
	unsigned char* p = (unsigned char*)utf8;
	long codepoint = 0;
	if (*p <= 0x7F) {
		codepoint = *p;
	}
	else if (*p <= 0xDF) {
		codepoint = (*p & 0x1F) << 6;
		p++;
		codepoint |= (*p & 0x3F);
	}
	else if (*p <= 0xEF) {
		codepoint = (*p & 0x0F) << 12;
		p++;
		codepoint |= (*p & 0x3F) << 6;
		p++;
		codepoint |= (*p & 0x3F);
	}
	else {
		codepoint = (*p & 0x07) << 18;
		p++;
		codepoint |= (*p & 0x3F) << 12;
		p++;
		codepoint |= (*p & 0x3F) << 6;
		p++;
		codepoint |= (*p & 0x3F);
	}
	return codepoint;
}

void queryAnalyser::analyse() {
	char* pointer = (char*)this->fpointer;
	for (long var = 0, len = this->fileLength - this->keywordLength; var < len; var++)
	{
		for (int i = 0; i < this->keywordLength; i++)
		{
			char cur = *(unsigned char*)(pointer + i);
			if (cur != this->keyword[i] )//&& cur != '\0'
				break;
			if (i == this->keywordLength - 1)
			{
				cout << "---> ";
				cout << this->filePath;
				cout << "\n";
				goto outer;
			}
		}
		pointer++;
	}
outer:
	pointer = NULL;
}

void queryAnalyser::fileIterator(char* dir) {
	char path[MAX_PATH];
	WIN32_FIND_DATAA  FindFileData;

	strcpy_s(path, MAX_PATH, dir);
	if (endsWith(path, "\\") != 1)
		strcat_s(path, MAX_PATH, "\\");
	strcat_s(path, MAX_PATH, "*");

	HANDLE hFind = FindFirstFileA(path, &FindFileData);
	do
	{
		if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			if (*FindFileData.cFileName == '.')continue;
			char subPath[MAX_PATH];
			strcpy_s(subPath, MAX_PATH, dir);
			if (endsWith(subPath, "\\") == -1)
				strcat_s(subPath, MAX_PATH, "\\");
			strcat_s(subPath, MAX_PATH, FindFileData.cFileName);

			fileIterator(subPath);
		}
		else
		{
			char subPath[MAX_PATH];
			strcpy_s(subPath, MAX_PATH, dir);
			if (endsWith(subPath, "\\") == -1)
				strcat_s(subPath, MAX_PATH, "\\");
			strcat_s(subPath, MAX_PATH, FindFileData.cFileName);

			if (endsWith(FindFileData.cFileName, this->fileType) == 1) {
				this->setFilePath(subPath);
				this->analyse();
			}
		}
	} while (FindNextFileA(hFind, &FindFileData) != 0);
}



queryAnalyser::~queryAnalyser()
{
	free(this->fileType);
	printf("search over");
}

char* getInputFromConsole() {
	SetConsoleOutputCP(CP_UTF8);
	SetConsoleCP(CP_UTF8);

	wchar_t wstr[MAX_INPUT_LENGTH];
	char mb_str[MAX_INPUT_LENGTH * 3 + 1];

	unsigned long read;
	void* con = GetStdHandle(STD_INPUT_HANDLE);

	ReadConsole(con, wstr, MAX_INPUT_LENGTH, &read, NULL);

	int size = WideCharToMultiByte(CP_UTF8, 0, wstr, read, mb_str, sizeof(mb_str), NULL, NULL);
	mb_str[size] = 0;

	return mb_str;
}

int main()
{
	queryAnalyser* inst = new queryAnalyser();
	while (true) {
		cout << "please enter search keyword: \n";
		char* keyword = getInputFromConsole();
		inst->setkeyword(keyword);
		cout << "please enter file affix for example: (.txt) : \n";
		char* fileType = getInputFromConsole();
		inst->setFileType(fileType);
		printMemory((char*)keyword, strlen(fileType)-2);
		inst->fileIterator((char*)".\\");
	}

	delete inst;


	return 0;
}


 posted on 2023-04-25 18:00  laremehpe  阅读(31)  评论(0编辑  收藏  举报