[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: ISO9660 & UTF-8



Dear linux-utf8 list,

I'm attaching a patch which complements Jungshik's original patch
( http://mail.nl.linux.org/linux-utf8/2002-03/msg00022.html )
which made mkisofs use iconv instead of internal Unicode conversion
tables.

Jungshik's patch already worked well for 8-bit encodings, but it didn't
account for UTF-8, which is a varying character length encoding. The
attached patch modified joliet_strlen so that it'll return the
correct target UCS-2 length.

Without this patch, UTF-8 filenames containing non-Latin characters
won't work on Windows. They would show in directory listings and be
accessible by 8.3 names, but not by their long filenames. This patch
remedies this problem.

How do we go about merging this into the cdrtools package?

(Please CC me, as I'm not subscribed to this list.)
--- joliet.c.orig	Tue Jan 23 14:28:41 2001
+++ joliet.c	Sun Oct 13 00:19:33 2002
@@ -103,7 +107,7 @@
 
 static void	convert_to_unicode	__PR((unsigned char *buffer,
 		int size, char *source, struct nls_table *inls));
-static int	joliet_strlen		__PR((const char *string));
+static int	joliet_strlen		__PR((const char *string, struct nls_table *inls));
 static void	get_joliet_vol_desc	__PR((struct iso_primary_descriptor *jvol_desc));
 static void	assign_joliet_directory_addresses __PR((struct directory *node));
 static void	build_jpathlist		__PR((struct directory *node));
@@ -272,12 +312,39 @@
  *		codes is available that we can easily adapt.
  */
 static int
-joliet_strlen(string)
+joliet_strlen(string, inls)
 	const char	*string;
+	struct nls_table *inls;
 {
 	int		rtn;
 
+#ifdef USE_ICONV
+       if ( inls->iconv_d && inls->charset2uni==NULL && inls->page_uni2charset==NULL){
+                char tmp[256];
+                /* we const-cast since we're sure iconv won't change the string itself */
+                char *string_ptr = (char*)string;
+                int string_len = strlen(string);
+                
+                rtn = 0;
+
+		/* iconv has no way of finding out the required size in the target
+		   charset, so we have to do a full conversion. */
+		   
+                while (string_len != 0)
+                {
+                   /* We convert to the same buffer, as much as required */
+                   char *tmp_ptr = tmp;
+                   int tmp_len = sizeof(tmp);
+                   if (iconv(inls->iconv_d, &string_ptr, &string_len, &tmp_ptr, &tmp_len) == (size_t)(-1))
+                      break;
+                   /* iconv advanced the tmp pointer with as many chars
+                      as it has written to it, so we add up the delta */
+                   rtn += (tmp_ptr - tmp);
+                }
+       }
+#else
 	rtn = strlen(string) << 1;
+#endif
 
 	/*
 	 * We do clamp the maximum length of a Joliet string to be the
@@ -573,10 +640,10 @@
 		}
 #ifdef APPLE_HYB
 		if (USE_MAC_NAME(de))
-			namelen = joliet_strlen(de->hfs_ent->name);
+			namelen = joliet_strlen(de->hfs_ent->name, hfs_inls);
 		else
 #endif	/* APPLE_HYB */
-			namelen = joliet_strlen(de->name);
+			namelen = joliet_strlen(de->name, in_nls);
 
 		if (dpnt == root) {
 			jpath_table_l[jpath_table_index] = 1;
@@ -729,10 +796,10 @@
 #ifdef APPLE_HYB
 		/* Use the HFS name if it exists */
 		if (USE_MAC_NAME(s_entry1))
-			cvt_len = joliet_strlen(s_entry1->hfs_ent->name);
+			cvt_len = joliet_strlen(s_entry1->hfs_ent->name, hfs_inls);
 		else
 #endif	/* APPLE_HYB */
-			cvt_len = joliet_strlen(s_entry1->name);
+			cvt_len = joliet_strlen(s_entry1->name, in_nls);
 
 		/*
 		 * Fix the record length
@@ -876,12 +943,12 @@
 				if (USE_MAC_NAME(s_entry))
 					/* Use the HFS name if it exists */
 					jpath_table_size +=
-						joliet_strlen(s_entry->hfs_ent->name) +
+						joliet_strlen(s_entry->hfs_ent->name, hfs_inls) +
 						offsetof(struct iso_path_table, name[0]);
 				else
 #endif	/* APPLE_HYB */
 					jpath_table_size +=
-						joliet_strlen(s_entry->name) +
+						joliet_strlen(s_entry->name, in_nls) +
 						offsetof(struct iso_path_table, name[0]);
 				if (jpath_table_size & 1) {
 					jpath_table_size++;
@@ -903,13 +970,13 @@
 				/* Use the HFS name if it exists */
 				s_entry->jreclen =
 				offsetof(struct iso_directory_record, name[0])
-					+ joliet_strlen(s_entry->hfs_ent->name)
+					+ joliet_strlen(s_entry->hfs_ent->name, hfs_inls)
 					+ 1;
 			else
 #endif	/* APPLE_HYB */
 				s_entry->jreclen =
 				offsetof(struct iso_directory_record, name[0])
-					+ joliet_strlen(s_entry->name)
+					+ joliet_strlen(s_entry->name, in_nls)
 					+ 1;
 		} else {
 			/*