diff src/os/win32/ngx_files.c @ 2628:64a10d6b97bd

win32 ngx_open_file() supports utf8 names and NGX_FILE_APPEND
author Igor Sysoev <igor@sysoev.ru>
date Mon, 30 Mar 2009 14:51:51 +0000
parents ceef364208c8
children 5190c5dc3486
line wrap: on
line diff
--- a/src/os/win32/ngx_files.c
+++ b/src/os/win32/ngx_files.c
@@ -8,6 +8,38 @@
 #include <ngx_core.h>
 
 
+#define NGX_UTF16_BUFLEN  256
+
+static u_short *ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len);
+
+
+/* FILE_FLAG_BACKUP_SEMANTICS allows to obtain a handle to a directory */
+
+ngx_fd_t
+ngx_open_file(u_char *name, u_long mode, u_long create, u_long access)
+{
+    u_short   *u;
+    ngx_fd_t   fd;
+    u_short    utf16[NGX_UTF16_BUFLEN];
+
+    u = ngx_utf8_to_utf16(utf16, name, NGX_UTF16_BUFLEN);
+
+    if (u == NULL) {
+        return INVALID_HANDLE_VALUE;
+    }
+
+    fd = CreateFileW(u, mode,
+                     FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+                     NULL, create, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+    if (u != utf16) {
+        ngx_free(u);
+    }
+
+    return fd;
+}
+
+
 ssize_t
 ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
 {
@@ -529,3 +561,82 @@ ngx_fs_bsize(u_char *name)
 
     return sc * bs;
 }
+
+
+static u_short *
+ngx_utf8_to_utf16(u_short *utf16, u_char *utf8, size_t len)
+{
+    u_char    *p;
+    u_short   *u, *last;
+    uint32_t   n;
+
+    p = utf8;
+    u = utf16;
+    last = utf16 + len;
+
+    while (u < last) {
+
+        if (*p < 0x80) {
+            *u = (u_short) *p;
+
+            if (*p == 0) {
+                return utf16;
+            }
+
+            u++;
+            p++;
+
+            continue;
+        }
+
+        n = ngx_utf8_decode(&p, 4);
+
+        if (n > 0xffff) {
+            free(utf16);
+            ngx_set_errno(NGX_EILSEQ);
+            return NULL;
+        }
+
+        *u++ = (u_short) n;
+    }
+
+    /* the given buffer is not enough, allocate a new one */
+
+    u = malloc(((p - utf8) + ngx_strlen(p) + 1) * sizeof(u_short));
+    if (u == NULL) {
+        return NULL;
+    }
+
+    ngx_memcpy(u, utf16, len * 2);
+
+    utf16 = u;
+    u += len;
+
+    for ( ;; ) {
+
+        if (*p < 0x80) {
+            *u = (u_short) *p;
+
+            if (*p == 0) {
+                return utf16;
+            }
+
+            u++;
+            p++;
+
+            continue;
+        }
+
+        n = ngx_utf8_decode(&p, 4);
+
+        if (n > 0xffff) {
+            free(utf16);
+            ngx_set_errno(NGX_EILSEQ);
+            return NULL;
+        }
+
+        *u++ = (u_short) n;
+    }
+
+    /* unreachable */
+}