<commit_before>#include "native_handler.h"
#include "include/cef_base.h"
#include "client_handler.h"
#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <vector>
#include <gtk/gtk.h>

using namespace std;

NativeHandler::NativeHandler() :
		CefV8Handler() {
	object = CefV8Value::CreateObject(NULL, NULL);

	const char *functionNames[] = { "exists", "alert", "read", "write",
			"absolute", "list", "isFile", "isDirectory", "remove", "asyncList",
			"open", "openDialog", "quit", "writeToPasteboard",
			"readFromPasteboard", "showDevTools", "newWindow", "saveDialog",
			"exit", "watchPath", "unwatchPath", "makeDirectory", "move",
			"moveToTrash" };
	int arrayLength = sizeof(functionNames) / sizeof(const char *);
	for (int i = 0; i < arrayLength; i++) {
		const char *functionName = functionNames[i];
		CefRefPtr<CefV8Value> function = CefV8Value::CreateFunction(
				functionName, this);
		object->SetValue(functionName, function, V8_PROPERTY_ATTRIBUTE_NONE);
	}
}

void NativeHandler::Exists(const CefString& name, CefRefPtr<CefV8Value> object,
		const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval,
		CefString& exception) {
	string path = arguments[0]->GetStringValue().ToString();
	struct stat sbuf;
	int result = stat(path.c_str(), &sbuf);
	retval = CefV8Value::CreateBool(result == 0);
}

void NativeHandler::Read(const CefString& name, CefRefPtr<CefV8Value> object,
		const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval,
		CefString& exception) {
	string path = arguments[0]->GetStringValue().ToString();
	int fd = open(path.c_str(), O_RDONLY);
	if (fd < 0)
		return;

	char buffer[8192];
	int r;
	string value;
	while ((r = read(fd, buffer, sizeof buffer)) > 0)
		value.append(buffer, 0, r);
	close(fd);
	retval = CefV8Value::CreateString(value);
}

void NativeHandler::Absolute(const CefString& name,
		CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments,
		CefRefPtr<CefV8Value>& retval, CefString& exception) {
	string path = arguments[0]->GetStringValue().ToString();
	if (path[0] == '~') {
		string resolved = getenv("HOME");
		resolved.append(path.substr(1));
		retval = CefV8Value::CreateString(resolved);
	} else
		retval = CefV8Value::CreateString(path);<commit_msg>Fully support resolving absolute paths<commit_after>#include "native_handler.h"
#include "include/cef_base.h"
#include "client_handler.h"
#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <vector>
#include <gtk/gtk.h>

using namespace std;

NativeHandler::NativeHandler() :
		CefV8Handler() {
	object = CefV8Value::CreateObject(NULL, NULL);

	const char *functionNames[] = { "exists", "alert", "read", "write",
			"absolute", "list", "isFile", "isDirectory", "remove", "asyncList",
			"open", "openDialog", "quit", "writeToPasteboard",
			"readFromPasteboard", "showDevTools", "newWindow", "saveDialog",
			"exit", "watchPath", "unwatchPath", "makeDirectory", "move",
			"moveToTrash" };
	int arrayLength = sizeof(functionNames) / sizeof(const char *);
	for (int i = 0; i < arrayLength; i++) {
		const char *functionName = functionNames[i];
		CefRefPtr<CefV8Value> function = CefV8Value::CreateFunction(
				functionName, this);
		object->SetValue(functionName, function, V8_PROPERTY_ATTRIBUTE_NONE);
	}
}

void NativeHandler::Exists(const CefString& name, CefRefPtr<CefV8Value> object,
		const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval,
		CefString& exception) {
	string path = arguments[0]->GetStringValue().ToString();
	struct stat sbuf;
	int result = stat(path.c_str(), &sbuf);
	retval = CefV8Value::CreateBool(result == 0);
}

void NativeHandler::Read(const CefString& name, CefRefPtr<CefV8Value> object,
		const CefV8ValueList& arguments, CefRefPtr<CefV8Value>& retval,
		CefString& exception) {
	string path = arguments[0]->GetStringValue().ToString();
	int fd = open(path.c_str(), O_RDONLY);
	if (fd < 0)
		return;

	char buffer[8192];
	int r;
	string value;
	while ((r = read(fd, buffer, sizeof buffer)) > 0)
		value.append(buffer, 0, r);
	close(fd);
	retval = CefV8Value::CreateString(value);
}

void NativeHandler::Absolute(const CefString& name,
		CefRefPtr<CefV8Value> object, const CefV8ValueList& arguments,
		CefRefPtr<CefV8Value>& retval, CefString& exception) {
	string path = arguments[0]->GetStringValue().ToString();
	string relativePath;
	if (path[0] != '~')
		relativePath.append(path);
	else {
		relativePath.append(getenv("HOME"));
		relativePath.append(path, 1, path.length() - 1);
	}

	vector < string > segments;
	char allSegments[path.length() + 1];
	strcpy(allSegments, path.c_str());
	const char* segment;
	for (segment = strtok(allSegments, "/"); segment;
			segment = strtok(NULL, "/")) {
		if (strcmp(segment, ".") == 0)
			continue;
		if (strcmp(segment, "..") == 0) {
			if (segments.empty()) {
				retval = CefV8Value::CreateString("/");
				return;
			} else {
				segments.pop_back();
				continue;
			}
		}
		segments.push_back(segment);
	}

	string absolutePath;
	unsigned int i;
	for (i = 0; i < segments.size(); i++) {
		absolutePath.append("/");
		absolutePath.append(segments.at(i));
	}
	retval = CefV8Value::CreateString(absolutePath);
{'fraction_non_alphanumeric': 0.16197051688747902, 'fraction_numerical': 0.012875536480686695, 'mean_word_length': 5.6916354556804, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 48, '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': '3600660', 'n_tokens_mistral': 2024, 'n_tokens_neox': 1918, 'n_words': 413}