Bug fix: ECMA-119 ".." pointed always to the same block as ".".
Bug fix: iso_write_opts_set_rrip_version_1_10() caused wrong size of root record CE, Stability enhancement: util.c:str2ascii() got a fallback for the case that charset "WCHAR_T" is not available, Debugging wrapper around iconv*() calls, Experiments about inode numbers in fs_image, Experiment to insert obsolete RR entries. (Sorry for the obfuscation. Most is due to a hard ride on Solaris. See macros at the end of libisofs/libisofs.h)
This commit is contained in:
parent
4f468171ad
commit
4d0063f7e2
@ -419,7 +419,11 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
#ifdef Libisofs_use_parent_for_dot_doT
|
||||||
|
int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||||
|
#else
|
||||||
int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
uint8_t buffer[BLOCK_SIZE];
|
uint8_t buffer[BLOCK_SIZE];
|
||||||
@ -462,7 +466,11 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
len = 34 + info.suf_len;
|
len = 34 + info.suf_len;
|
||||||
|
#ifdef Libisofs_use_parent_for_dot_doT
|
||||||
|
write_one_dir_record(t, parent, 1, buf, 1, &info, 0);
|
||||||
|
#else
|
||||||
write_one_dir_record(t, dir, 1, buf, 1, &info, 0);
|
write_one_dir_record(t, dir, 1, buf, 1, &info, 0);
|
||||||
|
#endif
|
||||||
buf += len;
|
buf += len;
|
||||||
|
|
||||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||||
@ -519,13 +527,24 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
#ifdef Libisofs_use_parent_for_dot_doT
|
||||||
|
|
||||||
|
/* ts A90309 : todo ? : rename parameter "root" to "dir" */
|
||||||
|
|
||||||
|
int write_dirs(Ecma119Image *t, Ecma119Node *root, Ecma119Node *parent)
|
||||||
|
#else
|
||||||
int write_dirs(Ecma119Image *t, Ecma119Node *root)
|
int write_dirs(Ecma119Image *t, Ecma119Node *root)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
/* write all directory entries for this dir */
|
/* write all directory entries for this dir */
|
||||||
|
#ifdef Libisofs_use_parent_for_dot_doT
|
||||||
|
ret = write_one_dir(t, root, parent);
|
||||||
|
#else
|
||||||
ret = write_one_dir(t, root);
|
ret = write_one_dir(t, root);
|
||||||
|
#endif
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -534,7 +553,11 @@ int write_dirs(Ecma119Image *t, Ecma119Node *root)
|
|||||||
for (i = 0; i < root->info.dir->nchildren; i++) {
|
for (i = 0; i < root->info.dir->nchildren; i++) {
|
||||||
Ecma119Node *child = root->info.dir->children[i];
|
Ecma119Node *child = root->info.dir->children[i];
|
||||||
if (child->type == ECMA119_DIR) {
|
if (child->type == ECMA119_DIR) {
|
||||||
|
#ifdef Libisofs_use_parent_for_dot_doT
|
||||||
|
ret = write_dirs(t, child, root);
|
||||||
|
#else
|
||||||
ret = write_dirs(t, child);
|
ret = write_dirs(t, child);
|
||||||
|
#endif
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -653,7 +676,11 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
|
|||||||
t = writer->target;
|
t = writer->target;
|
||||||
|
|
||||||
/* first of all, we write the directory structure */
|
/* first of all, we write the directory structure */
|
||||||
|
#ifdef Libisofs_use_parent_for_dot_doT
|
||||||
|
ret = write_dirs(t, t->root, t->root);
|
||||||
|
#else
|
||||||
ret = write_dirs(t, t->root);
|
ret = write_dirs(t, t->root);
|
||||||
|
#endif
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -4771,23 +4771,60 @@ struct burn_source {
|
|||||||
|
|
||||||
#endif /* LIBISOFS_WITHOUT_LIBBURN */
|
#endif /* LIBISOFS_WITHOUT_LIBBURN */
|
||||||
|
|
||||||
|
/* ----------------------------- Bug Fixes ----------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
/* Bug Fix : Augment ecma119.c:write_dirs() by parameter parent
|
||||||
|
and use that one for the second directory entry 001 = "..".
|
||||||
|
|
||||||
|
Everything else seems wrong.
|
||||||
|
*/
|
||||||
|
#define Libisofs_use_parent_for_dot_doT yes
|
||||||
|
|
||||||
|
|
||||||
|
/* Bug fix : Use correct size of 237 if the ER of RRIP-1.10 shal be written
|
||||||
|
(rather than size 182 of RRIP-1.12)
|
||||||
|
|
||||||
|
*/
|
||||||
|
#define Libisofs_rrip_1_10_er_bugfiX yes
|
||||||
|
|
||||||
|
|
||||||
|
/* ---------------------------- Experiments ---------------------------- */
|
||||||
|
|
||||||
/* Attempt to fix several issues about inode numbers from ISO images */
|
|
||||||
|
|
||||||
/* Experiment: Ignore PX inode numbers,
|
/* Experiment: Ignore PX inode numbers,
|
||||||
have boot image inode number counted by fs_give_ino_number()
|
have boot image inode number counted by fs_give_ino_number()
|
||||||
*/
|
*/
|
||||||
#define Libisofs_new_fs_image_inO yes
|
#define Libisofs_new_fs_image_inO yes
|
||||||
|
|
||||||
|
|
||||||
/* Experiment: Trying to avoid the risk of losing file content by duplicate
|
/* Experiment: Trying to avoid the risk of losing file content by duplicate
|
||||||
inodes. iso_file_src_cmp() shall compare sizes too.
|
inodes. iso_file_src_cmp() shall compare sizes too.
|
||||||
*/
|
*/
|
||||||
#define Libisofs_file_src_cmp_sizE yes
|
#define Libisofs_file_src_cmp_sizE yes
|
||||||
|
|
||||||
|
|
||||||
/* Experiment: Revoke Ticket 144, use data file LBAs again.
|
/* Experiment: Revoke Ticket 144, use data file LBAs again.
|
||||||
(will work only if not Libisofs_new_fs_image_inO
|
(will work only if not Libisofs_new_fs_image_inO
|
||||||
and wll only be safe with Libisofs_file_src_cmp_sizE)
|
and wll only be safe with Libisofs_file_src_cmp_sizE)
|
||||||
#define Libisofs_ino_from_lbA yes
|
#define Libisofs_ino_from_lbA yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Experiment: Write obsolete RR entries with Rock Ridge.
|
||||||
|
I suspect Solaris wants to see them.
|
||||||
|
DID NOT HELP: Solaris knows only RRIP_1991A.
|
||||||
|
|
||||||
|
#define Libisofs_with_rrip_rR yes
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Experiment: Use iso_iconv*() wrappers.
|
||||||
|
They can print errno messages and they
|
||||||
|
can avoid iconv() if the identical mapping is desired.
|
||||||
|
One could install own simple conversion capabilities.
|
||||||
|
*/
|
||||||
|
#define Libisofs_with_iso_iconV yes
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_LIBISOFS_H_*/
|
#endif /*LIBISO_LIBISOFS_H_*/
|
||||||
|
@ -381,6 +381,38 @@ int rrip_SL_append_comp(size_t *n, uint8_t ***comps, char *s, int size, char fl)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_rrip_rR
|
||||||
|
|
||||||
|
/* ts A90307 */
|
||||||
|
/**
|
||||||
|
* Add to the given tree node a RR System Use Entry. This is an obsolete
|
||||||
|
* entry from before RRIP-1.10. Nevertheless mkisofs produces it and there
|
||||||
|
* is the suspicion that Solaris takes it as indication for Rock Ridge.
|
||||||
|
*
|
||||||
|
* I once saw a copy of a RRIP spec which mentioned RR. Here i just use
|
||||||
|
* the same constant 5 bytes as produced by mkisofs.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int rrip_add_RR(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||||
|
{
|
||||||
|
uint8_t *RR;
|
||||||
|
RR = malloc(5);
|
||||||
|
if (RR == NULL) {
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
RR[0] = 'R';
|
||||||
|
RR[1] = 'R';
|
||||||
|
RR[2] = 5;
|
||||||
|
RR[3] = 1;
|
||||||
|
RR[4] = 0201;
|
||||||
|
return susp_append(t, susp, RR);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_with_rrip_rR */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a SL System Use Entry to the given tree node. This is used to store
|
* Add a SL System Use Entry to the given tree node. This is used to store
|
||||||
* the content of a symbolic link, and is mandatory if the tree node
|
* the content of a symbolic link, and is mandatory if the tree node
|
||||||
@ -496,7 +528,6 @@ int aaip_add_AA(Ecma119Image *t, struct susp_info *susp,
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
aapt = *data;
|
aapt = *data;
|
||||||
if (!(aapt[4] & 1)) {
|
if (!(aapt[4] & 1)) {
|
||||||
/* Single field can be handed over directly */
|
/* Single field can be handed over directly */
|
||||||
@ -554,6 +585,7 @@ int rrip_add_ER(Ecma119Image *t, struct susp_info *susp)
|
|||||||
decrease by 1."
|
decrease by 1."
|
||||||
So "IEEE_P1282" would be the new form, "RRIP_1991A" is the old form.
|
So "IEEE_P1282" would be the new form, "RRIP_1991A" is the old form.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ER = malloc(182);
|
ER = malloc(182);
|
||||||
if (ER == NULL) {
|
if (ER == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
@ -958,6 +990,11 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
|||||||
if (t->aaip && !t->aaip_susp_1_10)
|
if (t->aaip && !t->aaip_susp_1_10)
|
||||||
su_size += 5;
|
su_size += 5;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_rrip_rR
|
||||||
|
/* obsolete RR field (once in AAIP-1.09) */
|
||||||
|
su_size += 5;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* PX and TF, we are sure they always fit in SUA */
|
/* PX and TF, we are sure they always fit in SUA */
|
||||||
if (!t->rrip_version_1_10) {
|
if (!t->rrip_version_1_10) {
|
||||||
su_size += 44 + 26;
|
su_size += 44 + 26;
|
||||||
@ -996,7 +1033,9 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* "." or ".." entry */
|
/* "." or ".." entry */
|
||||||
|
|
||||||
su_size += 5; /* NM field */
|
su_size += 5; /* NM field */
|
||||||
|
|
||||||
if (type == 1 && n->parent == NULL) {
|
if (type == 1 && n->parent == NULL) {
|
||||||
/*
|
/*
|
||||||
* "." for root directory
|
* "." for root directory
|
||||||
@ -1004,7 +1043,20 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
|
|||||||
* ER needs a Continuation Area, thus we also need a CE entry
|
* ER needs a Continuation Area, thus we also need a CE entry
|
||||||
*/
|
*/
|
||||||
su_size += 7 + 28; /* SP + CE */
|
su_size += 7 + 28; /* SP + CE */
|
||||||
*ce = 182; /* ER of RRIP */
|
|
||||||
|
#ifdef Libisofs_rrip_1_10_er_bugfiX
|
||||||
|
|
||||||
|
/* ER of RRIP */
|
||||||
|
if (t->rrip_version_1_10) {
|
||||||
|
*ce = 237;
|
||||||
|
} else {
|
||||||
|
*ce = 182;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
*ce = 182;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (t->aaip) {
|
if (t->aaip) {
|
||||||
*ce += 160; /* ER of AAIP */
|
*ce += 160; /* ER of AAIP */
|
||||||
}
|
}
|
||||||
@ -1095,6 +1147,11 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
char *dest = NULL;
|
char *dest = NULL;
|
||||||
size_t aaip_er_len= 0;
|
size_t aaip_er_len= 0;
|
||||||
|
|
||||||
|
#ifdef Libisofs_rrip_1_10_er_bugfiX
|
||||||
|
size_t rrip_er_len= 182;
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
||||||
int ce_is_predicted = 0;
|
int ce_is_predicted = 0;
|
||||||
size_t aaip_sua_free= 0, aaip_len= 0;
|
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||||
@ -1138,6 +1195,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_rrip_rR
|
||||||
|
/* ts A90307 */
|
||||||
|
ret = rrip_add_RR(t, node, info);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto add_susp_cleanup;
|
||||||
|
}
|
||||||
|
#endif /* Libisofs_with_rrip_rR */
|
||||||
|
|
||||||
/* PX and TF, we are sure they always fit in SUA */
|
/* PX and TF, we are sure they always fit in SUA */
|
||||||
ret = rrip_add_PX(t, node, info);
|
ret = rrip_add_PX(t, node, info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -1448,6 +1513,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == 1 && n->parent == NULL) {
|
if (type == 1 && n->parent == NULL) {
|
||||||
/*
|
/*
|
||||||
* "." for root directory
|
* "." for root directory
|
||||||
@ -1456,6 +1522,28 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
* Note that SP entry was already added above
|
* Note that SP entry was already added above
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef Libisofs_rrip_1_10_er_bugfiX
|
||||||
|
|
||||||
|
if (t->rrip_version_1_10) {
|
||||||
|
rrip_er_len = 237;
|
||||||
|
} else {
|
||||||
|
rrip_er_len = 182;
|
||||||
|
}
|
||||||
|
if (t->aaip && !t->aaip_susp_1_10) {
|
||||||
|
aaip_er_len = 160;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute length of AAIP string of root node */
|
||||||
|
aaip_sua_free= 0;
|
||||||
|
ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto add_susp_cleanup;
|
||||||
|
|
||||||
|
/* Allocate the necessary CE space */
|
||||||
|
ret = susp_add_CE(t, rrip_er_len + aaip_er_len + aaip_len, info);
|
||||||
|
|
||||||
|
#else /* Libisofs_rrip_1_10_er_bugfiX */
|
||||||
|
|
||||||
if (t->aaip && !t->aaip_susp_1_10) {
|
if (t->aaip && !t->aaip_susp_1_10) {
|
||||||
aaip_er_len = 160;
|
aaip_er_len = 160;
|
||||||
}
|
}
|
||||||
@ -1469,6 +1557,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
/* Allocate the necessary CE space */
|
/* Allocate the necessary CE space */
|
||||||
ret = susp_add_CE(t, 182 + aaip_er_len + aaip_len, info);
|
ret = susp_add_CE(t, 182 + aaip_er_len + aaip_len, info);
|
||||||
/* 182 is RRIP-ER length */
|
/* 182 is RRIP-ER length */
|
||||||
|
|
||||||
|
#endif /* ! Libisofs_rrip_1_10_er_bugfiX */
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
}
|
}
|
||||||
|
341
libisofs/util.c
341
libisofs/util.c
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
/* if we don't have eaccess, we check file access by openning it */
|
/* if we don't have eaccess, we check file access by opening it */
|
||||||
#ifndef HAVE_EACCESS
|
#ifndef HAVE_EACCESS
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -32,6 +32,118 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
|
||||||
|
|
||||||
|
/* Produce possibly inflationary error messages directly to stderr */
|
||||||
|
static int iso_iconv_debug = 0;
|
||||||
|
|
||||||
|
|
||||||
|
struct iso_iconv_handle {
|
||||||
|
int status; /* bit0= open , bit1= identical mapping */
|
||||||
|
iconv_t descr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@param flag bit0= shortcut by identical mapping is not allowed
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int iso_iconv_open(struct iso_iconv_handle *handle,
|
||||||
|
char *tocode, char *fromcode, int flag)
|
||||||
|
{
|
||||||
|
handle->status = 0;
|
||||||
|
handle->descr = (iconv_t) -1;
|
||||||
|
|
||||||
|
if (strcmp(tocode, fromcode) == 0 && !(flag & 1)) {
|
||||||
|
handle->status = 1 | 2;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
handle->descr = iconv_open(tocode, fromcode);
|
||||||
|
if (handle->descr == (iconv_t) -1) {
|
||||||
|
if (strlen(tocode) + strlen(fromcode) <= 160 && iso_iconv_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"libisofs_DEBUG: iconv_open(\"%s\", \"%s\") failed: errno= %d %s\n",
|
||||||
|
tocode, fromcode, errno, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
handle->status = 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
size_t iso_iconv(struct iso_iconv_handle *handle,
|
||||||
|
char **inbuf, size_t *inbytesleft,
|
||||||
|
char **outbuf, size_t *outbytesleft, int flag)
|
||||||
|
{
|
||||||
|
size_t ret;
|
||||||
|
|
||||||
|
if (!(handle->status & 1)) {
|
||||||
|
if (iso_iconv_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"libisofs_DEBUG: iso_iconv(): iso_iconv_handle not in open state\n");
|
||||||
|
return (size_t) -1;
|
||||||
|
}
|
||||||
|
if (handle->status & 2) {
|
||||||
|
if (inbuf == NULL || outbuf == NULL) {
|
||||||
|
null_buf:;
|
||||||
|
if (iso_iconv_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"libisofs_DEBUG: iso_iconv(): NULL buffers not allowed in shortcut mapping\n");
|
||||||
|
return (size_t) -1;
|
||||||
|
}
|
||||||
|
if (*inbuf == NULL || *outbuf == NULL)
|
||||||
|
goto null_buf;
|
||||||
|
while (*inbytesleft > 0 && *outbytesleft > 0) {
|
||||||
|
*((*outbuf)++) = *((*inbuf)++);
|
||||||
|
(*inbytesleft)--;
|
||||||
|
(*outbytesleft)--;
|
||||||
|
}
|
||||||
|
if (*inbytesleft > 0 && *outbytesleft <= 0)
|
||||||
|
return (size_t) -1;
|
||||||
|
return (size_t) 0;
|
||||||
|
}
|
||||||
|
ret = iconv(handle->descr, inbuf, inbytesleft, outbuf, outbytesleft);
|
||||||
|
if (ret == (size_t) -1) {
|
||||||
|
if (iso_iconv_debug)
|
||||||
|
fprintf(stderr, "libisofs_DEBUG: iconv() failed: errno= %d %s\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return (size_t) -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_iconv_close(struct iso_iconv_handle *handle, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!(handle->status & 1)) {
|
||||||
|
if (iso_iconv_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"libisofs_DEBUG: iso_iconv_close(): iso_iconv_handle not in open state\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
handle->status &= ~1;
|
||||||
|
if (handle->status & 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = iconv_close(handle->descr);
|
||||||
|
if (ret == -1) {
|
||||||
|
if (iso_iconv_debug)
|
||||||
|
fprintf(stderr,
|
||||||
|
"libisofs_DEBUG: iconv_close() failed: errno= %d %s\n",
|
||||||
|
errno, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_with_iso_iconV */
|
||||||
|
|
||||||
|
|
||||||
int int_pow(int base, int power)
|
int int_pow(int base, int power)
|
||||||
{
|
{
|
||||||
int result = 1;
|
int result = 1;
|
||||||
@ -71,7 +183,14 @@ int strconv(const char *str, const char *icharset, const char *ocharset,
|
|||||||
size_t inbytes;
|
size_t inbytes;
|
||||||
size_t outbytes;
|
size_t outbytes;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
struct iso_iconv_handle conv;
|
||||||
|
int conv_ret;
|
||||||
|
#else
|
||||||
iconv_t conv;
|
iconv_t conv;
|
||||||
|
#endif
|
||||||
|
|
||||||
char *out;
|
char *out;
|
||||||
char *src;
|
char *src;
|
||||||
char *ret;
|
char *ret;
|
||||||
@ -83,21 +202,41 @@ int strconv(const char *str, const char *icharset, const char *ocharset,
|
|||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
conv_ret = iso_iconv_open(&conv, (char *) ocharset, (char *) icharset, 0);
|
||||||
|
if (conv_ret <= 0) {
|
||||||
|
#else
|
||||||
conv = iconv_open(ocharset, icharset);
|
conv = iconv_open(ocharset, icharset);
|
||||||
if (conv == (iconv_t)(-1)) {
|
if (conv == (iconv_t)(-1)) {
|
||||||
|
#endif
|
||||||
|
|
||||||
return ISO_CHARSET_CONV_ERROR;
|
return ISO_CHARSET_CONV_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
src = (char *)str;
|
src = (char *)str;
|
||||||
ret = (char *)out;
|
ret = (char *)out;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
if (n == -1) {
|
||||||
|
/* error */
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
#else
|
||||||
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
/* error */
|
/* error */
|
||||||
iconv_close(conv);
|
iconv_close(conv);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ISO_CHARSET_CONV_ERROR;
|
return ISO_CHARSET_CONV_ERROR;
|
||||||
}
|
}
|
||||||
*ret = '\0';
|
*ret = '\0';
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
#else
|
||||||
iconv_close(conv);
|
iconv_close(conv);
|
||||||
|
#endif
|
||||||
|
|
||||||
*output = malloc(ret - out + 1);
|
*output = malloc(ret - out + 1);
|
||||||
if (*output == NULL) {
|
if (*output == NULL) {
|
||||||
@ -113,7 +252,14 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
|
|||||||
size_t inbytes;
|
size_t inbytes;
|
||||||
size_t outbytes;
|
size_t outbytes;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
struct iso_iconv_handle conv;
|
||||||
|
int conv_ret;
|
||||||
|
#else
|
||||||
iconv_t conv;
|
iconv_t conv;
|
||||||
|
#endif
|
||||||
|
|
||||||
char *out;
|
char *out;
|
||||||
char *src;
|
char *src;
|
||||||
char *ret;
|
char *ret;
|
||||||
@ -125,21 +271,40 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
|
|||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
conv_ret = iso_iconv_open(&conv, (char *) ocharset, (char *) icharset, 0);
|
||||||
|
if (conv_ret <= 0) {
|
||||||
|
#else
|
||||||
conv = iconv_open(ocharset, icharset);
|
conv = iconv_open(ocharset, icharset);
|
||||||
if (conv == (iconv_t)(-1)) {
|
if (conv == (iconv_t)(-1)) {
|
||||||
|
#endif
|
||||||
|
|
||||||
return ISO_CHARSET_CONV_ERROR;
|
return ISO_CHARSET_CONV_ERROR;
|
||||||
}
|
}
|
||||||
src = (char *)str;
|
src = (char *)str;
|
||||||
ret = (char *)out;
|
ret = (char *)out;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
if (n == -1) {
|
||||||
|
/* error */
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
#else
|
||||||
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
/* error */
|
/* error */
|
||||||
iconv_close(conv);
|
iconv_close(conv);
|
||||||
|
#endif
|
||||||
|
|
||||||
return ISO_CHARSET_CONV_ERROR;
|
return ISO_CHARSET_CONV_ERROR;
|
||||||
}
|
}
|
||||||
*ret = '\0';
|
*ret = '\0';
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
#else
|
||||||
iconv_close(conv);
|
iconv_close(conv);
|
||||||
|
#endif
|
||||||
|
|
||||||
*output = malloc(ret - out + 1);
|
*output = malloc(ret - out + 1);
|
||||||
if (*output == NULL) {
|
if (*output == NULL) {
|
||||||
@ -159,7 +324,17 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
|
|||||||
static
|
static
|
||||||
int str2wchar(const char *icharset, const char *input, wchar_t **output)
|
int str2wchar(const char *icharset, const char *input, wchar_t **output)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
struct iso_iconv_handle conv;
|
||||||
|
int conv_ret;
|
||||||
|
#else
|
||||||
iconv_t conv;
|
iconv_t conv;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ts A90308 : that while loop smells like a potential show stopper */
|
||||||
|
size_t loop_counter = 0, loop_limit = 3;
|
||||||
|
|
||||||
size_t inbytes;
|
size_t inbytes;
|
||||||
size_t outbytes;
|
size_t outbytes;
|
||||||
char *ret;
|
char *ret;
|
||||||
@ -171,12 +346,20 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output)
|
|||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
conv_ret = iso_iconv_open(&conv, "WCHAR_T", (char *) icharset, 0);
|
||||||
|
if (conv_ret <= 0) {
|
||||||
|
#else
|
||||||
conv = iconv_open("WCHAR_T", icharset);
|
conv = iconv_open("WCHAR_T", icharset);
|
||||||
if (conv == (iconv_t)-1) {
|
if (conv == (iconv_t)-1) {
|
||||||
|
#endif
|
||||||
|
|
||||||
return ISO_CHARSET_CONV_ERROR;
|
return ISO_CHARSET_CONV_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
inbytes = strlen(input);
|
inbytes = strlen(input);
|
||||||
|
loop_limit = inbytes + 3;
|
||||||
outbytes = (inbytes + 1) * sizeof(wchar_t);
|
outbytes = (inbytes + 1) * sizeof(wchar_t);
|
||||||
|
|
||||||
/* we are sure that numchars <= inbytes */
|
/* we are sure that numchars <= inbytes */
|
||||||
@ -187,14 +370,18 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output)
|
|||||||
ret = (char *)wstr;
|
ret = (char *)wstr;
|
||||||
src = (char *)input;
|
src = (char *)input;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
#else
|
||||||
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
||||||
|
#endif
|
||||||
|
|
||||||
while (n == -1) {
|
while (n == -1) {
|
||||||
|
|
||||||
if (errno == E2BIG) {
|
if (errno == E2BIG) {
|
||||||
/* error, should never occur */
|
/* error, should never occur */
|
||||||
iconv_close(conv);
|
goto conv_error;
|
||||||
free(wstr);
|
|
||||||
return ISO_CHARSET_CONV_ERROR;
|
|
||||||
} else {
|
} else {
|
||||||
wchar_t *wret;
|
wchar_t *wret;
|
||||||
|
|
||||||
@ -214,14 +401,41 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output)
|
|||||||
|
|
||||||
if (!inbytes)
|
if (!inbytes)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Just to appease my remorse about unclear loop ends */
|
||||||
|
loop_counter++;
|
||||||
|
if (loop_counter > loop_limit)
|
||||||
|
goto conv_error;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
#else
|
||||||
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
#else
|
||||||
iconv_close(conv);
|
iconv_close(conv);
|
||||||
|
#endif
|
||||||
|
|
||||||
*( (wchar_t *)ret )='\0';
|
*( (wchar_t *)ret )='\0';
|
||||||
*output = wstr;
|
*output = wstr;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
|
conv_error:;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
#else
|
||||||
|
iconv_close(conv);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
free(wstr);
|
||||||
|
return ISO_CHARSET_CONV_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
int str2ascii(const char *icharset, const char *input, char **output)
|
int str2ascii(const char *icharset, const char *input, char **output)
|
||||||
@ -231,12 +445,26 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
char *ret;
|
char *ret;
|
||||||
char *ret_;
|
char *ret_;
|
||||||
char *src;
|
char *src;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
struct iso_iconv_handle conv;
|
||||||
|
int conv_ret;
|
||||||
|
#else
|
||||||
iconv_t conv;
|
iconv_t conv;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ts A90308 : that while loop smells like a potential show stopper */
|
||||||
|
size_t loop_counter = 0, loop_limit = 3;
|
||||||
|
|
||||||
|
/* ts A90308 : fallback in case that iconv() is too demanding for system */
|
||||||
|
unsigned char *cpt;
|
||||||
|
|
||||||
size_t numchars;
|
size_t numchars;
|
||||||
size_t outbytes;
|
size_t outbytes;
|
||||||
size_t inbytes;
|
size_t inbytes;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
|
|
||||||
if (icharset == NULL || input == NULL || output == NULL) {
|
if (icharset == NULL || input == NULL || output == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
@ -247,12 +475,13 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
*/
|
*/
|
||||||
result = str2wchar(icharset, input, &wsrc_);
|
result = str2wchar(icharset, input, &wsrc_);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
goto fallback;
|
||||||
}
|
}
|
||||||
src = (char *)wsrc_;
|
src = (char *)wsrc_;
|
||||||
numchars = wcslen(wsrc_);
|
numchars = wcslen(wsrc_);
|
||||||
|
|
||||||
inbytes = numchars * sizeof(wchar_t);
|
inbytes = numchars * sizeof(wchar_t);
|
||||||
|
loop_limit = inbytes + 3;
|
||||||
|
|
||||||
ret_ = malloc(numchars + 1);
|
ret_ = malloc(numchars + 1);
|
||||||
if (ret_ == NULL) {
|
if (ret_ == NULL) {
|
||||||
@ -262,14 +491,27 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
ret = ret_;
|
ret = ret_;
|
||||||
|
|
||||||
/* initialize iconv */
|
/* initialize iconv */
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
conv_ret = iso_iconv_open(&conv, "ASCII", "WCHAR_T", 0);
|
||||||
|
if (conv_ret <= 0) {
|
||||||
|
#else
|
||||||
conv = iconv_open("ASCII", "WCHAR_T");
|
conv = iconv_open("ASCII", "WCHAR_T");
|
||||||
if (conv == (iconv_t)-1) {
|
if (conv == (iconv_t)-1) {
|
||||||
|
#endif
|
||||||
|
|
||||||
free(wsrc_);
|
free(wsrc_);
|
||||||
free(ret_);
|
free(ret_);
|
||||||
return ISO_CHARSET_CONV_ERROR;
|
goto fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
#else
|
||||||
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
||||||
|
#endif
|
||||||
|
|
||||||
while (n == -1) {
|
while (n == -1) {
|
||||||
/* The destination buffer is too small. Stops here. */
|
/* The destination buffer is too small. Stops here. */
|
||||||
if (errno == E2BIG)
|
if (errno == E2BIG)
|
||||||
@ -299,16 +541,41 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
if (!inbytes)
|
if (!inbytes)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Just to appease my remorse about unclear loop ends */
|
||||||
|
loop_counter++;
|
||||||
|
if (loop_counter > loop_limit)
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
#else
|
||||||
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
#else
|
||||||
iconv_close(conv);
|
iconv_close(conv);
|
||||||
|
#endif
|
||||||
|
|
||||||
*ret='\0';
|
*ret='\0';
|
||||||
free(wsrc_);
|
free(wsrc_);
|
||||||
|
|
||||||
*output = ret_;
|
*output = ret_;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
|
fallback:;
|
||||||
|
/* Assume to have a single byte charset with ASCII as core.
|
||||||
|
Anything suspicious will be mapped to '_'.
|
||||||
|
*/
|
||||||
|
*output = strdup(input);
|
||||||
|
for (cpt = (unsigned char *) *output; *cpt; cpt++) {
|
||||||
|
if (*cpt < 32 || *cpt > 126)
|
||||||
|
*cpt = '_';
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -343,7 +610,17 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
char *src;
|
char *src;
|
||||||
char *ret;
|
char *ret;
|
||||||
char *ret_;
|
char *ret_;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
struct iso_iconv_handle conv;
|
||||||
|
int conv_ret;
|
||||||
|
#else
|
||||||
iconv_t conv;
|
iconv_t conv;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ts A90308 : that while loop smells like a potential show stopper */
|
||||||
|
size_t loop_counter = 0, loop_limit = 3;
|
||||||
|
|
||||||
size_t numchars;
|
size_t numchars;
|
||||||
size_t outbytes;
|
size_t outbytes;
|
||||||
size_t inbytes;
|
size_t inbytes;
|
||||||
@ -365,6 +642,7 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
numchars = wcslen(wsrc_);
|
numchars = wcslen(wsrc_);
|
||||||
|
|
||||||
inbytes = numchars * sizeof(wchar_t);
|
inbytes = numchars * sizeof(wchar_t);
|
||||||
|
loop_limit = inbytes + 3;
|
||||||
|
|
||||||
ret_ = malloc((numchars+1) * sizeof(uint16_t));
|
ret_ = malloc((numchars+1) * sizeof(uint16_t));
|
||||||
if (ret_ == NULL) {
|
if (ret_ == NULL) {
|
||||||
@ -374,14 +652,27 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
ret = ret_;
|
ret = ret_;
|
||||||
|
|
||||||
/* initialize iconv */
|
/* initialize iconv */
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
conv_ret = iso_iconv_open(&conv, "UCS-2BE", "WCHAR_T", 0);
|
||||||
|
if (conv_ret <= 0) {
|
||||||
|
#else
|
||||||
conv = iconv_open("UCS-2BE", "WCHAR_T");
|
conv = iconv_open("UCS-2BE", "WCHAR_T");
|
||||||
if (conv == (iconv_t)-1) {
|
if (conv == (iconv_t)-1) {
|
||||||
|
#endif
|
||||||
|
|
||||||
free(wsrc_);
|
free(wsrc_);
|
||||||
free(ret_);
|
free(ret_);
|
||||||
return ISO_CHARSET_CONV_ERROR;
|
return ISO_CHARSET_CONV_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
#else
|
||||||
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
||||||
|
#endif
|
||||||
|
|
||||||
while (n == -1) {
|
while (n == -1) {
|
||||||
/* The destination buffer is too small. Stops here. */
|
/* The destination buffer is too small. Stops here. */
|
||||||
if (errno == E2BIG)
|
if (errno == E2BIG)
|
||||||
@ -411,10 +702,24 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
if (!inbytes)
|
if (!inbytes)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Just to appease my remorse about unclear loop ends */
|
||||||
|
loop_counter++;
|
||||||
|
if (loop_counter > loop_limit)
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
|
#else
|
||||||
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
#else
|
||||||
iconv_close(conv);
|
iconv_close(conv);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* close the ucs string */
|
/* close the ucs string */
|
||||||
set_ucsbe((uint16_t*) ret, '\0');
|
set_ucsbe((uint16_t*) ret, '\0');
|
||||||
@ -1233,7 +1538,14 @@ char *ucs2str(const char *buf, size_t len)
|
|||||||
{
|
{
|
||||||
size_t outbytes, inbytes;
|
size_t outbytes, inbytes;
|
||||||
char *str, *src, *out;
|
char *str, *src, *out;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
struct iso_iconv_handle conv;
|
||||||
|
int conv_ret;
|
||||||
|
#else
|
||||||
iconv_t conv;
|
iconv_t conv;
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
inbytes = len;
|
inbytes = len;
|
||||||
@ -1250,20 +1562,32 @@ char *ucs2str(const char *buf, size_t len)
|
|||||||
*/
|
*/
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
conv_ret = iso_iconv_open(&conv, iso_get_local_charset(0), "UCS-2BE", 0);
|
||||||
|
if (conv_ret <= 0) {
|
||||||
|
#else
|
||||||
conv = iconv_open(iso_get_local_charset(0), "UCS-2BE");
|
conv = iconv_open(iso_get_local_charset(0), "UCS-2BE");
|
||||||
if (conv == (iconv_t)(-1)) {
|
if (conv == (iconv_t)(-1)) {
|
||||||
|
#endif
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
src = (char *)buf;
|
src = (char *)buf;
|
||||||
str = (char *)out;
|
str = (char *)out;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_iso_iconV
|
||||||
|
n = iso_iconv(&conv, &src, &inbytes, &str, &outbytes, 0);
|
||||||
|
iso_iconv_close(&conv, 0);
|
||||||
|
#else
|
||||||
n = iconv(conv, &src, &inbytes, &str, &outbytes);
|
n = iconv(conv, &src, &inbytes, &str, &outbytes);
|
||||||
|
iconv_close(conv);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
/* error */
|
/* error */
|
||||||
iconv_close(conv);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
iconv_close(conv);
|
|
||||||
*str = '\0';
|
*str = '\0';
|
||||||
|
|
||||||
/* remove trailing spaces */
|
/* remove trailing spaces */
|
||||||
@ -1292,3 +1616,4 @@ int iso_lib_is_compatible(int major, int minor, int micro)
|
|||||||
&& (cminor > minor
|
&& (cminor > minor
|
||||||
|| (cminor == minor && cmicro >= micro)));
|
|| (cminor == minor && cmicro >= micro)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user