aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/erl_unicode.c83
-rwxr-xr-xerts/emulator/beam/global.h4
2 files changed, 55 insertions, 32 deletions
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index 8f1b22ff92..a448b600ca 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -2023,11 +2023,11 @@ char *erts_convert_filename_to_encoding(Eterm name, char *statbuf, size_t statbu
} else if (is_binary(name)) {
byte *temp_alloc = NULL;
byte *bytes;
- byte *err_pos;
- Uint size,num_chars;
+ Uint size;
size = binary_size(name);
bytes = erts_get_aligned_binary_bytes(name, &temp_alloc);
+
if (encoding != ERL_FILENAME_WIN_WCHAR) {
/*Add 0 termination only*/
if (used)
@@ -2039,36 +2039,11 @@ char *erts_convert_filename_to_encoding(Eterm name, char *statbuf, size_t statbu
}
memcpy(name_buf,bytes,size);
name_buf[size]=0;
- } else if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK ||
- erts_get_user_requested_filename_encoding() == ERL_FILENAME_LATIN1) {
- byte *p;
- /* What to do now? Maybe latin1, so just take byte for byte instead */
- if (used)
- *used = (Sint) (size+1)*2;
- if ((size+1)*2 > statbuf_size) {
- name_buf = (char *) erts_alloc(alloc_type, (size+1)*2);
- } else {
- name_buf = statbuf;
- }
- p = (byte *) name_buf;
- while (size--) {
- *p++ = *bytes++;
- *p++ = 0;
- }
- *p++ = 0;
- *p++ = 0;
- } else { /* WIN_WCHAR and valid UTF8 */
- if (used)
- *used = (Sint) (num_chars+1)*2;
- if ((num_chars+1)*2 > statbuf_size) {
- name_buf = (char *) erts_alloc(alloc_type, (num_chars+1)*2);
- } else {
- name_buf = statbuf;
- }
- erts_copy_utf8_to_utf16_little((byte *) name_buf, bytes, num_chars);
- name_buf[num_chars*2] = 0;
- name_buf[num_chars*2+1] = 0;
- }
+ } else {
+ name_buf = erts_convert_filename_to_wchar(bytes, size,
+ statbuf, statbuf_size,
+ alloc_type, used, 0);
+ }
erts_free_aligned_binary_bytes(temp_alloc);
} else {
return NULL;
@@ -2076,6 +2051,50 @@ char *erts_convert_filename_to_encoding(Eterm name, char *statbuf, size_t statbu
return name_buf;
}
+char* erts_convert_filename_to_wchar(byte* bytes, Uint size,
+ char *statbuf, size_t statbuf_size,
+ ErtsAlcType_t alloc_type, Sint* used,
+ Uint extra_wchars)
+{
+ byte *err_pos;
+ Uint num_chars;
+ char* name_buf = NULL;
+ Sint need;
+ char *p;
+
+ if (erts_analyze_utf8(bytes,size,&err_pos,&num_chars,NULL) != ERTS_UTF8_OK ||
+ erts_get_user_requested_filename_encoding() == ERL_FILENAME_LATIN1) {
+
+ /* What to do now? Maybe latin1, so just take byte for byte instead */
+ need = (Sint) (size + extra_wchars + 1) * 2;
+ if (need > statbuf_size) {
+ name_buf = (char *) erts_alloc(alloc_type, need);
+ } else {
+ name_buf = statbuf;
+ }
+ p = name_buf;
+ while (size--) {
+ *p++ = *bytes++;
+ *p++ = 0;
+ }
+ } else { /* WIN_WCHAR and valid UTF8 */
+ need = (Sint) (num_chars + extra_wchars + 1) * 2;
+ if (need > statbuf_size) {
+ name_buf = (char *) erts_alloc(alloc_type, need);
+ } else {
+ name_buf = statbuf;
+ }
+ erts_copy_utf8_to_utf16_little((byte *) name_buf, bytes, num_chars);
+ p = name_buf + num_chars*2;
+ }
+ *p++ = 0;
+ *p++ = 0;
+ if (used)
+ *used = p - name_buf;
+ return name_buf;
+}
+
+
static int filename_len_16bit(byte *str)
{
byte *p = str;
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 11e464b639..c040b259a0 100755
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -918,6 +918,10 @@ char *erts_convert_filename_to_encoding(Eterm name, char *statbuf,
int allow_empty, int allow_atom,
int encoding,
Sint *used /* out */);
+char* erts_convert_filename_to_wchar(byte* bytes, Uint size,
+ char *statbuf, size_t statbuf_size,
+ ErtsAlcType_t alloc_type, Sint* used,
+ Uint extra_wchars);
Eterm erts_convert_native_to_filename(Process *p, byte *bytes);
Eterm erts_utf8_to_list(Process *p, Uint num, byte *bytes, Uint sz, Uint left,
Uint *num_built, Uint *num_eaten, Eterm tail);