[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Libcdio-devel] modifications of ISO9660 and UDF headers for MSVC
From: |
Pete Batard |
Subject: |
[Libcdio-devel] modifications of ISO9660 and UDF headers for MSVC |
Date: |
Sun, 29 Jan 2012 17:39:30 +0000 |
User-agent: |
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0) Gecko/20111222 Thunderbird/9.0.1 |
Two additional patches that modify the ISO9660 and UDF headers for MSVC
usage.
The most controversial has to be the ISO9660 as MSVC simply cannot use a
zero sized array, even at the end of a struct, if that struct is going
to be included in the middle of another.
Therefore, instead of defining:
iso711_t filename_len;
char filename[];
We leverage the fact that iso711_t and char are the same size and the
following union:
union {
iso711_t len;
char str[1];
} filename;
This avoids the use of an empty array, while most of the existing code
unchanged. The only gotcha however is that the actual string payload of
filename.str[] starts at 1, not 0.
I'm hoping this is acceptable as a workaround, as dealing with zero
sized arrays is the one item we cannot avoid for MSVC support.
I guess these can be construed as API change, so probably warrant an API
bump.
Regards,
/Pete
>From c40dd3269e049611cc1f53e01b1d0bec0fb50957 Mon Sep 17 00:00:00 2001
From: Pete Batard <address@hidden>
Date: Sun, 29 Jan 2012 17:15:50 +0000
Subject: [PATCH 1/3] ISO9660: fix iso9660.h header for MSVC compatibility
* MSVC compilers cannot handle a zero sized array in the middle
of a struct, and iso9660_dir_s is reused within iso9660_pvd_s.
* Leverage the fact that iso711_t and char are the same size and
use an union.
* The only gotcha is that the actual string payload now starts at 1
* also fix the use of pre_user_data as MSVC cannot use a const to
initialize the size of an array
---
include/cdio/iso9660.h | 14 ++++++++++++--
lib/iso9660/iso9660.c | 4 ++--
lib/iso9660/iso9660_fs.c | 26 ++++++++++++--------------
lib/iso9660/rock.c | 8 ++++----
4 files changed, 30 insertions(+), 22 deletions(-)
diff --git a/include/cdio/iso9660.h b/include/cdio/iso9660.h
index 4f5786f..c6ddf64 100644
--- a/include/cdio/iso9660.h
+++ b/include/cdio/iso9660.h
@@ -273,8 +273,18 @@ struct iso9660_dir_s {
the Extent described by this
Directory Record is
recorded. (9.1.9) */
- iso711_t filename_len; /*! number of bytes in filename field */
- char filename[EMPTY_ARRAY_SIZE];
+/*! MSVC compilers cannot handle a zero sized array in the middle
+ of a struct, and iso9660_dir_s is reused within iso9660_pvd_s.
+ Therefore, instead of defining:
+ iso711_t filename_len;
+ char filename[];
+ we leverage the fact that iso711_t and char are the same size
+ and use an union. The only gotcha is that the actual string
+ payload of filename.str[] starts at 1, not 0. */
+ union {
+ iso711_t len;
+ char str[1];
+ } filename;
} GNUC_PACKED;
/*!
diff --git a/lib/iso9660/iso9660.c b/lib/iso9660/iso9660.c
index e06ebad..6edd7bd 100644
--- a/lib/iso9660/iso9660.c
+++ b/lib/iso9660/iso9660.c
@@ -771,10 +771,10 @@ iso9660_dir_add_entry_su(void *dir,
idr->volume_sequence_number = to_723(1);
- idr->filename_len = to_711(strlen(filename)
+ idr->filename.len = to_711(strlen(filename)
? strlen(filename) : 1); /* working hack! */
- memcpy(idr->filename, filename, from_711(idr->filename_len));
+ memcpy(&idr->filename.str[1], filename, from_711(idr->filename.len));
memcpy(&dir8[offset] + su_offset, su_data, su_size);
}
diff --git a/lib/iso9660/iso9660_fs.c b/lib/iso9660/iso9660_fs.c
index ff62077..61f8560 100644
--- a/lib/iso9660/iso9660_fs.c
+++ b/lib/iso9660/iso9660_fs.c
@@ -107,12 +107,10 @@ adjust_fuzzy_pvd( iso9660_t *p_iso )
frame and a header.
*/
if (CDIO_CD_FRAMESIZE_RAW == p_iso->i_framesize) {
- const int pre_user_data=CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE
- + CDIO_CD_SUBHEADER_SIZE;
- char buf[pre_user_data];
-
- i_byte_offset -= pre_user_data;
-
+ char buf[CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE + CDIO_CD_SUBHEADER_SIZE];
+
+ i_byte_offset -= CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE +
CDIO_CD_SUBHEADER_SIZE;
+
if ( DRIVER_OP_SUCCESS != cdio_stream_seek (p_iso->stream, i_byte_offset,
SEEK_SET) )
return;
@@ -739,7 +737,7 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
bool_3way_t b_xa,
if (!dir_len) return NULL;
- i_fname = from_711(p_iso9660_dir->filename_len);
+ i_fname = from_711(p_iso9660_dir->filename.len);
/* .. string in statbuf is one longer than in p_iso9660_dir's listing '\1' */
stat_len = sizeof(iso9660_stat_t)+i_fname+2;
@@ -784,15 +782,15 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
bool_3way_t b_xa,
}
strncpy(p_stat->filename, rr_fname, i_rr_fname+1);
} else {
- if ('\0' == p_iso9660_dir->filename[0] && 1 == i_fname)
+ if ('\0' == p_iso9660_dir->filename.str[1] && 1 == i_fname)
strncpy (p_stat->filename, ".", sizeof("."));
- else if ('\1' == p_iso9660_dir->filename[0] && 1 == i_fname)
+ else if ('\1' == p_iso9660_dir->filename.str[1] && 1 == i_fname)
strncpy (p_stat->filename, "..", sizeof(".."));
#ifdef HAVE_JOLIET
else if (i_joliet_level) {
int i_inlen = i_fname;
cdio_utf8_t *p_psz_out = NULL;
- if (cdio_charset_to_utf8(p_iso9660_dir->filename, i_inlen,
+ if (cdio_charset_to_utf8(&p_iso9660_dir->filename.str[1], i_inlen,
&p_psz_out, "UCS-2BE")) {
strncpy(p_stat->filename, p_psz_out, i_fname);
free(p_psz_out);
@@ -804,7 +802,7 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir,
bool_3way_t b_xa,
}
#endif /*HAVE_JOLIET*/
else {
- strncpy (p_stat->filename, p_iso9660_dir->filename, i_fname);
+ strncpy (p_stat->filename, &p_iso9660_dir->filename.str[1], i_fname);
}
}
}
@@ -878,12 +876,12 @@ iso9660_dir_to_name (const iso9660_dir_t *iso9660_dir)
/* (iso9660_dir->file_flags & ISO_DIRECTORY) */
- if (iso9660_dir->filename[0] == '\0')
+ if (iso9660_dir->filename.str[1] == '\0')
return strdup(".");
- else if (iso9660_dir->filename[0] == '\1')
+ else if (iso9660_dir->filename.str[1] == '\1')
return strdup("..");
else {
- return strdup(iso9660_dir->filename);
+ return strdup(&iso9660_dir->filename.str[1]);
}
}
diff --git a/lib/iso9660/rock.c b/lib/iso9660/rock.c
index 1a91297..1a887c3 100644
--- a/lib/iso9660/rock.c
+++ b/lib/iso9660/rock.c
@@ -105,7 +105,7 @@ realloc_symlink(/*in/out*/ iso9660_stat_t *p_stat, uint8_t
i_grow)
#define SETUP_ROCK_RIDGE(DE,CHR,LEN) \
{ \
- LEN= sizeof(iso9660_dir_t) + DE->filename_len; \
+ LEN= sizeof(iso9660_dir_t) + DE->filename.len; \
if(LEN & 1) LEN++; \
CHR = ((unsigned char *) DE) + LEN; \
LEN = *((unsigned char *) DE) - LEN; \
@@ -178,10 +178,10 @@ get_rock_ridge_filename(iso9660_dir_t * p_iso9660_dir,
break;
case SIG('C','E'):
{
- iso711_t i_fname = from_711(p_iso9660_dir->filename_len);
- if ('\0' == p_iso9660_dir->filename[0] && 1 == i_fname)
+ iso711_t i_fname = from_711(p_iso9660_dir->filename.len);
+ if ('\0' == p_iso9660_dir->filename.str[1] && 1 == i_fname)
break;
- if ('\1' == p_iso9660_dir->filename[0] && 1 == i_fname)
+ if ('\1' == p_iso9660_dir->filename.str[1] && 1 == i_fname)
break;
}
CHECK_CE;
--
1.7.8.msysgit.0
>From 2d92744537978446cea3cd4bfe4ae583c3747995 Mon Sep 17 00:00:00 2001
From: Pete Batard <address@hidden>
Date: Sun, 29 Jan 2012 17:21:08 +0000
Subject: [PATCH 2/3] UDF: fix ecma_167.h header for MSVC compatibility
* multiple zero sized arrays are not allowed with MSVC
* use an union of zero sized arrays instead
---
include/cdio/ecma_167.h | 22 ++++++++++++++--------
lib/udf/udf_fs.c | 2 +-
2 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/include/cdio/ecma_167.h b/include/cdio/ecma_167.h
index 9c7c1bb..b97cba7 100644
--- a/include/cdio/ecma_167.h
+++ b/include/cdio/ecma_167.h
@@ -499,9 +499,11 @@ struct logvol_integrity_desc_s
udf_Uint8_t logvol_contents_use[32];
udf_Uint32_t i_partitions;
udf_Uint32_t imp_use_len;
- udf_Uint32_t freespace_table[0];
- udf_Uint32_t size_table[0];
- udf_Uint8_t imp_use[0];
+ union { /* MSVC workaround for multiple zero sized arrays */
+ udf_Uint32_t freespace_table[0];
+ udf_Uint32_t size_table[0];
+ udf_Uint8_t imp_use[0];
+ } u;
} GNUC_PACKED;
/** Integrity Type (ECMA 167r3 3/10.10.3) */
@@ -571,9 +573,11 @@ struct udf_fileid_desc_s
udf_Uint8_t i_file_id;
udf_long_ad_t icb;
udf_Uint16_t i_imp_use;
- udf_Uint8_t imp_use[0];
- udf_Uint8_t file_id[0];
- udf_Uint8_t padding[0];
+ union { /* MSVC workaround for multiple zero sized arrays */
+ udf_Uint8_t imp_use[0];
+ udf_Uint8_t file_id[0];
+ udf_Uint8_t padding[0];
+ } u;
} GNUC_PACKED;
typedef struct udf_fileid_desc_s udf_fileid_desc_t;
@@ -991,8 +995,10 @@ struct extended_file_entry
udf_Uint64_t unique_ID;
udf_Uint32_t length_extended_attr;
udf_Uint32_t length_alloc_descs;
- udf_Uint8_t ext_attr[0];
- udf_Uint8_t alloc_descs[0];
+ union { /* MSVC workaround for multiple zero sized arrays */
+ udf_Uint8_t ext_attr[0];
+ udf_Uint8_t alloc_descs[0];
+ } u;
} GNUC_PACKED;
PRAGMA_END_PACKED
diff --git a/lib/udf/udf_fs.c b/lib/udf/udf_fs.c
index 1669bc2..d99c9a4 100644
--- a/lib/udf/udf_fs.c
+++ b/lib/udf/udf_fs.c
@@ -681,7 +681,7 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
p_udf_dirent->psz_name = (char *)
realloc(p_udf_dirent->psz_name, sizeof(char)*i_len+1);
- unicode16_decode(p_udf_dirent->fid->imp_use
+ unicode16_decode(p_udf_dirent->fid->u.imp_use
+ p_udf_dirent->fid->i_imp_use,
i_len, p_udf_dirent->psz_name);
}
--
1.7.8.msysgit.0
- [Libcdio-devel] modifications of ISO9660 and UDF headers for MSVC,
Pete Batard <=