Archive-Unzip-Burst
view release on metacpan or search on metacpan
unzip-6.0/process.c view on Meta::CPAN
On return, G.unipath_filename =
NULL, if no Unicode path extra field or error
"", if the standard path is UTF-8 (free when done)
null-terminated UTF-8 path (free when done)
Return PK_COOL if no error.
---------------------------------------------------------------------------*/
G.unipath_filename = NULL;
if (ef_len == 0 || ef_buf == NULL)
return PK_COOL;
Trace((stderr,"\ngetUnicodeData: scanning extra field of length %u\n",
ef_len));
while (ef_len >= EB_HEADSIZE) {
eb_id = makeword(EB_ID + ef_buf);
eb_len = makeword(EB_LEN + ef_buf);
if (eb_len > (ef_len - EB_HEADSIZE)) {
/* discovered some extra field inconsistency! */
Trace((stderr,
"getUnicodeData: block length %u > rest ef_size %u\n", eb_len,
ef_len - EB_HEADSIZE));
break;
}
if (eb_id == EF_UNIPATH) {
int offset = EB_HEADSIZE;
ush ULen = eb_len - 5;
ulg chksum = CRCVAL_INITIAL;
/* version */
G.unipath_version = (uch) *(offset + ef_buf);
offset += 1;
if (G.unipath_version > 1) {
/* can do only version 1 */
Info(slide, 0x401, ((char *)slide,
LoadFarString(UnicodeVersionError)));
return PK_ERR;
}
/* filename CRC */
G.unipath_checksum = makelong(offset + ef_buf);
offset += 4;
/*
* Compute 32-bit crc
*/
chksum = crc32(chksum, (uch *)(G.filename_full),
strlen(G.filename_full));
/* If the checksums's don't match then likely filename has been
* modified and the Unicode Path is no longer valid.
*/
if (chksum != G.unipath_checksum) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(UnicodeMismatchError)));
if (G.unicode_mismatch == 1) {
/* warn and continue */
} else if (G.unicode_mismatch == 2) {
/* ignore and continue */
} else if (G.unicode_mismatch == 0) {
}
return PK_ERR;
}
/* UTF-8 Path */
if ((G.unipath_filename = malloc(ULen + 1)) == NULL) {
return PK_ERR;
}
if (ULen == 0) {
/* standard path is UTF-8 so use that */
G.unipath_filename[0] = '\0';
} else {
/* UTF-8 path */
strncpy(G.unipath_filename,
(ZCONST char *)(offset + ef_buf), ULen);
G.unipath_filename[ULen] = '\0';
}
}
/* Skip this extra field block */
ef_buf += (eb_len + EB_HEADSIZE);
ef_len -= (eb_len + EB_HEADSIZE);
}
return PK_COOL;
} /* end function getUnicodeData() */
#ifdef UNICODE_WCHAR
/*---------------------------------------------
* Unicode conversion functions
*
* Based on functions provided by Paul Kienitz
*
*---------------------------------------------
*/
/*
NOTES APPLICABLE TO ALL STRING FUNCTIONS:
All of the x_to_y functions take parameters for an output buffer and
its available length, and return an int. The value returned is the
length of the string that the input produces, which may be larger than
the provided buffer length. If the returned value is less than the
buffer length, then the contents of the buffer will be null-terminated;
otherwise, it will not be terminated and may be invalid, possibly
stopping in the middle of a multibyte sequence.
In all cases you may pass NULL as the buffer and/or 0 as the length, if
you just want to learn how much space the string is going to require.
The functions will return -1 if the input is invalid UTF-8 or cannot be
encoded as UTF-8.
*/
static int utf8_char_bytes OF((ZCONST char *utf8));
static ulg ucs4_char_from_utf8 OF((ZCONST char **utf8));
static int utf8_to_ucs4_string OF((ZCONST char *utf8, ulg *ucs4buf,
unzip-6.0/process.c view on Meta::CPAN
ZCONST char *utf8;
ulg *ucs4buf;
int buflen;
{
int count = 0;
for (;;)
{
ulg ch = ucs4_char_from_utf8(&utf8);
if (ch == ~0L)
return -1;
else
{
if (ucs4buf && count < buflen)
ucs4buf[count] = ch;
if (ch == 0)
return count;
count++;
}
}
}
#if 0 /* currently unused */
/* ucs4_string_to_utf8
*
*
*/
static int ucs4_string_to_utf8(ucs4, utf8buf, buflen)
ZCONST ulg *ucs4;
char *utf8buf;
int buflen;
{
char mb[6];
int count = 0;
if (!ucs4)
return -1;
for (;;)
{
int mbl = utf8_from_ucs4_char(mb, *ucs4++);
int c;
if (mbl <= 0)
return -1;
/* We could optimize this a bit by passing utf8buf + count */
/* directly to utf8_from_ucs4_char when buflen >= count + 6... */
c = buflen - count;
if (mbl < c)
c = mbl;
if (utf8buf && count < buflen)
strncpy(utf8buf + count, mb, c);
if (mbl == 1 && !mb[0])
return count; /* terminating nul */
count += mbl;
}
}
/* utf8_chars
*
* Wrapper: counts the actual unicode characters in a UTF-8 string.
*/
static int utf8_chars(utf8)
ZCONST char *utf8;
{
return utf8_to_ucs4_string(utf8, NULL, 0);
}
#endif /* unused */
/* --------------------------------------------------- */
/* Unicode Support
*
* These functions common for all Unicode ports.
*
* These functions should allocate and return strings that can be
* freed with free().
*
* 8/27/05 EG
*
* Use zwchar for wide char which is unsigned long
* in zip.h and 32 bits. This avoids problems with
* different sizes of wchar_t.
*/
#if 0 /* currently unused */
/* is_ascii_string
* Checks if a string is all ascii
*/
int is_ascii_string(mbstring)
ZCONST char *mbstring;
{
char *p;
uch c;
for (p = mbstring; c = (uch)*p; p++) {
if (c > 0x7F) {
return 0;
}
}
return 1;
}
/* local to UTF-8 */
char *local_to_utf8_string(local_string)
ZCONST char *local_string;
{
return wide_to_utf8_string(local_to_wide_string(local_string));
}
# endif /* unused */
/* wide_to_escape_string
provides a string that represents a wide char not in local char set
An initial try at an algorithm. Suggestions welcome.
According to the standard, Unicode character points are restricted to
the number range from 0 to 0x10FFFF, respective 21 bits.
For a hexadecimal notation, 2 octets are sufficient for the mostly
used characters from the "Basic Multilingual Plane", all other
Unicode characters can be represented by 3 octets (= 6 hex digits).
The Unicode standard suggests to write Unicode character points
( run in 0.997 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )