Merge branch 'master' of git@git.labs.intellij.net:idea/community
[idea/community.git] / native / IdeaWin32 / IdeaWin32.cpp
1 #include "stdafx.h"
2 #include "IdeaWin32.h"
3 #include "jni_util.h"
4 #include "windows.h"
5
6 jfieldID nameId;
7
8 HANDLE FindFileInner(JNIEnv *env, jstring path, LPWIN32_FIND_DATA lpData) {
9         const jchar* str = env->GetStringChars(path, 0);
10         HANDLE h = FindFirstFile((LPCWSTR)str, lpData);
11         env->ReleaseStringChars(path, str);
12         return h;
13 }
14
15 bool CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
16                          jint count)
17 {
18     int i;
19     for (i=0; i<count; i++) {
20         jobject p = env->GetObjectArrayElement(src, i);
21         env->SetObjectArrayElement(dst, i, p);
22         env->DeleteLocalRef(p);
23     }
24     return true;
25 }
26
27 static LONGLONG
28 fileTimeToInt64 (const FILETIME * time)
29 {
30     ULARGE_INTEGER _time;
31
32     _time.LowPart = time->dwLowDateTime;
33     _time.HighPart = time->dwHighDateTime;
34
35     return _time.QuadPart;
36 }
37
38 jfieldID nameID; 
39 jfieldID attributesID;
40 jfieldID timestampID;
41
42 jobject CreateFileInfo(JNIEnv *env, LPWIN32_FIND_DATA lpData, jclass cls) {
43
44         jobject o = env->AllocObject(cls);
45         if (o == NULL) {
46                 return NULL;
47         }
48         jstring fileName = env->NewString((jchar*)lpData->cFileName, (jsize)wcslen(lpData->cFileName));
49         if (fileName == NULL) {
50                 return NULL;
51         }
52         env->SetObjectField(o, nameID, fileName);
53         env->SetIntField(o, attributesID, lpData->dwFileAttributes);
54         env->SetLongField(o, timestampID, fileTimeToInt64(&lpData->ftLastWriteTime));
55         return o;
56 }
57
58 JNIEXPORT void JNICALL Java_com_intellij_openapi_vfs_impl_win32_FileInfo_initIDs(JNIEnv *env, jclass cls) {
59         nameID = env->GetFieldID(cls, "name", "Ljava/lang/String;");
60         attributesID = env->GetFieldID(cls, "attributes", "I");
61         timestampID = env->GetFieldID(cls, "timestamp", "J");
62 }
63
64 JNIEXPORT jobject JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_getInfo(JNIEnv *env, jobject method, jstring path) {
65         WIN32_FIND_DATA data;
66         HANDLE h = FindFileInner(env, path, &data);
67         if (h == INVALID_HANDLE_VALUE) {
68           return NULL;
69         }
70         FindClose(h);   
71         jclass infoClass = env->FindClass("com/intellij/openapi/vfs/impl/win32/FileInfo");
72         return CreateFileInfo(env, &data, infoClass);
73 }
74
75 JNIEXPORT jboolean JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_checkExist(JNIEnv *env, jobject method, jstring path) {
76         jint result = 0;
77     WIN32_FILE_ATTRIBUTE_DATA wfad;
78         const jchar* str = env->GetStringChars(path, 0);
79
80     if (GetFileAttributesEx((LPCWSTR)path, GetFileExInfoStandard, &wfad)) return JNI_TRUE;
81         return JNI_FALSE;
82 }
83
84 JNIEXPORT jobjectArray JNICALL Java_com_intellij_openapi_vfs_impl_win32_IdeaWin32_listChildren(JNIEnv *env, jobject method, jstring path)
85 {
86
87   WIN32_FIND_DATA data;
88   HANDLE h = FindFileInner(env, path, &data);
89   if (h == INVALID_HANDLE_VALUE) {
90           return NULL;
91   }
92
93   jobjectArray rv, old;
94   int len, maxlen;
95
96   len = 0;
97   maxlen = 16;
98   jclass infoClass = env->FindClass("com/intellij/openapi/vfs/impl/win32/FileInfo");
99   rv = env->NewObjectArray(maxlen, infoClass, NULL);
100   if (rv == NULL) goto error;
101   do  {
102         if (len == maxlen) {
103             old = rv;
104             rv = env->NewObjectArray(maxlen <<= 1,
105                                         infoClass, NULL);
106             if (rv == NULL) goto error;
107             if (!CopyObjectArray(env, rv, old, len)) goto error;
108             env->DeleteLocalRef(old);
109         }
110                 jobject o = CreateFileInfo(env, &data, infoClass);
111           env->SetObjectArrayElement(rv, len++, o);
112           env->DeleteLocalRef(o);
113   }
114   while (FindNextFile(h, &data));
115
116   FindClose(h); 
117
118         old = rv;
119         rv = env->NewObjectArray(len, infoClass, NULL);
120         if (rv == NULL) goto error;
121         if (!CopyObjectArray(env, rv, old, len)) goto error;
122         return rv;
123
124
125 error:
126   FindClose(h); 
127   return NULL;
128 }
129
130 BOOL APIENTRY DllMain( HMODULE hModule,
131                        DWORD  ul_reason_for_call,
132                        LPVOID lpReserved
133                                          )
134 {
135     return TRUE;
136 }
137