You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/10/21 17:26:56 UTC
svn commit: r828045 - in /commons/sandbox/runtime/trunk/src/main:
java/org/apache/commons/runtime/io/Path.java native/os/unix/path.c
native/os/win32/path.c native/os/win32/wutil.c
Author: mturk
Date: Wed Oct 21 15:26:55 2009
New Revision: 828045
URL: http://svn.apache.org/viewvc?rev=828045&view=rev
Log:
Implement firts part of windows Path methods
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java
commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c
Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java?rev=828045&r1=828044&r2=828045&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java Wed Oct 21 15:26:55 2009
@@ -56,18 +56,23 @@
*/
public static final int MAX;
/**
+ * Maximum length of individual {@code Path} part.
+ */
+ public static final int PART_SIZE;
+ /**
* {@code true} if file system is case sensitive.
*/
public static final boolean CASE_SENSITIVE;
private static native void init0(int [] p);
static {
- int [] ia = new int[4];
+ int [] ia = new int[8];
init0(ia);
SEPARATOR = (char)ia[0];
DELIMITER = (char)ia[1];
MAX = ia[2];
- CASE_SENSITIVE = ia[3] == 1;
+ PART_SIZE = ia[3];
+ CASE_SENSITIVE = ia[4] == 0;
}
private static native String normal0(String path)
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c?rev=828045&r1=828044&r2=828045&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c Wed Oct 21 15:26:55 2009
@@ -172,15 +172,16 @@
ACR_IO_EXPORT_DECLARE(void, Path, init0)(ACR_JNISTDARGS,
jintArray p)
{
- jint ia[4];
+ jint ia[8];
UNREFERENCED_O;
ia[0] = '/';
ia[1] = ':';
ia[2] = PATH_MAX - 1;
- ia[3] = 1;
- (*_E)->SetIntArrayRegion(_E, p, 0, 4, &ia[0]);
+ ia[3] = PATH_MAX - 2;
+ ia[4] = 1;
+ (*_E)->SetIntArrayRegion(_E, p, 0, 8, &ia[0]);
}
ACR_IO_EXPORT_DECLARE(jstring, Path, canon0)(ACR_JNISTDARGS, jstring path)
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c?rev=828045&r1=828044&r2=828045&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c Wed Oct 21 15:26:55 2009
@@ -38,13 +38,17 @@
*/
static __inline wchar_t *NO2UNC(wchar_t *fname)
{
- if (wcsncmp(fname, L"\\\\?\\", 4) == 0) {
+ if (fname[0] == L'/' && fname[1] == L'/' &&
+ fname[2] == L'?' && fname[2] == L'/') {
fname += 4;
- if (wcsncmp(fname, L"UNC\\", 4) == 0) {
+ if (fname[0] == L'U' && fname[1] == L'N' &&
+ fname[2] == L'C' && fname[3] == L'/') {
fname += 2;
*fname = L'\\';
}
- else if (wcsncmp(fname, L"UN\\\\", 4) == 0) {
+ else if (fname[0] == L'U' && fname[1] == L'N' &&
+ fname[2] == L'/' && fname[3] == L'/') {
+ fname += 2;
/* Already modified in-place.
*/
fname += 2;
@@ -62,6 +66,99 @@
}
}
+static __inline void BS2FS(wchar_t *path)
+{
+ while (*path) {
+ if (*path == L'\\')
+ *path = L'/';
+ path++;
+ }
+}
+
+#define UCPATH_MAX 8192
+#define IS_PATH_SEP(C) ((C) == L'/' || (C) == L'\0')
+
+static wchar_t *_rel_path(wchar_t *pcopy, size_t size, const wchar_t *path)
+{
+ wchar_t *cp;
+ wchar_t *rv;
+ int ch = '/';
+ size_t l;
+
+ wcslcpy(pcopy, path, size);
+ /* Convert everything to back slashes
+ */
+ BS2FS(pcopy);
+ /* Remove \\?\ and replace \\?\UNC\ with \\
+ */
+ pcopy = NO2UNC(pcopy);
+ l = wcslen(pcopy);
+ if (l > 1 && pcopy[l - 1] == L'/')
+ pcopy[l - 1] = L'\0';
+
+ rv = pcopy;
+ if (((pcopy[0] >= L'A' && pcopy[0] <= 'Z') ||
+ (pcopy[0] >= L'a' && pcopy[0] <= 'z')) && pcopy[1] == L':') {
+ /* Never go above C: */
+ pcopy += 2;
+ }
+ else if (pcopy[0] == L'/' && pcopy[1] == '/') {
+ /* Never go above //share/
+ */
+ if (pcopy[2] == L'.' && pcopy[3] == L'/') {
+ /* This is //./pipe/ */
+ return pcopy;
+ }
+ cp = wcschr(pcopy + 2, '/');
+ if (cp)
+ pcopy = cp;
+ else {
+ /* We only have //share
+ */
+ return pcopy;
+ }
+ }
+ path = cp = pcopy;
+ while (*path) {
+ if (IS_PATH_SEP(ch) && *path == L'.') {
+ size_t nd = 0;
+ while (path[nd] == L'.')
+ nd++;
+ if (nd > 2) {
+ errno = ACR_EINVAL;
+ return NULL;
+ }
+ if (IS_PATH_SEP(path[nd])) {
+ path += nd;
+ if (*path)
+ path++;
+ while (nd > 1) {
+ if (cp > pcopy + 1) {
+ cp--;
+ while (cp > pcopy) {
+ if (IS_PATH_SEP(*(cp - 1)))
+ break;
+ cp--;
+ }
+ }
+ else
+ break;
+ nd--;
+ }
+ }
+ else
+ ch = *cp++ = *path++;
+ }
+ else
+ ch = *cp++ = *path++;
+ }
+ *cp = L'\0';
+ /* Duplicate the final path
+ */
+ return rv;
+
+}
+
wchar_t * acr_GetJavaNativePathW(JNIEnv *_E, jstring str, wchar_t *b)
{
size_t srclen;
@@ -204,3 +301,66 @@
}
return r;
}
+
+
+ACR_IO_EXPORT_DECLARE(void, Path, init0)(ACR_JNISTDARGS,
+ jintArray p)
+{
+ jint ia[8];
+
+ UNREFERENCED_O;
+
+ ia[0] = '\\';
+ ia[1] = ';';
+ ia[2] = UCPATH_MAX; /* Use our path limit */
+ ia[3] = NON_UNC_PATH_LENGTH;
+ ia[4] = 1;
+ (*_E)->SetIntArrayRegion(_E, p, 0, 8, &ia[0]);
+}
+
+ACR_IO_EXPORT_DECLARE(jstring, Path, normal0)(ACR_JNISTDARGS, jstring path)
+{
+ int rc = 0;
+ jstring rv = NULL;
+
+ UNREFERENCED_O;
+ WITH_WSTR(path) {
+ wchar_t pcopy[UCPATH_MAX];
+ wchar_t *rel;
+ if ((rel = _rel_path(pcopy, UCPATH_MAX, J2W(path))))
+ rv = ACR_NewJavaStringW(_E, rel);
+ else
+ rc = ACR_GET_OS_ERROR();
+ } END_WITH_WSTR(path);
+
+ ACR_THROW_IO_IF_ERR(rc);
+ return rv;
+}
+
+ACR_IO_EXPORT_DECLARE(jstring, Path, native0)(ACR_JNISTDARGS, jstring path)
+{
+ jstring rv = NULL;
+
+ WITH_WPATH(path) {
+ rv = ACR_NewJavaStringW(_E, J2W(path));
+ } END_WITH_WPATH(path);
+ return rv;
+}
+
+ACR_IO_EXPORT_DECLARE(jint, Path, compare0)(ACR_JNISTDARGS,
+ jstring path,
+ jstring other)
+{
+ int rc = 1;
+
+ UNREFERENCED_O;
+ WITH_WSTR(path) {
+ WITH_WSTR(other) {
+ /* Presume case insensitive file system
+ */
+ rc = _wcsicmp(J2W(path), J2W(other));
+ } END_WITH_WSTR(other);
+ } END_WITH_WSTR(path);
+
+ return rc;
+}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c?rev=828045&r1=828044&r2=828045&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c Wed Oct 21 15:26:55 2009
@@ -220,6 +220,96 @@
return 0;
}
+static int acr_to_unicode_path(wchar_t* retstr, size_t retlen,
+ const wchar_t* srcstr)
+{
+ /* TODO: The computations could preconvert the string to determine
+ * the true size of the retstr, but that's a memory over speed
+ * tradeoff that isn't appropriate this early in development.
+ *
+ * Allocate the maximum string length based on leading 4
+ * characters of \\?\ (allowing nearly unlimited path lengths)
+ * plus the trailing null, then transform /'s into \\'s since
+ * the \\?\ form doesn't allow '/' path seperators.
+ *
+ * Note that the \\?\ form only works for local drive paths, and
+ * \\?\UNC\ is needed UNC paths.
+ */
+ size_t srclen = wcslen(srcstr) + 1;
+ wchar_t *t = retstr;
+
+ /* leave an extra space for double zero */
+ t[--retlen] = L'\0';
+ /* This is correct, we don't twist the filename if it is will
+ * definately be shorter than MAX_PATH. It merits some
+ * performance testing to see if this has any effect, but there
+ * seem to be applications that get confused by the resulting
+ * Unicode \\?\ style file names, especially if they use argv[0]
+ * or call the Win32 API functions such as GetModuleName, etc.
+ * Not every application is prepared to handle such names.
+ *
+ * Note that a utf-8 name can never result in more wide chars
+ * than the original number of utf-8 narrow chars.
+ */
+ if (srclen > NON_UNC_PATH_LENGTH) {
+ if (srcstr[1] == L':' && (srcstr[2] == L'/' || srcstr[2] == L'\\')) {
+ wcscpy (retstr, L"\\\\?\\");
+ retlen -= 4;
+ t += 4;
+ }
+ else if ((srcstr[0] == L'/' || srcstr[0] == L'\\')
+ && (srcstr[1] == L'/' || srcstr[1] == L'\\')
+ && (srcstr[2] != L'?')) {
+ if (srcstr[2] == L'.' && (srcstr[3] == L'/' || srcstr[3] == L'\\')) {
+ /* We have \\.\ sequence that can apear only
+ * if we have something like \\.\pipe\
+ */
+ wcscpy (retstr, L"\\\\.\\");
+ srcstr += 4;
+ retlen -= 4;
+ t += 4;
+ }
+ else {
+ /* Skip the slashes and ? */
+ srcstr += 2;
+ srclen -= 2;
+ wcscpy (retstr, L"\\\\?\\UNC\\");
+ retlen -= 8;
+ t += 8;
+ }
+ }
+ else if (srcstr[0] == L'/' || srcstr[0] == L'\\') {
+ int cd;
+ /* Addition to APR. Allow \FilePath
+ * and construct \\?\CurrenttDrive:\FilePath
+ * We use _getdrive CRT function
+ */
+ wcscpy (retstr, L"\\\\?\\");
+ if ((cd = _getdrive()))
+ retstr[4] = L'A' + cd - 1;
+ else {
+ /* C:\ should always be there
+ * If not later open will fail anyhow
+ */
+ retstr[4] = L'C';
+ }
+ retstr[5] = L':';
+ retlen -= 6;
+ t += 6;
+ }
+ }
+ if (srclen > retlen)
+ return ACR_EOVERFLOW;
+ memcpy(t, srcstr, srclen * sizeof(wchar_t));
+ t[srclen] = L'\0';
+ for (; *t; t++) {
+ if (*t == L'/')
+ *t = L'\\';
+ }
+ return 0;
+}
+
+
wchar_t *x_wcsdup_utf8_path(const char *str)
{
int rc;