xref: /freebsd/contrib/libarchive/libarchive/archive_string.h (revision b9128a37faafede823eb456aa65a11ac69997284)
1  /*-
2   * Copyright (c) 2003-2010 Tim Kientzle
3   * All rights reserved.
4   *
5   * Redistribution and use in source and binary forms, with or without
6   * modification, are permitted provided that the following conditions
7   * are met:
8   * 1. Redistributions of source code must retain the above copyright
9   *    notice, this list of conditions and the following disclaimer.
10   * 2. Redistributions in binary form must reproduce the above copyright
11   *    notice, this list of conditions and the following disclaimer in the
12   *    documentation and/or other materials provided with the distribution.
13   *
14   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17   * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24   */
25  
26  #ifndef ARCHIVE_STRING_H_INCLUDED
27  #define ARCHIVE_STRING_H_INCLUDED
28  
29  #ifndef __LIBARCHIVE_BUILD
30  #ifndef __LIBARCHIVE_TEST
31  #error This header is only to be used internally to libarchive.
32  #endif
33  #endif
34  
35  #include <stdarg.h>
36  #ifdef HAVE_STDLIB_H
37  #include <stdlib.h>  /* required for wchar_t on some systems */
38  #endif
39  #ifdef HAVE_STRING_H
40  #include <string.h>
41  #endif
42  #ifdef HAVE_WCHAR_H
43  #include <wchar.h>
44  #endif
45  
46  #include "archive.h"
47  
48  /*
49   * Basic resizable/reusable string support similar to Java's "StringBuffer."
50   *
51   * Unlike sbuf(9), the buffers here are fully reusable and track the
52   * length throughout.
53   */
54  
55  struct archive_string {
56  	char	*s;  /* Pointer to the storage */
57  	size_t	 length; /* Length of 's' in characters */
58  	size_t	 buffer_length; /* Length of malloc-ed storage in bytes. */
59  };
60  
61  struct archive_wstring {
62  	wchar_t	*s;  /* Pointer to the storage */
63  	size_t	 length; /* Length of 's' in characters */
64  	size_t	 buffer_length; /* Length of malloc-ed storage in bytes. */
65  };
66  
67  struct archive_string_conv;
68  
69  /* Initialize an archive_string object on the stack or elsewhere. */
70  #define	archive_string_init(a)	\
71  	do { (a)->s = NULL; (a)->length = 0; (a)->buffer_length = 0; } while(0)
72  
73  /* Append a C char to an archive_string, resizing as necessary. */
74  struct archive_string *
75  archive_strappend_char(struct archive_string *, char);
76  
77  /* Ditto for a wchar_t and an archive_wstring. */
78  struct archive_wstring *
79  archive_wstrappend_wchar(struct archive_wstring *, wchar_t);
80  
81  /* Append a raw array to an archive_string, resizing as necessary */
82  struct archive_string *
83  archive_array_append(struct archive_string *, const char *, size_t);
84  
85  /* Convert a Unicode string to current locale and append the result. */
86  /* Returns -1 if conversion fails. */
87  int
88  archive_string_append_from_wcs(struct archive_string *, const wchar_t *, size_t);
89  
90  
91  /* Create a string conversion object.
92   * Return NULL and set a error message if the conversion is not supported
93   * on the platform. */
94  struct archive_string_conv *
95  archive_string_conversion_to_charset(struct archive *, const char *, int);
96  struct archive_string_conv *
97  archive_string_conversion_from_charset(struct archive *, const char *, int);
98  /* Create the default string conversion object for reading/writing an archive.
99   * Return NULL if the conversion is unneeded.
100   * Note: On non Windows platform this always returns NULL.
101   */
102  struct archive_string_conv *
103  archive_string_default_conversion_for_read(struct archive *);
104  struct archive_string_conv *
105  archive_string_default_conversion_for_write(struct archive *);
106  /* Dispose of a string conversion object. */
107  void
108  archive_string_conversion_free(struct archive *);
109  const char *
110  archive_string_conversion_charset_name(struct archive_string_conv *);
111  void
112  archive_string_conversion_set_opt(struct archive_string_conv *, int);
113  #define SCONV_SET_OPT_UTF8_LIBARCHIVE2X	1
114  #define SCONV_SET_OPT_NORMALIZATION_C	2
115  #define SCONV_SET_OPT_NORMALIZATION_D	4
116  
117  
118  /* Copy one archive_string to another in locale conversion.
119   * Return -1 if conversion fails. */
120  int
121  archive_strncpy_l(struct archive_string *, const void *, size_t,
122      struct archive_string_conv *);
123  
124  /* Copy one archive_string to another in locale conversion.
125   * Return -1 if conversion fails. */
126  int
127  archive_strncat_l(struct archive_string *, const void *, size_t,
128      struct archive_string_conv *);
129  
130  
131  /* Copy one archive_string to another */
132  #define	archive_string_copy(dest, src) \
133  	((dest)->length = 0, archive_string_concat((dest), (src)))
134  #define	archive_wstring_copy(dest, src) \
135  	((dest)->length = 0, archive_wstring_concat((dest), (src)))
136  
137  /* Concatenate one archive_string to another */
138  void archive_string_concat(struct archive_string *dest, struct archive_string *src);
139  void archive_wstring_concat(struct archive_wstring *dest, struct archive_wstring *src);
140  
141  /* Ensure that the underlying buffer is at least as large as the request. */
142  struct archive_string *
143  archive_string_ensure(struct archive_string *, size_t);
144  struct archive_wstring *
145  archive_wstring_ensure(struct archive_wstring *, size_t);
146  
147  /* Append C string, which may lack trailing \0. */
148  /* The source is declared void * here because this gets used with
149   * "signed char *", "unsigned char *" and "char *" arguments.
150   * Declaring it "char *" as with some of the other functions just
151   * leads to a lot of extra casts. */
152  struct archive_string *
153  archive_strncat(struct archive_string *, const void *, size_t);
154  struct archive_wstring *
155  archive_wstrncat(struct archive_wstring *, const wchar_t *, size_t);
156  
157  /* Append a C string to an archive_string, resizing as necessary. */
158  struct archive_string *
159  archive_strcat(struct archive_string *, const void *);
160  struct archive_wstring *
161  archive_wstrcat(struct archive_wstring *, const wchar_t *);
162  
163  /* Copy a C string to an archive_string, resizing as necessary. */
164  #define	archive_strcpy(as,p) \
165  	archive_strncpy((as), (p), ((p) == NULL ? 0 : strlen(p)))
166  #define	archive_wstrcpy(as,p) \
167  	archive_wstrncpy((as), (p), ((p) == NULL ? 0 : wcslen(p)))
168  #define	archive_strcpy_l(as,p,lo) \
169  	archive_strncpy_l((as), (p), ((p) == NULL ? 0 : strlen(p)), (lo))
170  
171  /* Copy a C string to an archive_string with limit, resizing as necessary. */
172  #define	archive_strncpy(as,p,l) \
173  	((as)->length=0, archive_strncat((as), (p), (l)))
174  #define	archive_wstrncpy(as,p,l) \
175  	((as)->length = 0, archive_wstrncat((as), (p), (l)))
176  
177  /* Return length of string. */
178  #define	archive_strlen(a) ((a)->length)
179  
180  /* Set string length to zero. */
181  #define	archive_string_empty(a) ((a)->length = 0)
182  #define	archive_wstring_empty(a) ((a)->length = 0)
183  
184  /* Release any allocated storage resources. */
185  void	archive_string_free(struct archive_string *);
186  void	archive_wstring_free(struct archive_wstring *);
187  
188  /* Like 'vsprintf', but resizes the underlying string as necessary. */
189  /* Note: This only implements a small subset of standard printf functionality. */
190  void	archive_string_vsprintf(struct archive_string *, const char *,
191  	    va_list) __LA_PRINTF(2, 0);
192  void	archive_string_sprintf(struct archive_string *, const char *, ...)
193  	    __LA_PRINTF(2, 3);
194  
195  /* Translates from MBS to Unicode. */
196  /* Returns non-zero if conversion failed in any way. */
197  int archive_wstring_append_from_mbs(struct archive_wstring *dest,
198      const char *, size_t);
199  
200  
201  /* A "multistring" can hold Unicode, UTF8, or MBS versions of
202   * the string.  If you set and read the same version, no translation
203   * is done.  If you set and read different versions, the library
204   * will attempt to transparently convert.
205   */
206  struct archive_mstring {
207  	struct archive_string aes_mbs;
208  	struct archive_string aes_utf8;
209  	struct archive_wstring aes_wcs;
210  	struct archive_string aes_mbs_in_locale;
211  	/* Bitmap of which of the above are valid.  Because we're lazy
212  	 * about malloc-ing and reusing the underlying storage, we
213  	 * can't rely on NULL pointers to indicate whether a string
214  	 * has been set. */
215  	int aes_set;
216  #define	AES_SET_MBS 1
217  #define	AES_SET_UTF8 2
218  #define	AES_SET_WCS 4
219  };
220  
221  void	archive_mstring_clean(struct archive_mstring *);
222  void	archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src);
223  int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **);
224  int archive_mstring_get_utf8(struct archive *, struct archive_mstring *, const char **);
225  int archive_mstring_get_wcs(struct archive *, struct archive_mstring *, const wchar_t **);
226  int	archive_mstring_get_mbs_l(struct archive *, struct archive_mstring *, const char **,
227  	    size_t *, struct archive_string_conv *);
228  int	archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs);
229  int	archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs,
230  	    size_t);
231  int	archive_mstring_copy_utf8(struct archive_mstring *, const char *utf8);
232  int	archive_mstring_copy_wcs(struct archive_mstring *, const wchar_t *wcs);
233  int	archive_mstring_copy_wcs_len(struct archive_mstring *,
234  	    const wchar_t *wcs, size_t);
235  int	archive_mstring_copy_mbs_len_l(struct archive_mstring *,
236  	    const char *mbs, size_t, struct archive_string_conv *);
237  int     archive_mstring_update_utf8(struct archive *, struct archive_mstring *aes, const char *utf8);
238  
239  
240  #endif
241