Return-Path: Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: (qmail 13453 invoked from network); 21 Oct 2009 15:27:21 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 21 Oct 2009 15:27:21 -0000 Received: (qmail 97414 invoked by uid 500); 21 Oct 2009 15:27:21 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 97340 invoked by uid 500); 21 Oct 2009 15:27:20 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 97331 invoked by uid 99); 21 Oct 2009 15:27:20 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Oct 2009 15:27:20 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 21 Oct 2009 15:27:17 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 566F82388985; Wed, 21 Oct 2009 15:26:56 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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 Date: Wed, 21 Oct 2009 15:26:56 -0000 To: commits@commons.apache.org From: mturk@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091021152656.566F82388985@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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;