]>
git.ipfire.org Git - thirdparty/cups.git/blob - cups/string.c
2 * "$Id: string.c 5047 2006-02-02 05:14:15Z mike $"
4 * String functions for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2006 by Easy Software Products.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
24 * This file is subject to the Apple OS-Developed Software exception.
28 * _cups_sp_alloc() - Allocate/reference a string.
29 * _cups_sp_flush() - Flush the string pool...
30 * _cups_sp_free() - Free/dereference a string.
31 * _cups_sp_statistics() - Return allocation statistics for string pool.
32 * _cups_strcpy() - Copy a string allowing for overlapping strings.
33 * _cups_strdup() - Duplicate a string.
34 * _cups_strcasecmp() - Do a case-insensitive comparison.
35 * _cups_strncasecmp() - Do a case-insensitive comparison on up to N chars.
36 * _cups_strlcat() - Safely concatenate two strings.
37 * _cups_strlcpy() - Safely copy two strings.
38 * compare_sp_items() - Compare two string pool items...
42 * Include necessary headers...
56 static int compare_sp_items(_cups_sp_item_t
*a
, _cups_sp_item_t
*b
);
60 * '_cups_sp_alloc()' - Allocate/reference a string.
63 char * /* O - String pointer */
64 _cups_sp_alloc(const char *s
) /* I - String */
66 _cups_globals_t
*cg
; /* Global data */
67 _cups_sp_item_t
*item
, /* String pool item */
72 * Range check input...
79 * Get the string pool...
85 cg
->stringpool
= cupsArrayNew((cups_array_func_t
)compare_sp_items
, NULL
);
91 * See if the string is already in the pool...
96 if ((item
= (_cups_sp_item_t
*)cupsArrayFind(cg
->stringpool
, &key
)) != NULL
)
99 * Found it, return the cached string...
108 * Not found, so allocate a new one...
111 item
= (_cups_sp_item_t
*)calloc(1, sizeof(_cups_sp_item_t
));
116 item
->str
= strdup(s
);
125 * Add the string to the pool and return it...
128 cupsArrayAdd(cg
->stringpool
, item
);
135 * '_cups_sp_flush()' - Flush the string pool...
139 _cups_sp_flush(_cups_globals_t
*cg
) /* I - Global data */
141 _cups_sp_item_t
*item
; /* Current item */
144 for (item
= (_cups_sp_item_t
*)cupsArrayFirst(cg
->stringpool
);
146 item
= (_cups_sp_item_t
*)cupsArrayNext(cg
->stringpool
))
152 cupsArrayDelete(cg
->stringpool
);
157 * '_cups_sp_free()' - Free/dereference a string.
161 _cups_sp_free(const char *s
)
163 _cups_globals_t
*cg
; /* Global data */
164 _cups_sp_item_t
*item
, /* String pool item */
165 key
; /* Search key */
169 * Range check input...
176 * Get the string pool...
185 * See if the string is already in the pool...
190 if ((item
= (_cups_sp_item_t
*)cupsArrayFind(cg
->stringpool
, &key
)) != NULL
)
193 * Found it, dereference...
198 if (!item
->ref_count
)
204 cupsArrayRemove(cg
->stringpool
, item
);
214 * '_cups_sp_statistics()' - Return allocation statistics for string pool.
217 size_t /* O - Number of strings */
218 _cups_sp_statistics(size_t *alloc_bytes
,/* O - Allocated bytes */
219 size_t *total_bytes
)/* O - Total string bytes */
221 size_t count
, /* Number of strings */
222 abytes
, /* Allocated string bytes */
223 tbytes
, /* Total string bytes */
224 len
; /* Length of string */
225 _cups_sp_item_t
*item
; /* Current item */
226 _cups_globals_t
*cg
; /* Global data */
230 * Loop through strings in pool, counting everything up...
235 for (count
= 0, abytes
= 0, tbytes
= 0,
236 item
= (_cups_sp_item_t
*)cupsArrayFirst(cg
->stringpool
);
238 item
= (_cups_sp_item_t
*)cupsArrayNext(cg
->stringpool
))
241 * Count allocated memory, using a 64-bit aligned buffer as a basis.
244 count
+= item
->ref_count
;
245 len
= (strlen(item
->str
) + 8) & ~7;
246 abytes
+= sizeof(_cups_sp_item_t
) + len
;
247 tbytes
+= item
->ref_count
* len
;
255 *alloc_bytes
= abytes
;
258 *total_bytes
= tbytes
;
265 * '_cups_strcpy()' - Copy a string allowing for overlapping strings.
269 _cups_strcpy(char *dst
, /* I - Destination string */
270 const char *src
) /* I - Source string */
280 * '_cups_strdup()' - Duplicate a string.
284 char * /* O - New string pointer */
285 _cups_strdup(const char *s
) /* I - String to duplicate */
287 char *t
; /* New string pointer */
293 if ((t
= malloc(strlen(s
) + 1)) == NULL
)
296 return (strcpy(t
, s
));
298 #endif /* !HAVE_STRDUP */
302 * '_cups_strcasecmp()' - Do a case-insensitive comparison.
305 #ifndef HAVE_STRCASECMP
306 int /* O - Result of comparison (-1, 0, or 1) */
307 _cups_strcasecmp(const char *s
, /* I - First string */
308 const char *t
) /* I - Second string */
310 while (*s
!= '\0' && *t
!= '\0')
312 if (tolower(*s
& 255) < tolower(*t
& 255))
314 else if (tolower(*s
& 255) > tolower(*t
& 255))
321 if (*s
== '\0' && *t
== '\0')
328 #endif /* !HAVE_STRCASECMP */
331 * '_cups_strncasecmp()' - Do a case-insensitive comparison on up to N chars.
334 #ifndef HAVE_STRNCASECMP
335 int /* O - Result of comparison (-1, 0, or 1) */
336 _cups_strncasecmp(const char *s
, /* I - First string */
337 vconst
char *t
, /* I - Second string */
338 size_t n
) /* I - Maximum number of characters to compare */
340 while (*s
!= '\0' && *t
!= '\0' && n
> 0)
342 if (tolower(*s
& 255) < tolower(*t
& 255))
344 else if (tolower(*s
& 255) > tolower(*t
& 255))
354 else if (*s
== '\0' && *t
== '\0')
361 #endif /* !HAVE_STRNCASECMP */
366 * '_cups_strlcat()' - Safely concatenate two strings.
369 size_t /* O - Length of string */
370 _cups_strlcat(char *dst
, /* O - Destination string */
371 const char *src
, /* I - Source string */
372 size_t size
) /* I - Size of destination string buffer */
374 size_t srclen
; /* Length of source string */
375 size_t dstlen
; /* Length of destination string */
379 * Figure out how much room is left...
382 dstlen
= strlen(dst
);
386 return (dstlen
); /* No room, return immediately... */
389 * Figure out how much room is needed...
392 srclen
= strlen(src
);
395 * Copy the appropriate amount...
401 memcpy(dst
+ dstlen
, src
, srclen
);
402 dst
[dstlen
+ srclen
] = '\0';
404 return (dstlen
+ srclen
);
406 #endif /* !HAVE_STRLCAT */
411 * '_cups_strlcpy()' - Safely copy two strings.
414 size_t /* O - Length of string */
415 _cups_strlcpy(char *dst
, /* O - Destination string */
416 const char *src
, /* I - Source string */
417 size_t size
) /* I - Size of destination string buffer */
419 size_t srclen
; /* Length of source string */
423 * Figure out how much room is needed...
428 srclen
= strlen(src
);
431 * Copy the appropriate amount...
437 memcpy(dst
, src
, srclen
);
442 #endif /* !HAVE_STRLCPY */
446 * 'compare_sp_items()' - Compare two string pool items...
449 static int /* O - Result of comparison */
450 compare_sp_items(_cups_sp_item_t
*a
, /* I - First item */
451 _cups_sp_item_t
*b
) /* I - Second item */
453 return (strcmp(a
->str
, b
->str
));
458 * End of "$Id: string.c 5047 2006-02-02 05:14:15Z mike $".