LCOV - code coverage report
Current view: top level - src/base - pdf-text-context.c (source / functions) Hit Total Coverage
Test: libgnupdf.info Lines: 38 48 79.2 %
Date: 2011-12-09 Functions: 7 9 77.8 %
Branches: 12 24 50.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- mode: C -*-
       2                 :            :  *
       3                 :            :  *       File:         pdf-text-context.c
       4                 :            :  *       Date:         Fri Feb 25 23:58:56 2008
       5                 :            :  *
       6                 :            :  *       GNU PDF Library - Encoded Text Context
       7                 :            :  *
       8                 :            :  */
       9                 :            : 
      10                 :            : /* Copyright (C) 2008-2011 Free Software Foundation, Inc. */
      11                 :            : 
      12                 :            : /* This program is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU General Public License as published by
      14                 :            :  * the Free Software Foundation, either version 3 of the License, or
      15                 :            :  * (at your option) any later version.
      16                 :            :  *
      17                 :            :  * This program is distributed in the hope that it will be useful,
      18                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20                 :            :  * GNU General Public License for more details.
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU General Public License
      23                 :            :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24                 :            :  */
      25                 :            : 
      26                 :            : #include <config.h>
      27                 :            : 
      28                 :            : #include <string.h>
      29                 :            : #include <stdio.h>
      30                 :            : #include <locale.h>
      31                 :            : #include <localename.h>    /* From gnulib sources.  */
      32                 :            : #include <localcharset.h>  /* From gnulib sources.  */
      33                 :            : #include <streq.h>         /* From gnulib sources.  */
      34                 :            : 
      35                 :            : #include <pdf-types.h>
      36                 :            : #include <pdf-text.h>
      37                 :            : #include <pdf-text-context.h>
      38                 :            : 
      39                 :            : /* Host Language code Length */
      40                 :            : #define PDF_TEXT_HLL  3
      41                 :            : 
      42                 :            : /* Structure containing the specific context configuration for the Text
      43                 :            :  *  Encoding Module */
      44                 :            : typedef struct pdf_text_context_s {
      45                 :            :   /* Host encoding configured in the system */
      46                 :            :   pdf_char_t *host_encoding;
      47                 :            :   /* 2-character LANG ID */
      48                 :            :   pdf_char_t host_language_id[PDF_TEXT_HLL];
      49                 :            :   /* 2-character Country ID */
      50                 :            :   pdf_char_t host_country_id[PDF_TEXT_HLL];
      51                 :            :   /* System endianness */
      52                 :            :   enum pdf_endianness_e host_endianness;
      53                 :            :   /* Default EOL character in the system */
      54                 :            :   pdf_text_eol_t host_eol;
      55                 :            : } pdf_text_context_t;
      56                 :            : 
      57                 :            : 
      58                 :            : /* This context will be initialized only once at program startup, and it will
      59                 :            :  *  be treated as constant from then on, so there shouldn't be any problem
      60                 :            :  *  with multiple threading and reentrancy */
      61                 :            : static pdf_text_context_t text_context;
      62                 :            : static pdf_bool_t text_context_initialized = PDF_FALSE;
      63                 :            : 
      64                 :            : /* Definition of the different platform-dependent EOL types, in UTF-8. This
      65                 :            :  *  array is based on the `enum pdf_text_eol_types' enumeration. */
      66                 :            : static const struct pdf_text_eol_s pdf_text_eol_types [PDF_TEXT_EOLMAX] = {
      67                 :            :   { { PDF_TEXT_DEF_CR, PDF_TEXT_DEF_LF,  0x00 } },  /* PDF_TEXT_EOL_WINDOWS */
      68                 :            :   { { PDF_TEXT_DEF_LF, 0x00,             0x00 } },  /* PDF_TEXT_EOL_UNIX    */
      69                 :            :   { { 0xC2,            PDF_TEXT_DEF_NEL, 0x00 } },  /* PDF_TEXT_EOL_EBCDIC  */
      70                 :            :   { { PDF_TEXT_DEF_CR, 0x00,             0x00 } }   /* PDF_TEXT_EOL_MACOS   */
      71                 :            : };
      72                 :            : 
      73                 :            : /* Function to detect the endianness of the system. Can be either Big Endian
      74                 :            :  *  (like PPC systems) or Little Endian (like Intel systems). PDF_IS_BIG_ENDIAN
      75                 :            :  *  is filled in config.h at configure level. */
      76                 :            : static void
      77                 :            : pdf_text_detect_host_endianness (void)
      78                 :            : {
      79                 :            : #if PDF_IS_BIG_ENDIAN
      80                 :            :   PDF_DEBUG_BASE("TextContext: Host is 'Big Endian'");
      81                 :            :   text_context.host_endianness = PDF_TEXT_BIG_ENDIAN;
      82                 :            : #else
      83                 :            :   PDF_DEBUG_BASE("TextContext: Host is 'Little Endian'");
      84                 :        745 :   text_context.host_endianness =  PDF_TEXT_LITTLE_ENDIAN;
      85                 :            : #endif
      86                 :            : }
      87                 :            : 
      88                 :            : static pdf_bool_t
      89                 :            : pdf_text_detect_host_encoding (pdf_error_t **error)
      90                 :            : {
      91                 :            :   const pdf_char_t *charset;
      92                 :            : 
      93                 :            :   /* Get host encoding and check it */
      94                 :        745 :   charset = locale_charset ();
      95   [ +  -  -  + ]:        745 :   if (!charset || (strlen (charset) < 3))
      96                 :            :     {
      97         [ #  # ]:          0 :       pdf_set_error (error,
      98                 :            :                      PDF_EDOMAIN_BASE_TEXT,
      99                 :            :                      PDF_ETEXTENC,
     100                 :            :                      "couldn't detect host encoding: "
     101                 :            :                      "invalid charset, '%s'",
     102                 :            :                      charset ? charset : "unknown");
     103                 :          0 :       return PDF_FALSE;
     104                 :            :     }
     105                 :            : 
     106                 :        745 :   text_context.host_encoding = strdup (charset);
     107                 :            : 
     108                 :            :   PDF_DEBUG_BASE ("TextContext: Host Encoding is '%s'",
     109                 :            :                   text_context.host_encoding);
     110                 :            : 
     111                 :        745 :   return PDF_TRUE;
     112                 :            : }
     113                 :            : 
     114                 :            : static pdf_bool_t
     115                 :        745 : pdf_text_detect_host_language_and_country (pdf_error_t **error)
     116                 :            : {
     117                 :            :   const pdf_char_t *locale_name;
     118                 :            : 
     119                 :            :   /* Initialize context strings */
     120                 :        745 :   memset (&text_context.host_language_id[0], 0, PDF_TEXT_HLL);
     121                 :        745 :   memset (&text_context.host_country_id[0], 0, PDF_TEXT_HLL);
     122                 :            : 
     123                 :            :   /* Get system default locale name and check it */
     124                 :        745 :   locale_name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
     125         [ -  + ]:        745 :   if (!locale_name)
     126                 :            :     {
     127                 :          0 :       pdf_set_error (error,
     128                 :            :                      PDF_EDOMAIN_BASE_TEXT,
     129                 :            :                      PDF_ETEXTENC,
     130                 :            :                      "couldn't detect host language and country: "
     131                 :            :                      "locale name not detected");
     132                 :          0 :       return PDF_FALSE;
     133                 :            :     }
     134                 :            : 
     135   [ +  -  +  - ]:       1490 :   if (!STREQ (locale_name, "C", 'C', 0, 0, 0, 0, 0, 0, 0, 0) &&
     136                 :        745 :       !STREQ (locale_name, "POSIX", 'P', 'O', 'S', 'I', 'X', 0, 0, 0, 0))
     137                 :            :     {
     138                 :            :       /* Store language ID */
     139                 :        745 :       strncpy (&(text_context.host_language_id[0]),
     140                 :            :                locale_name,
     141                 :            :                PDF_TEXT_HLL - 1);
     142                 :            : 
     143                 :            :       /* If available, store country ID */
     144 [ +  - ][ +  - ]:        745 :       if((strlen (locale_name) >= 5) &&
     145                 :        745 :          (locale_name[2] == '_'))
     146                 :            :         {
     147                 :        745 :           strncpy(&(text_context.host_country_id[0]),
     148                 :            :                   &locale_name[3],
     149                 :            :                   PDF_TEXT_HLL - 1);
     150                 :            :         }
     151                 :            :     }
     152                 :            : 
     153                 :            :   PDF_DEBUG_BASE("TextContext: Locale name is '%s'",
     154                 :            :                  locale_name);
     155                 :            :   PDF_DEBUG_BASE("TextContext: Language ID is '%.2s'",
     156                 :            :                  text_context.host_language_id);
     157                 :            :   PDF_DEBUG_BASE("TextContext: Country ID is '%.2s'",
     158                 :            :                  text_context.host_country_id);
     159                 :        745 :   return PDF_TRUE;
     160                 :            : }
     161                 :            : 
     162                 :            : static void
     163                 :            : pdf_text_detect_host_eol (void)
     164                 :            : {
     165                 :            :   /* The EOL sequence (a.k.a Newline function) may be represented by different
     166                 :            :    *  characters, depending on the platform
     167                 :            :    *
     168                 :            :    *  Mac OS 9.x and earlier ---> CR (Carriage Return), U+000D (Not supported)
     169                 :            :    *  Mac OS X, Unix, GNU/Linux ---> LF (Line Feed), U+000A
     170                 :            :    *  Windows ---> CRLF (Carriage Return + Line Feed), <U+000D,U+000A>
     171                 :            :    *  EBCDIC-based OS --> NEL (Next Line), U+0085 (Not supported)
     172                 :            :    */
     173                 :            : #ifdef PDF_HOST_WIN32
     174                 :            :   {
     175                 :            :     text_context.host_eol =
     176                 :            :       (pdf_text_eol_t)&pdf_text_eol_types[PDF_TEXT_EOL_WINDOWS];
     177                 :            :   }
     178                 :            : #else
     179                 :            :   {
     180                 :        745 :     text_context.host_eol =
     181                 :            :       (pdf_text_eol_t)&pdf_text_eol_types[PDF_TEXT_EOL_UNIX];
     182                 :            :   }
     183                 :            : #endif
     184                 :            : }
     185                 :            : 
     186                 :            : void
     187                 :        745 : pdf_text_context_deinit (void)
     188                 :            : {
     189         [ +  - ]:        745 :   if (text_context.host_encoding)
     190                 :            :     {
     191                 :        745 :       pdf_dealloc (text_context.host_encoding);
     192                 :        745 :       text_context.host_encoding = NULL;
     193                 :            :     }
     194                 :            : 
     195                 :        745 :   text_context_initialized = PDF_FALSE;
     196                 :            :   PDF_DEBUG_BASE ("Text context correctly deinitialized...");
     197                 :        745 : }
     198                 :            : 
     199                 :            : pdf_bool_t
     200                 :        745 : pdf_text_context_init (pdf_error_t **error)
     201                 :            : {
     202                 :            :   /* Get system endianness */
     203                 :            :   pdf_text_detect_host_endianness ();
     204                 :            : 
     205                 :            :   /* Get language and country ID from locale */
     206         [ -  + ]:        745 :   if (!pdf_text_detect_host_language_and_country (error))
     207                 :          0 :     return PDF_FALSE;
     208                 :            : 
     209                 :            :   /* Get host encoding from system */
     210         [ -  + ]:        745 :   if (!pdf_text_detect_host_encoding (error))
     211                 :          0 :     return PDF_FALSE;
     212                 :            : 
     213                 :            :   /* Detect host default EOL sequence */
     214                 :            :   pdf_text_detect_host_eol ();
     215                 :            : 
     216                 :            :   /* Mark the context as initialized */
     217                 :        745 :   text_context_initialized = PDF_TRUE;
     218                 :            : 
     219                 :            :   PDF_DEBUG_BASE ("Text context correctly initialized...");
     220                 :        745 :   return PDF_TRUE;
     221                 :            : }
     222                 :            : 
     223                 :            : pdf_bool_t
     224                 :       2488 : pdf_text_context_initialized (void)
     225                 :            : {
     226                 :       2488 :   return text_context_initialized;
     227                 :            : }
     228                 :            : 
     229                 :            : enum pdf_endianness_e
     230                 :          0 : pdf_text_context_get_host_endianness (void)
     231                 :            : {
     232                 :          0 :   return text_context.host_endianness;
     233                 :            : }
     234                 :            : 
     235                 :            : const pdf_char_t *
     236                 :         28 : pdf_text_context_get_host_encoding (void)
     237                 :            : {
     238                 :         28 :   return text_context.host_encoding;
     239                 :            : }
     240                 :            : 
     241                 :            : const pdf_char_t *
     242                 :         32 : pdf_text_context_get_host_language (void)
     243                 :            : {
     244                 :         32 :   return (const pdf_char_t *)text_context.host_language_id;
     245                 :            : }
     246                 :            : 
     247                 :            : const pdf_char_t *
     248                 :          0 : pdf_text_context_get_host_country (void)
     249                 :            : {
     250                 :          0 :   return (const pdf_char_t *)text_context.host_country_id;
     251                 :            : }
     252                 :            : 
     253                 :            : pdf_text_eol_t
     254                 :         18 : pdf_text_context_get_host_eol (enum pdf_text_eol_types eol_type)
     255                 :            : {
     256         [ +  + ]:         18 :   return (eol_type == PDF_TEXT_EOL_HOST ?
     257                 :            :           text_context.host_eol :
     258                 :         16 :           (pdf_text_eol_t) &(pdf_text_eol_types [eol_type]));
     259                 :            : }
     260                 :            : 
     261                 :            : /* End of pdf-text-context.c */

Generated by: LCOV version 1.8