160b4ad09SPeter Avalos /*- 2c09f92d2SPeter Avalos * Copyright (c) 2003-2010 Tim Kientzle 360b4ad09SPeter Avalos * All rights reserved. 460b4ad09SPeter Avalos * 560b4ad09SPeter Avalos * Redistribution and use in source and binary forms, with or without 660b4ad09SPeter Avalos * modification, are permitted provided that the following conditions 760b4ad09SPeter Avalos * are met: 860b4ad09SPeter Avalos * 1. Redistributions of source code must retain the above copyright 960b4ad09SPeter Avalos * notice, this list of conditions and the following disclaimer. 1060b4ad09SPeter Avalos * 2. Redistributions in binary form must reproduce the above copyright 1160b4ad09SPeter Avalos * notice, this list of conditions and the following disclaimer in the 1260b4ad09SPeter Avalos * documentation and/or other materials provided with the distribution. 1360b4ad09SPeter Avalos * 1460b4ad09SPeter Avalos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 1560b4ad09SPeter Avalos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1660b4ad09SPeter Avalos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1760b4ad09SPeter Avalos * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 1860b4ad09SPeter Avalos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1960b4ad09SPeter Avalos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2060b4ad09SPeter Avalos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2160b4ad09SPeter Avalos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2260b4ad09SPeter Avalos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2360b4ad09SPeter Avalos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2460b4ad09SPeter Avalos * 259c82a63eSPeter Avalos * $FreeBSD: head/lib/libarchive/archive_string.h 201092 2009-12-28 02:26:06Z kientzle $ 2660b4ad09SPeter Avalos * 2760b4ad09SPeter Avalos */ 2860b4ad09SPeter Avalos 29085658deSDaniel Fojt #ifndef ARCHIVE_STRING_H_INCLUDED 30085658deSDaniel Fojt #define ARCHIVE_STRING_H_INCLUDED 31085658deSDaniel Fojt 329c82a63eSPeter Avalos #ifndef __LIBARCHIVE_BUILD 33c09f92d2SPeter Avalos #ifndef __LIBARCHIVE_TEST 349c82a63eSPeter Avalos #error This header is only to be used internally to libarchive. 359c82a63eSPeter Avalos #endif 36c09f92d2SPeter Avalos #endif 379c82a63eSPeter Avalos 3860b4ad09SPeter Avalos #include <stdarg.h> 3960b4ad09SPeter Avalos #ifdef HAVE_STDLIB_H 4060b4ad09SPeter Avalos #include <stdlib.h> /* required for wchar_t on some systems */ 4160b4ad09SPeter Avalos #endif 4260b4ad09SPeter Avalos #ifdef HAVE_STRING_H 4360b4ad09SPeter Avalos #include <string.h> 4460b4ad09SPeter Avalos #endif 4560b4ad09SPeter Avalos #ifdef HAVE_WCHAR_H 4660b4ad09SPeter Avalos #include <wchar.h> 4760b4ad09SPeter Avalos #endif 4860b4ad09SPeter Avalos 49ce5fd9c5SPeter Avalos #include "archive.h" 50ce5fd9c5SPeter Avalos 5160b4ad09SPeter Avalos /* 52c09f92d2SPeter Avalos * Basic resizable/reusable string support similar to Java's "StringBuffer." 5360b4ad09SPeter Avalos * 5460b4ad09SPeter Avalos * Unlike sbuf(9), the buffers here are fully reusable and track the 5560b4ad09SPeter Avalos * length throughout. 5660b4ad09SPeter Avalos */ 5760b4ad09SPeter Avalos 5860b4ad09SPeter Avalos struct archive_string { 5960b4ad09SPeter Avalos char *s; /* Pointer to the storage */ 60c09f92d2SPeter Avalos size_t length; /* Length of 's' in characters */ 61c09f92d2SPeter Avalos size_t buffer_length; /* Length of malloc-ed storage in bytes. */ 6260b4ad09SPeter Avalos }; 6360b4ad09SPeter Avalos 64c09f92d2SPeter Avalos struct archive_wstring { 65c09f92d2SPeter Avalos wchar_t *s; /* Pointer to the storage */ 66c09f92d2SPeter Avalos size_t length; /* Length of 's' in characters */ 67c09f92d2SPeter Avalos size_t buffer_length; /* Length of malloc-ed storage in bytes. */ 68c09f92d2SPeter Avalos }; 69c09f92d2SPeter Avalos 70c09f92d2SPeter Avalos struct archive_string_conv; 71c09f92d2SPeter Avalos 7260b4ad09SPeter Avalos /* Initialize an archive_string object on the stack or elsewhere. */ 7360b4ad09SPeter Avalos #define archive_string_init(a) \ 7460b4ad09SPeter Avalos do { (a)->s = NULL; (a)->length = 0; (a)->buffer_length = 0; } while(0) 7560b4ad09SPeter Avalos 7660b4ad09SPeter Avalos /* Append a C char to an archive_string, resizing as necessary. */ 7760b4ad09SPeter Avalos struct archive_string * 78c09f92d2SPeter Avalos archive_strappend_char(struct archive_string *, char); 7960b4ad09SPeter Avalos 80c09f92d2SPeter Avalos /* Ditto for a wchar_t and an archive_wstring. */ 81c09f92d2SPeter Avalos struct archive_wstring * 82c09f92d2SPeter Avalos archive_wstrappend_wchar(struct archive_wstring *, wchar_t); 8360b4ad09SPeter Avalos 84e95abc47Szrj /* Append a raw array to an archive_string, resizing as necessary */ 85e95abc47Szrj struct archive_string * 86e95abc47Szrj archive_array_append(struct archive_string *, const char *, size_t); 87e95abc47Szrj 88c09f92d2SPeter Avalos /* Convert a Unicode string to current locale and append the result. */ 89c09f92d2SPeter Avalos /* Returns -1 if conversion fails. */ 90c09f92d2SPeter Avalos int 91c09f92d2SPeter Avalos archive_string_append_from_wcs(struct archive_string *, const wchar_t *, size_t); 9260b4ad09SPeter Avalos 93c09f92d2SPeter Avalos 94c09f92d2SPeter Avalos /* Create a string conversion object. 95c09f92d2SPeter Avalos * Return NULL and set a error message if the conversion is not supported 96c09f92d2SPeter Avalos * on the platform. */ 97c09f92d2SPeter Avalos struct archive_string_conv * 98c09f92d2SPeter Avalos archive_string_conversion_to_charset(struct archive *, const char *, int); 99c09f92d2SPeter Avalos struct archive_string_conv * 100c09f92d2SPeter Avalos archive_string_conversion_from_charset(struct archive *, const char *, int); 101c09f92d2SPeter Avalos /* Create the default string conversion object for reading/writing an archive. 102c09f92d2SPeter Avalos * Return NULL if the conversion is unneeded. 103c09f92d2SPeter Avalos * Note: On non Windows platform this always returns NULL. 104c09f92d2SPeter Avalos */ 105c09f92d2SPeter Avalos struct archive_string_conv * 106c09f92d2SPeter Avalos archive_string_default_conversion_for_read(struct archive *); 107c09f92d2SPeter Avalos struct archive_string_conv * 108c09f92d2SPeter Avalos archive_string_default_conversion_for_write(struct archive *); 109c09f92d2SPeter Avalos /* Dispose of a string conversion object. */ 110c09f92d2SPeter Avalos void 111c09f92d2SPeter Avalos archive_string_conversion_free(struct archive *); 112c09f92d2SPeter Avalos const char * 113c09f92d2SPeter Avalos archive_string_conversion_charset_name(struct archive_string_conv *); 114c09f92d2SPeter Avalos void 115c09f92d2SPeter Avalos archive_string_conversion_set_opt(struct archive_string_conv *, int); 116c09f92d2SPeter Avalos #define SCONV_SET_OPT_UTF8_LIBARCHIVE2X 1 11759bf7050SPeter Avalos #define SCONV_SET_OPT_NORMALIZATION_C 2 11859bf7050SPeter Avalos #define SCONV_SET_OPT_NORMALIZATION_D 4 119c09f92d2SPeter Avalos 120c09f92d2SPeter Avalos 121c09f92d2SPeter Avalos /* Copy one archive_string to another in locale conversion. 122e95abc47Szrj * Return -1 if conversion fails. */ 123c09f92d2SPeter Avalos int 12459bf7050SPeter Avalos archive_strncpy_l(struct archive_string *, const void *, size_t, 125c09f92d2SPeter Avalos struct archive_string_conv *); 126c09f92d2SPeter Avalos 127c09f92d2SPeter Avalos /* Copy one archive_string to another in locale conversion. 128e95abc47Szrj * Return -1 if conversion fails. */ 129c09f92d2SPeter Avalos int 13059bf7050SPeter Avalos archive_strncat_l(struct archive_string *, const void *, size_t, 131c09f92d2SPeter Avalos struct archive_string_conv *); 132c09f92d2SPeter Avalos 13360b4ad09SPeter Avalos 13460b4ad09SPeter Avalos /* Copy one archive_string to another */ 13560b4ad09SPeter Avalos #define archive_string_copy(dest, src) \ 136c09f92d2SPeter Avalos ((dest)->length = 0, archive_string_concat((dest), (src))) 137c09f92d2SPeter Avalos #define archive_wstring_copy(dest, src) \ 138c09f92d2SPeter Avalos ((dest)->length = 0, archive_wstring_concat((dest), (src))) 13960b4ad09SPeter Avalos 1408029ab02SPeter Avalos /* Concatenate one archive_string to another */ 141c09f92d2SPeter Avalos void archive_string_concat(struct archive_string *dest, struct archive_string *src); 142c09f92d2SPeter Avalos void archive_wstring_concat(struct archive_wstring *dest, struct archive_wstring *src); 1438029ab02SPeter Avalos 14460b4ad09SPeter Avalos /* Ensure that the underlying buffer is at least as large as the request. */ 14560b4ad09SPeter Avalos struct archive_string * 146c09f92d2SPeter Avalos archive_string_ensure(struct archive_string *, size_t); 147c09f92d2SPeter Avalos struct archive_wstring * 148c09f92d2SPeter Avalos archive_wstring_ensure(struct archive_wstring *, size_t); 14960b4ad09SPeter Avalos 15060b4ad09SPeter Avalos /* Append C string, which may lack trailing \0. */ 1518029ab02SPeter Avalos /* The source is declared void * here because this gets used with 1528029ab02SPeter Avalos * "signed char *", "unsigned char *" and "char *" arguments. 1538029ab02SPeter Avalos * Declaring it "char *" as with some of the other functions just 1548029ab02SPeter Avalos * leads to a lot of extra casts. */ 15560b4ad09SPeter Avalos struct archive_string * 156c09f92d2SPeter Avalos archive_strncat(struct archive_string *, const void *, size_t); 157c09f92d2SPeter Avalos struct archive_wstring * 158c09f92d2SPeter Avalos archive_wstrncat(struct archive_wstring *, const wchar_t *, size_t); 15960b4ad09SPeter Avalos 16060b4ad09SPeter Avalos /* Append a C string to an archive_string, resizing as necessary. */ 161c09f92d2SPeter Avalos struct archive_string * 162c09f92d2SPeter Avalos archive_strcat(struct archive_string *, const void *); 163c09f92d2SPeter Avalos struct archive_wstring * 164c09f92d2SPeter Avalos archive_wstrcat(struct archive_wstring *, const wchar_t *); 16560b4ad09SPeter Avalos 16660b4ad09SPeter Avalos /* Copy a C string to an archive_string, resizing as necessary. */ 16760b4ad09SPeter Avalos #define archive_strcpy(as,p) \ 168c09f92d2SPeter Avalos archive_strncpy((as), (p), ((p) == NULL ? 0 : strlen(p))) 169c09f92d2SPeter Avalos #define archive_wstrcpy(as,p) \ 170c09f92d2SPeter Avalos archive_wstrncpy((as), (p), ((p) == NULL ? 0 : wcslen(p))) 17159bf7050SPeter Avalos #define archive_strcpy_l(as,p,lo) \ 17259bf7050SPeter Avalos archive_strncpy_l((as), (p), ((p) == NULL ? 0 : strlen(p)), (lo)) 17360b4ad09SPeter Avalos 17460b4ad09SPeter Avalos /* Copy a C string to an archive_string with limit, resizing as necessary. */ 17560b4ad09SPeter Avalos #define archive_strncpy(as,p,l) \ 17660b4ad09SPeter Avalos ((as)->length=0, archive_strncat((as), (p), (l))) 177c09f92d2SPeter Avalos #define archive_wstrncpy(as,p,l) \ 178c09f92d2SPeter Avalos ((as)->length = 0, archive_wstrncat((as), (p), (l))) 17960b4ad09SPeter Avalos 18060b4ad09SPeter Avalos /* Return length of string. */ 18160b4ad09SPeter Avalos #define archive_strlen(a) ((a)->length) 18260b4ad09SPeter Avalos 18360b4ad09SPeter Avalos /* Set string length to zero. */ 18460b4ad09SPeter Avalos #define archive_string_empty(a) ((a)->length = 0) 185c09f92d2SPeter Avalos #define archive_wstring_empty(a) ((a)->length = 0) 18660b4ad09SPeter Avalos 18760b4ad09SPeter Avalos /* Release any allocated storage resources. */ 188c09f92d2SPeter Avalos void archive_string_free(struct archive_string *); 189c09f92d2SPeter Avalos void archive_wstring_free(struct archive_wstring *); 19060b4ad09SPeter Avalos 19160b4ad09SPeter Avalos /* Like 'vsprintf', but resizes the underlying string as necessary. */ 192c09f92d2SPeter Avalos /* Note: This only implements a small subset of standard printf functionality. */ 193c09f92d2SPeter Avalos void archive_string_vsprintf(struct archive_string *, const char *, 194ce5fd9c5SPeter Avalos va_list) __LA_PRINTF(2, 0); 195c09f92d2SPeter Avalos void archive_string_sprintf(struct archive_string *, const char *, ...) 196ce5fd9c5SPeter Avalos __LA_PRINTF(2, 3); 19760b4ad09SPeter Avalos 198c09f92d2SPeter Avalos /* Translates from MBS to Unicode. */ 199c09f92d2SPeter Avalos /* Returns non-zero if conversion failed in any way. */ 200c09f92d2SPeter Avalos int archive_wstring_append_from_mbs(struct archive_wstring *dest, 201c09f92d2SPeter Avalos const char *, size_t); 202c09f92d2SPeter Avalos 203c09f92d2SPeter Avalos 204c09f92d2SPeter Avalos /* A "multistring" can hold Unicode, UTF8, or MBS versions of 205c09f92d2SPeter Avalos * the string. If you set and read the same version, no translation 206c09f92d2SPeter Avalos * is done. If you set and read different versions, the library 207c09f92d2SPeter Avalos * will attempt to transparently convert. 208c09f92d2SPeter Avalos */ 209c09f92d2SPeter Avalos struct archive_mstring { 210c09f92d2SPeter Avalos struct archive_string aes_mbs; 211c09f92d2SPeter Avalos struct archive_string aes_utf8; 212c09f92d2SPeter Avalos struct archive_wstring aes_wcs; 213c09f92d2SPeter Avalos struct archive_string aes_mbs_in_locale; 214c09f92d2SPeter Avalos /* Bitmap of which of the above are valid. Because we're lazy 215c09f92d2SPeter Avalos * about malloc-ing and reusing the underlying storage, we 216c09f92d2SPeter Avalos * can't rely on NULL pointers to indicate whether a string 217c09f92d2SPeter Avalos * has been set. */ 218c09f92d2SPeter Avalos int aes_set; 219c09f92d2SPeter Avalos #define AES_SET_MBS 1 220c09f92d2SPeter Avalos #define AES_SET_UTF8 2 221c09f92d2SPeter Avalos #define AES_SET_WCS 4 222c09f92d2SPeter Avalos }; 223c09f92d2SPeter Avalos 224c09f92d2SPeter Avalos void archive_mstring_clean(struct archive_mstring *); 225c09f92d2SPeter Avalos void archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src); 226c09f92d2SPeter Avalos int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **); 227c09f92d2SPeter Avalos int archive_mstring_get_utf8(struct archive *, struct archive_mstring *, const char **); 228c09f92d2SPeter Avalos int archive_mstring_get_wcs(struct archive *, struct archive_mstring *, const wchar_t **); 229*50f8aa9cSAntonio Huete Jimenez int archive_mstring_get_mbs_l(struct archive *, struct archive_mstring *, const char **, 230c09f92d2SPeter Avalos size_t *, struct archive_string_conv *); 231c09f92d2SPeter Avalos int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs); 232c09f92d2SPeter Avalos int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs, 233c09f92d2SPeter Avalos size_t); 234c09f92d2SPeter Avalos int archive_mstring_copy_utf8(struct archive_mstring *, const char *utf8); 235c09f92d2SPeter Avalos int archive_mstring_copy_wcs(struct archive_mstring *, const wchar_t *wcs); 236c09f92d2SPeter Avalos int archive_mstring_copy_wcs_len(struct archive_mstring *, 237c09f92d2SPeter Avalos const wchar_t *wcs, size_t); 238c09f92d2SPeter Avalos int archive_mstring_copy_mbs_len_l(struct archive_mstring *, 239c09f92d2SPeter Avalos const char *mbs, size_t, struct archive_string_conv *); 240c09f92d2SPeter Avalos int archive_mstring_update_utf8(struct archive *, struct archive_mstring *aes, const char *utf8); 24160b4ad09SPeter Avalos 24260b4ad09SPeter Avalos 24360b4ad09SPeter Avalos #endif 244