Ticket #458: win32_read_dir.patch
| File win32_read_dir.patch, 5.9 KB (added by , 13 years ago) |
|---|
-
src/os/win32/ngx_files.c
# HG changeset patch # User K # Date 1386335779 -7200 # Fri Dec 06 15:16:19 2013 +0200 # Node ID da3b8749f162ff4849633e32bd19eabb4370a688 # Parent fedf777c6b24651d4dd86310334521ace0b2139b Win32: WCHAR support it ngx_read_dir() to enable Unicode in autoindex Functions ngx_open_dir() and ngx_read_dir() are refactored to use WCHAR file names. UTF-8 version of file name is cached in additional buffer. diff -r fedf777c6b24 -r da3b8749f162 src/os/win32/ngx_files.c
a b 426 426 ngx_int_t 427 427 ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) 428 428 { 429 size_t len; 430 u_short *u; 431 u_short utf16[NGX_UTF16_BUFLEN]; 432 429 433 ngx_cpystrn(name->data + name->len, NGX_DIR_MASK, NGX_DIR_MASK_LEN + 1); 430 434 431 dir->dir = FindFirstFile((const char *) name->data, &dir->finddata); 435 len = NGX_UTF16_BUFLEN; 436 u = ngx_utf8_to_utf16(utf16, name->data, &len); 437 438 if (u == NULL) { 439 return NGX_ERROR; 440 } 441 442 dir->namelen = 0; // clear cached utf-8 buffer 443 dir->dir = FindFirstFileW(u, &dir->finddata); 432 444 433 445 if (dir->dir == INVALID_HANDLE_VALUE) { 434 446 return NGX_ERROR; … … 441 453 } 442 454 443 455 456 457 444 458 ngx_int_t 445 459 ngx_read_dir(ngx_dir_t *dir) 446 460 { … … 449 463 return NGX_OK; 450 464 } 451 465 452 if (FindNextFile(dir->dir, &dir->finddata) != 0) { 466 dir->namelen = 0; // clear cached utf-8 buffer 467 if (FindNextFileW(dir->dir, &dir->finddata) != 0) { 453 468 dir->type = 1; 454 469 return NGX_OK; 455 470 } … … 574 589 } 575 590 } 576 591 592 static u_char * 593 ngx_utf8_encode_char(u_long ch, u_char *str) { 594 if (ch <= 0x7f) { 595 *str++ = (u_char)ch; 596 } else if (ch <= 0x0007ff) { 597 *str++ = (u_char)(0xc0 | (ch >> 6) & 0x1f); 598 *str++ = (u_char)(0x80 | (ch & 0x3f)); 599 } else if (ch <= 0x00ffff) { 600 *str++ = (u_char)(0xe0 | (ch >> 12) & 0x0f); 601 *str++ = (u_char)(0x80 | (ch >> 6) & 0x3f); 602 *str++ = (u_char)(0x80 | (ch & 0x3f)); 603 } else if (ch <= 0x10ffff) { 604 *str++ = (u_char)(0xf0 | (ch >> 18) & 0x07); 605 *str++ = (u_char)(0x80 | (ch >> 12) & 0x3f); 606 *str++ = (u_char)(0x80 | (ch >> 6) & 0x3f); 607 *str++ = (u_char)(0x80 | (ch & 0x3f)); 608 } 609 return str; 610 } 611 612 static u_char * 613 ngx_utf16_to_utf8(u_char *utf8, u_short *utf16, size_t *len) 614 { 615 u_short *u; 616 u_char *p; 617 u_long surrogate; 618 619 p = utf8; 620 u = utf16; 621 622 for ( ;; ) { 623 624 if ((*u >= 0xd800) && (*u <= 0xdbff)) { 625 surrogate = (*u - 0xd800) << 10; 626 if (!((*(u+1) >= 0xdc00) && (*(u+1) <= 0xdfff))) { 627 // Broken surrogate pair, out as is 628 p = ngx_utf8_encode_char(*u, p); 629 } 630 } else if ((*u >= 0xdc00) && (*u <= 0xdfff)) { 631 surrogate |= *u - 0xdc00; 632 p = ngx_utf8_encode_char(surrogate + 0x10000, p); 633 } else { 634 p = ngx_utf8_encode_char(*u, p); 635 } 636 637 if (*u == 0) { 638 *len = p - utf8 - 1; 639 return utf8; 640 } 641 642 u++; 643 } 644 645 /* unreachable */ 646 } 647 648 649 u_char * 650 ngx_de_name(ngx_dir_t *dir) 651 { 652 size_t len; 653 u_char *u; 654 655 if (!dir->namelen) { 656 len = NGX_UTF8_BUFLEN; 657 u = ngx_utf16_to_utf8(dir->name, dir->finddata.cFileName, &len); 658 dir->namelen = len; 659 } 660 return dir->name; 661 } 662 663 664 size_t 665 ngx_de_namelen(ngx_dir_t *dir) 666 { 667 if (!dir->namelen) { 668 ngx_de_name(dir); 669 } 670 return dir->namelen; 671 } 672 577 673 578 674 ngx_int_t 579 675 ngx_de_info(u_char *name, ngx_dir_t *dir) … … 801 897 802 898 n = ngx_utf8_decode(&p, 4); 803 899 804 if (n > 0x ffff) {900 if (n > 0x10ffff) { 805 901 ngx_set_errno(NGX_EILSEQ); 806 902 return NULL; 807 903 } 808 904 809 *u++ = (u_short) n; 905 if (n > 0xffff) { 906 // LE order 907 *u++ = (u_short) (0xd800 | ( ((n >> 16) & 0x1f) - 1 ) << 6 | (n & 0xffff) >> 10); // high surrogate 908 // ??? check buffer length ??? 909 *u++ = (u_short) (0xdc00 | n & 0x3ff); // low surrogate 910 } else { 911 *u++ = (u_short) n; 912 } 810 913 } 811 914 812 915 /* the given buffer is not enough, allocate a new one */ … … 838 941 839 942 n = ngx_utf8_decode(&p, 4); 840 943 841 if (n > 0x ffff) {944 if (n > 0x10ffff) { 842 945 free(utf16); 843 946 ngx_set_errno(NGX_EILSEQ); 844 947 return NULL; 845 948 } 846 949 847 *u++ = (u_short) n; 950 if (n > 0xffff) { 951 // LE order 952 *u++ = (u_short) (0xd800 | ( ((n >> 16) & 0x1f) - 1 ) << 6 | (n & 0xffff) >> 10); // high surrogate 953 // ??? check buffer length ??? 954 *u++ = (u_short) (0xdc00 | n & 0x3ff); // low surrogate 955 } else { 956 *u++ = (u_short) n; 957 } 848 958 } 849 959 850 960 /* unreachable */ -
src/os/win32/ngx_files.h
diff -r fedf777c6b24 -r da3b8749f162 src/os/win32/ngx_files.h
a b 28 28 } ngx_file_mapping_t; 29 29 30 30 31 /* Windows defines MAX_PATH as 260 */ 32 #define NGX_UTF8_BUFLEN ((MAX_PATH-1)*4+1) /* utf-8 char takes at most 4 bytes for U+10FFFF range */ 33 34 31 35 typedef struct { 32 36 HANDLE dir; 33 WIN32_FIND_DATA finddata; 37 WIN32_FIND_DATAW finddata; 38 u_char name[NGX_UTF8_BUFLEN]; 39 size_t namelen; 34 40 35 41 unsigned valid_info:1; 36 42 unsigned type:1; … … 208 214 #define ngx_dir_access(a) (a) 209 215 210 216 211 #define ngx_de_name(dir) ((u_char *) (dir)->finddata.cFileName) 212 #define ngx_de_namelen(dir) ngx_strlen((dir)->finddata.cFileName) 217 u_char *ngx_de_name(ngx_dir_t *dir); 218 size_t ngx_de_namelen(ngx_dir_t *dir); 213 219 214 220 ngx_int_t ngx_de_info(u_char *name, ngx_dir_t *dir); 215 221 #define ngx_de_info_n "dummy()"
