2 * Copyright (c) 2005 Massachusetts Institute of Technology
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 #ifndef __KHIMAIRA_MSTRING_H
28 #define __KHIMAIRA_MSTRING_H
35 /*! \defgroup util_mstring Multi String and CSV functions
40 #define KHM_CASE_SENSITIVE 16
42 #define KHM_MAXCCH_STRING 16384
44 #define KHM_MAXCB_STRING (KHM_MAXCCH_STRING * sizeof(wchar_t))
46 /*! \brief Initialize a multi-string
48 KHMEXP khm_int32 KHMAPI
49 multi_string_init(wchar_t * ms,
52 /*! \brief Prepend a string to a multi string
54 Adds the string \a str to the beginning of multi-string \a ms.
56 \param[in,out] ms The multi-string to be modified.
58 \param[in,out] pcb_ms A pointer to the size of the multistring.
59 On entry this specifies the size of the buffer pointed to by
60 \a ms. If the call is successful, on exit this will receive
61 the new size of the multi string in bytes. If the buffer is
62 insufficient, the function will return KHM_ERROR_TOO_LONG and
63 set this to the required size of the buffer in bytes.
65 \param[in] str The string to prepend to \a ms. This cannot be
66 longer than KHM_MAXCCH_STRING in characters including the
69 KHMEXP khm_int32 KHMAPI
70 multi_string_prepend(wchar_t * ms,
74 /*! \brief Append a string to a multi-string
76 Appends the string specified by \a str to the multi string
77 specified by \a ms. The size of the multi string in characters
78 including terminating NULLs after appending \a str can not exceed
81 \param[in] ms The buffer containing the multi string
83 \param[in,out] pcb_ms Points to a khm_int32 indicating the size of
84 the buffer pointed to by \a ms. On entry this contains the
85 size (in bytes) of the buffer pointed to by \a ms. On exit,
86 contains the new size of the multi string in bytes.
88 \param[in] str The string to append to the multi string. This
89 string cannot be NULL or an empty (zero length) string. The
90 length of \a str cannot exceed KHM_MAXCCH_STRING in
91 characters including terminating NULL.
93 \retval KHM_ERROR_SUCCESS The string was appended to the multi string
95 \retval KHM_ERROR_TOO_LONG The buffer pointed to by \a ms was
96 insufficient. The required size of the buffer is in \a pcb_ms
98 \retval KHM_ERROR_INVALID_PARAM One of more of the parameters were invalid.
100 KHMEXP khm_int32 KHMAPI
101 multi_string_append(wchar_t * ms,
103 const wchar_t * str);
105 /*! \brief Deletes a string from a multi string
107 Deletes the string specified by \a str from the multi string
108 specified by \a ms. How the string is matched to the strings in
109 \a ms is determined by \a flags. If more than one match is found,
110 then only the first match is deleted.
112 \param[in] ms The multi string to modify. The length of the multi
113 string in characters cannot exceed KHM_MAXCCH_STRING.
115 \param[in] str The string to search for
117 \param[in] flags How \a str is to be matched to existing strings
118 in \a ms. This could be a combination of KHM_PREFIX and
119 KHM_CASE_SENSITIVE. If KHM_PREFIX is used, then \a ms is
120 searched for a string that begins with \a str. Otherwise, \a
121 str must match the an entire string in the multi string. If
122 KHM_CASE_SENSITIVE is specified, then a case sensitive match
123 is performed. The defualt is to use a case insensitive
126 \retval KHM_ERROR_SUCCESS A string was matched and deleted from \a ms
128 \retval KHM_ERROR_NOT_FOUND No matches were found
130 \retval KHM_ERROR_INVALID_PARAM One or more parameters were incorrect.
132 \note The search for the existing string is done with
135 KHMEXP khm_int32 KHMAPI
136 multi_string_delete(wchar_t * ms,
138 const khm_int32 flags);
140 /*! \brief Search a multi string for a string
142 Searches the string specified by \a ms for a string that matches
143 \a str. How the match is performed is determined by \a flags.
144 Returns a poitner to the start of the matched string in \a ms. If
145 more than one string in \a ms matches \a str, then only the first
148 \param[in] ms The multi string to search in. The length of the
149 multi string cannot exceed KHM_MAXCCH_STRING in characters.
151 \param[in] str The string to search for
153 \param[in] flags How \a str is to be matched to existing strings
154 in \a ms. This could be a combination of KHM_PREFIX and
155 KHM_CASE_SENSITIVE. If KHM_PREFIX is used, then \a ms is
156 searched for a string that begins with \a str. Otherwise, \a
157 str must match the an entire string in the multi string. If
158 KHM_CASE_SENSITIVE is specified, then a case sensitive match
159 is performed. The defualt is to use a case insensitive
162 \return A pointer to the start of the first matched string or
163 NULL if no matches were found.
166 KHMEXP wchar_t * KHMAPI
167 multi_string_find(const wchar_t * ms,
169 const khm_int32 flags);
171 /*! \brief Convert a multi string to CSV
173 Converts a multi string to a comma separated value string based on
176 - Each string in the multi string is treated an individual field
178 - A field is quoted if it has double quotes or commas
180 - Double quotes within quoted fields are escaped by two
181 consecutive double quotes.
186 multi_string = L"foo\0bar\0baz,quux\0ab\"cd\0";
187 csv_string = L"foo,bar,\"baz,quux\",\"ab\"\"cd\"";
190 If multi_string_to_csv() is called on \a multi_string above,
191 you would obtain \a csv_string.
193 \param[out] csvbuf The buffer to place the CSV string in. Can be
194 NULL if only teh size of the needed buffer is required.
196 \param[in,out] pcb_csvbuf On entry, points to a khm_int32 that
197 holds the size of the buffer pointed to by \a csvbuf. On
198 exit, gets the number of bytes writted to \a csvbuf or the
199 required size of \a csvbuf if the buffer is too small or \a
202 \param[in] ms The mutli string to convert to a CSV.
204 \retval KHM_ERROR_SUCCESS The multi string was successfully
205 converted to a CSV string. The number of bytes written is in
206 \a pcb_csvbuf. The count includes the terminating NULL.
208 \retval KHM_ERROR_TOO_LONG The buffer was too small or \a csvbuf
209 was NULL. The required number of bytes in the buffer is in \a
212 \retval KHM_ERROR_INVALID_PARAM One or more parameters were ivnalid.
214 \see csv_to_multi_string()
216 KHMEXP khm_int32 KHMAPI
217 multi_string_to_csv(wchar_t * csvbuf,
218 khm_size * pcb_csvbuf,
221 /*! \brief Converts a CSV to a multi string
223 Undoes what multi_string_to_csv() does.
225 \param[out] ms The buffer that recieves the multi string. This
226 can be NULL if only the size of the buffer is requried.
228 \param[in,out] pcb_ms On entry contains the number of bytes ni the
229 buffer poitned to by \a ms. On exit contains the number of
230 bytes that were copied to \a ms including terminating NULLs,
231 or if the buffer was too small or \a ms was NULL, holds the
232 size in bytes of the requied buffer.
234 \param[in] csv The CSV string.
236 \retval KHM_ERROR_SUCCESS The CSV string was successfully
237 converted. The number of bytes written is in \a pcb_ms.
239 \retval KHM_ERROR_TOO_LONG The provided buffer was too small or \a
240 ms was NULL. The required size of the buffer in bytes is in \a
243 \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid.
246 KHMEXP khm_int32 KHMAPI
247 csv_to_multi_string(wchar_t * ms,
249 const wchar_t * csv);
251 /*! \brief Get the next string in a multi string
253 When \a str is pointing to a string that is in a multi string,
254 this function returns a pointer to the next string in the multi
257 Typically, one would start by having \a str point to the start of
258 the multi string (which is the first string in the multi string),
259 and then call this function repeatedly, until it returns NULL, at
260 which point the end of the multi string has been reached.
262 \param[in] str Pointer to a string in a multi string. Each string
263 in a multi string cannot exceed KHM_MAXCCH_STRING in charaters
264 including the terminating NULL.
266 \return A pointer to the start of the next string in the multi
267 string or NULL if there is no more strings.
269 KHMEXP wchar_t * KHMAPI
270 multi_string_next(const wchar_t * str);
272 /*! \brief Get the length of a multi string in bytes
274 The returned length includes the trailing double \a NULL and any
275 other \a NULL inbetween.
277 \param[in] str Pointer to a multi string.
278 \param[in] max_cb Maximum size that the str can be. This can not
279 be larger than KHM_MAXCB_STRING.
280 \param[out] len_cb The length of the string in bytes if the call
283 \retval KHM_ERROR_SUCCESS The length of the string is in \a len_cb
284 \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid
285 \retval KHM_ERROR_TOO_LONG The multi string is longer than \a
288 KHMEXP khm_int32 KHMAPI
289 multi_string_length_cb(const wchar_t * str,
293 /*! \brief Get the length of a multi string in characters
295 The returned length includes the trailing double \a NULL and any
296 other \a NULL inbetween.
298 \param[in] str Pointer to a multi string.
299 \param[in] max_cch Maximum size that the str can be. This can not
300 be larger than KHM_MAXCCH_STRING.
301 \param[out] len_cch The length of the string in characters if the call
304 \retval KHM_ERROR_SUCCESS The length of the string is in \a len_cch
305 \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid
306 \retval KHM_ERROR_TOO_LONG The multi string is longer than \a
309 KHMEXP khm_int32 KHMAPI
310 multi_string_length_cch(const wchar_t * str,
314 /*! \brief Get the number of strings in a multi string
316 KHMEXP khm_size KHMAPI
317 multi_string_length_n(const wchar_t * str);
319 /*! \brief Copy a multi string with byte counts
321 Copy a multi string from one location to another.
323 \param[out] s_dest Receives a copy of the multi string
324 \param[in] max_cb_dest Number of bytes in the buffer pointed to by
326 \param[in] src The source multi string
328 \retval KHM_ERROR_SUCCESS The multi string was copied successfully
329 \retval KHM_ERROR_INVALID_PARAM One or more parameters were
331 \retval KHM_ERROR_TOO_LONG The size of the destination buffer was
334 KHMEXP khm_int32 KHMAPI
335 multi_string_copy_cb(wchar_t * s_dest,
336 khm_size max_cb_dest,
337 const wchar_t * src);
339 /*! \brief Copy a multi string with character count
341 Copy a multi string from one location to another.
343 \param[out] s_dest Receives a copy of the multi string
344 \param[in] max_cb_dest Number of characters in the buffer pointed
346 \param[in] src The source multi string
348 \retval KHM_ERROR_SUCCESS The multi string was copied successfully
349 \retval KHM_ERROR_INVALID_PARAM One or more parameters were
351 \retval KHM_ERROR_TOO_LONG The size of the destination buffer was
354 KHMEXP khm_int32 KHMAPI
355 multi_string_copy_cch(wchar_t * s_dest,
356 khm_size max_cch_dest,
357 const wchar_t * src);