/*
- * "$Id: transcode.c 5300 2006-03-17 19:50:14Z mike $"
+ * "$Id: transcode.c 5373 2006-04-06 20:03:32Z mike $"
*
* Transcoding support for the Common UNIX Printing System (CUPS).
*
* conv_vbcs_to_utf8() - Convert legacy DBCS/VBCS to UTF-8.
* free_sbcs_charmap() - Free memory used by a single byte character set.
* free_vbcs_charmap() - Free memory used by a variable byte character set.
+ * get_charmap() - Lookup or get a character set map (private).
* get_charmap_count() - Count lines in a charmap file.
* get_sbcs_charmap() - Get SBCS Charmap.
* get_vbcs_charmap() - Get DBCS/VBCS Charmap.
#include "globals.h"
#include "debug.h"
+#include <limits.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
+/*
+ * Local globals...
+ */
+
+#ifdef HAVE_PTHREAD_H
+static pthread_mutex_t map_mutex = PTHREAD_MUTEX_INITIALIZER;
+ /* Mutex to control access to maps */
+#endif /* HAVE_PTHREAD_H */
+static _cups_cmap_t *cmap_cache = NULL;
+ /* SBCS Charmap Cache */
+static _cups_vmap_t *vmap_cache = NULL;
+ /* VBCS Charmap Cache */
+
+
/*
* Local functions...
*/
const cups_encoding_t encoding);
static void free_sbcs_charmap(_cups_cmap_t *sbcs);
static void free_vbcs_charmap(_cups_vmap_t *vbcs);
+static void *get_charmap(const cups_encoding_t encoding);
static int get_charmap_count(cups_file_t *fp);
static _cups_cmap_t *get_sbcs_charmap(const cups_encoding_t encoding,
const char *filename);
*/
void
-_cupsCharmapFlush(_cups_globals_t *cg) /* I - Global data */
+_cupsCharmapFlush(void)
{
_cups_cmap_t *cmap, /* Legacy SBCS / Unicode Charset Map */
*cnext; /* Next Legacy SBCS Charset Map */
*vnext; /* Next Legacy VBCS Charset Map */
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_lock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
+
/*
* Loop through SBCS charset map cache, free all memory...
*/
- for (cmap = cg->cmap_cache; cmap; cmap = cnext)
+ for (cmap = cmap_cache; cmap; cmap = cnext)
{
cnext = cmap->next;
free_sbcs_charmap(cmap);
}
- cg->cmap_cache = NULL;
+ cmap_cache = NULL;
/*
* Loop through DBCS/VBCS charset map cache, free all memory...
*/
- for (vmap = cg->vmap_cache; vmap; vmap = vnext)
+ for (vmap = vmap_cache; vmap; vmap = vnext)
{
vnext = vmap->next;
free(vmap);
}
- cg->vmap_cache = NULL;
+ vmap_cache = NULL;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
}
{
_cups_cmap_t *cmap; /* Legacy SBCS / Unicode Charset Map */
_cups_vmap_t *vmap; /* Legacy VBCS / Unicode Charset Map */
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
/*
* See if we already have this SBCS charset map loaded...
*/
- for (cmap = cg->cmap_cache; cmap; cmap = cmap->next)
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_lock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
+
+ for (cmap = cmap_cache; cmap; cmap = cmap->next)
{
if (cmap->encoding == encoding)
{
if (cmap->used > 0)
cmap->used --;
-
- return;
+ break;
}
}
* See if we already have this DBCS/VBCS charset map loaded...
*/
- for (vmap = cg->vmap_cache; vmap; vmap = vmap->next)
+ for (vmap = vmap_cache; vmap; vmap = vmap->next)
{
if (vmap->encoding == encoding)
{
if (vmap->used > 0)
vmap->used --;
- return;
+ break;
}
}
+
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
}
_cupsCharmapGet(
const cups_encoding_t encoding) /* I - Encoding */
{
- char filename[1024]; /* Filename for charset map file */
- _cups_globals_t *cg = _cupsGlobals(); /* Global data */
+ void *charmap; /* Charset map pointer */
DEBUG_printf(("_cupsCharmapGet(encoding=%d)\n", encoding));
}
/*
- * Get the data directory and charset map name...
+ * Lookup or get the charset map pointer and return...
*/
- snprintf(filename, sizeof(filename), "%s/charmaps/%s.txt",
- cg->cups_datadir, _cupsEncodingName(encoding));
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_lock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
- DEBUG_printf((" filename=\"%s\"\n", filename));
+ charmap = get_charmap(encoding);
- /*
- * Read charset map input file into cache...
- */
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
- if (encoding < CUPS_ENCODING_SBCS_END)
- return (get_sbcs_charmap(encoding, filename));
- else if (encoding < CUPS_ENCODING_VBCS_END)
- return (get_vbcs_charmap(encoding, filename));
- else
- return (NULL);
+ return (charmap);
}
const int maxout, /* I - Max output */
const cups_encoding_t encoding) /* I - Encoding */
{
+ int bytes; /* Number of bytes converted */
+
+
/*
* Check for valid arguments...
*/
* Convert input legacy charset to UTF-8...
*/
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_lock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
+
if (encoding < CUPS_ENCODING_SBCS_END)
- return (conv_sbcs_to_utf8(dest, (cups_sbcs_t *)src, maxout, encoding));
+ bytes = conv_sbcs_to_utf8(dest, (cups_sbcs_t *)src, maxout, encoding);
else if (encoding < CUPS_ENCODING_VBCS_END)
- return (conv_vbcs_to_utf8(dest, (cups_sbcs_t *)src, maxout, encoding));
+ bytes = conv_vbcs_to_utf8(dest, (cups_sbcs_t *)src, maxout, encoding);
else
{
- puts(" Bad encoding, returning -1");
- return (-1);
+ DEBUG_puts(" Bad encoding, returning -1");
+ bytes = -1;
}
+
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
+
+ return (bytes);
}
const int maxout, /* I - Max output */
const cups_encoding_t encoding) /* I - Encoding */
{
+ int bytes; /* Number of bytes converted */
+
+
/*
* Check for valid arguments...
*/
* Convert input UTF-8 to legacy charset...
*/
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_lock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
+
if (encoding < CUPS_ENCODING_SBCS_END)
- return (conv_utf8_to_sbcs((cups_sbcs_t *)dest, src, maxout, encoding));
+ bytes = conv_utf8_to_sbcs((cups_sbcs_t *)dest, src, maxout, encoding);
else if (encoding < CUPS_ENCODING_VBCS_END)
- return (conv_utf8_to_vbcs((cups_sbcs_t *)dest, src, maxout, encoding));
+ bytes = conv_utf8_to_vbcs((cups_sbcs_t *)dest, src, maxout, encoding);
else
- return (-1);
+ bytes = -1;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&map_mutex);
+#endif /* HAVE_PTHREAD_H */
+
+ return (bytes);
}
* Find legacy charset map in cache...
*/
- if ((cmap = (_cups_cmap_t *)_cupsCharmapGet(encoding)) == NULL)
+ if ((cmap = (_cups_cmap_t *)get_charmap(encoding)) == NULL)
return (-1);
/*
* Convert internal UCS-4 to output UTF-8 (and delete BOM)...
*/
- _cupsCharmapFree(encoding);
+ cmap->used --;
return (cupsUTF32ToUTF8(dest, work, maxout));
}
* Find legacy charset map in cache...
*/
- if ((cmap = (_cups_cmap_t *) _cupsCharmapGet(encoding)) == NULL)
+ if ((cmap = (_cups_cmap_t *)get_charmap(encoding)) == NULL)
return (-1);
/*
*dest = '\0';
- _cupsCharmapFree(encoding);
+ cmap->used --;
return ((int)(dest - start));
}
* Find legacy charset map in cache...
*/
- if ((vmap = (_cups_vmap_t *)_cupsCharmapGet(encoding)) == NULL)
+ if ((vmap = (_cups_vmap_t *)get_charmap(encoding)) == NULL)
return (-1);
/*
*dest = '\0';
- _cupsCharmapFree(encoding);
+ vmap->used --;
return ((int)(dest - start));
}
* Find legacy charset map in cache...
*/
- if ((vmap = (_cups_vmap_t *)_cupsCharmapGet(encoding)) == NULL)
+ if ((vmap = (_cups_vmap_t *)get_charmap(encoding)) == NULL)
return (-1);
/*
*workptr = 0;
- _cupsCharmapFree(encoding);
+ vmap->used --;
/*
* Convert internal UCS-4 to output UTF-8 (and delete BOM)...
}
+/*
+ * 'get_charmap()' - Lookup or get a character set map (private).
+ *
+ * This code handles single-byte (SBCS), double-byte (DBCS), and
+ * variable-byte (VBCS) character sets _without_ charset escapes...
+ * This code does not handle multiple-byte character sets (MBCS)
+ * (such as ISO-2022-JP) with charset switching via escapes...
+ */
+
+
+void * /* O - Charset map pointer */
+get_charmap(
+ const cups_encoding_t encoding) /* I - Encoding */
+{
+ char filename[1024]; /* Filename for charset map file */
+ _cups_globals_t *cg = _cupsGlobals(); /* Global data */
+
+
+ /*
+ * Get the data directory and charset map name...
+ */
+
+ snprintf(filename, sizeof(filename), "%s/charmaps/%s.txt",
+ cg->cups_datadir, _cupsEncodingName(encoding));
+
+ DEBUG_printf((" filename=\"%s\"\n", filename));
+
+ /*
+ * Read charset map input file into cache...
+ */
+
+ if (encoding < CUPS_ENCODING_SBCS_END)
+ return (get_sbcs_charmap(encoding, filename));
+ else if (encoding < CUPS_ENCODING_VBCS_END)
+ return (get_vbcs_charmap(encoding, filename));
+ else
+ return (NULL);
+}
+
+
/*
* 'get_charmap_count()' - Count lines in a charmap file.
*/
cups_ucs2_t *crow; /* Pointer to UCS-2 row in 'char2uni' */
cups_sbcs_t *srow; /* Pointer to SBCS row in 'uni2char' */
char line[256]; /* Line from charset map file */
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
/*
* See if we already have this SBCS charset map loaded...
*/
- for (cmap = cg->cmap_cache; cmap; cmap = cmap->next)
+ for (cmap = cmap_cache; cmap; cmap = cmap->next)
{
if (cmap->encoding == encoding)
{
cmap->used ++;
DEBUG_printf((" returning existing cmap=%p\n", cmap));
+
return ((void *)cmap);
}
}
{
cupsFileClose(fp);
DEBUG_puts(" Unable to allocate memory!");
+
return (NULL);
}
* Add it to the cache and return...
*/
- cmap->next = cg->cmap_cache;
- cg->cmap_cache = cmap;
+ cmap->next = cmap_cache;
+ cmap_cache = cmap;
DEBUG_printf((" returning new cmap=%p\n", cmap));
char line[256]; /* Line from charset map file */
int i; /* Loop variable */
int wide; /* 32-bit legacy char */
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
DEBUG_printf(("get_vbcs_charmap(encoding=%d, filename=\"%s\")\n",
* See if we already have this DBCS/VBCS charset map loaded...
*/
- for (vmap = cg->vmap_cache; vmap; vmap = vmap->next)
+ for (vmap = vmap_cache; vmap; vmap = vmap->next)
{
if (vmap->encoding == encoding)
{
vmap->used ++;
DEBUG_printf((" returning existing vmap=%p\n", vmap));
+
return ((void *)vmap);
}
}
if ((fp = cupsFileOpen(filename, "r")) == NULL)
{
DEBUG_printf((" Unable to open file: %s\n", strerror(errno)));
+
return (NULL);
}
if ((mapcount = get_charmap_count(fp)) <= 0)
{
DEBUG_puts(" Unable to get charmap count!");
+
return (NULL);
}
{
cupsFileClose(fp);
DEBUG_puts(" Unable to allocate memory!");
+
return (NULL);
}
* Add it to the cache and return...
*/
- vmap->next = cg->vmap_cache;
- cg->vmap_cache = vmap;
+ vmap->next = vmap_cache;
+ vmap_cache = vmap;
DEBUG_printf((" returning new vmap=%p\n", vmap));
/*
- * End of "$Id: transcode.c 5300 2006-03-17 19:50:14Z mike $"
+ * End of "$Id: transcode.c 5373 2006-04-06 20:03:32Z mike $"
*/