diff options
author | Igor Sysoev <igor@sysoev.ru> | 2009-03-30 14:51:51 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2009-03-30 14:51:51 +0000 |
commit | fadc7a7e810874b95bb934aa107bfe0a795347d3 (patch) | |
tree | 433f2fc4d83f67bdd560acf35b82dee0af4ac0fa /src/os/win32/ngx_files.c | |
parent | 8017a63cb3952850d0b40b4c95a938a7dbff7fe5 (diff) | |
download | nginx-fadc7a7e810874b95bb934aa107bfe0a795347d3.tar.gz nginx-fadc7a7e810874b95bb934aa107bfe0a795347d3.zip |
win32 ngx_open_file() supports utf8 names and NGX_FILE_APPEND
Diffstat (limited to 'src/os/win32/ngx_files.c')
-rw-r--r-- | src/os/win32/ngx_files.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c index afe31b9a0..f20b47973 100644 --- 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 */ +} |