/*
	Copyright 2003 by Marc J. Rochkind. All rights reserved.
	May be copied only for purposes and under conditions described
	on the Web page www.basepath.com/aup/copyright.htm.

	The Example Files are provided "as is," without any warranty;
	without even the implied warranty of merchantability or fitness
	for a particular purpose. The author and his publisher are not
	responsible for any damages, direct or incidental, resulting
	from the use or non-use of these Example Files.

	The Example Files may contain defects, and some contain deliberate
	coding mistakes that were included for educational reasons.
	You are responsible for determining if and how the Example Files
	are to be used.

*/

#include "defs.h"
#include <dirent.h>
#include "JtuxDir.h" // generated by javah
#include "jtux_util.h"
#include "JNI_macros.h"

JNIEXPORT void JNICALL Java_jtux_UDir_closedir(JNIEnv *env, jclass obj,
  jlong dirp)
{
	JTHROW_neg1(closedir((DIR *)(intptr_t)dirp))
}

JNIEXPORT void JNICALL Java_jtux_UDir_mkdir(JNIEnv *env, jclass obj,
  jstring path, jint mode)
{
	JSTR_GET_DECL(path_c, path)

	JSTR_NULLTEST(path_c)
	JTHROW_neg1(mkdir(path_c, mode))
	JSTR_REL(path_c, path)
}

JNIEXPORT jlong JNICALL Java_jtux_UDir_opendir(JNIEnv *env, jclass obj,
  jstring path)
{
	DIR *dirp;
	JSTR_GET_DECL(path_c, path)

	JSTR_NULLTEST_V(path_c, 0)
	JTHROW_null(dirp = opendir(path_c))
	JSTR_REL(path_c, path)
	return (intptr_t)dirp;
}

JNIEXPORT jobject JNICALL Java_jtux_UDir_readdir(JNIEnv *env, jclass obj,
  jlong dirp)
{
	jclass cls_s_dirent = (*env)->FindClass(env, "jtux/UDir$s_dirent");
	jobject dirent;
	jmethodID mid;
	long name_max;
	int r;
	struct dirent *entry, *result;

	errno = 0;
	if ((name_max = pathconf(".", _PC_NAME_MAX)) == -1) {
		if (errno == 0)
			name_max = 1000; // no limit -- take a guess
		else {
			JTHROW_neg1(-1);
			return NULL;
		}
	}
	JTHROW_null(entry = malloc(offsetof(struct dirent, d_name) + name_max + 1))
	if (entry == NULL)
		return NULL;
	JTHROW_rv(r = readdir_r((DIR *)(intptr_t)dirp, entry, &result))
	if (r > 0 || result == NULL) {
		free(entry);
		return NULL;
	}
	if (cls_s_dirent == NULL) {
		free(entry);
		return NULL;
	}
	if ((mid = (*env)->GetMethodID(env, cls_s_dirent, "<init>", "()V")) == NULL) {
		free(entry);
		return NULL;
	}
	if ((dirent = (*env)->NewObject(env, cls_s_dirent, mid)) == NULL) {
		free(entry);
		return NULL;
	}
	if (!field_ctoj_int(env, cls_s_dirent, "d_ino", dirent, result->d_ino)) {
		free(entry);
		return NULL;
	}
	if (!field_ctoj_string(env, cls_s_dirent, "d_name", dirent, result->d_name)) {
		free(entry);
		return NULL;
	}
	free(entry);
	return dirent;
}

JNIEXPORT void JNICALL Java_jtux_UDir_rewinddir(JNIEnv *env, jclass obj,
  jlong dirp)
{
	rewinddir((DIR *)(intptr_t)dirp);
}

JNIEXPORT void JNICALL Java_jtux_UDir_rmdir(JNIEnv *env, jclass obj,
  jstring path)
{
	JSTR_GET_DECL(path_c, path)

	JSTR_NULLTEST(path_c)
	JTHROW_neg1(rmdir(path_c))
	JSTR_REL(path_c, path)
}

JNIEXPORT void JNICALL Java_jtux_UDir_seekdir(JNIEnv *env, jclass obj,
  jlong dirp, jlong loc)
{
	seekdir((DIR *)(intptr_t)dirp, loc);
}

JNIEXPORT jlong JNICALL Java_jtux_UDir_telldir(JNIEnv *env, jclass obj,
  jlong dirp)
{
	return telldir((DIR *)(intptr_t)dirp);
}
