exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

i18n.c (3529B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2020, 2021 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file json/i18n.c
     18  * @brief helper functions for i18n in JSON processing
     19  * @author Christian Grothoff
     20  */
     21 #include "platform.h"  /* UNNECESSARY? */
     22 #include <gnunet/gnunet_util_lib.h>
     23 #include "taler/taler_util.h"
     24 #include "taler/taler_json_lib.h"
     25 
     26 
     27 const json_t *
     28 TALER_JSON_extract_i18n (const json_t *object,
     29                          const char *language_pattern,
     30                          const char *field)
     31 {
     32   const json_t *ret;
     33   json_t *i18n;
     34   double quality = 0.0;
     35 
     36   ret = json_object_get (object,
     37                          field);
     38   if (NULL == ret)
     39     return NULL; /* field MUST exist in object */
     40   {
     41     char *name;
     42 
     43     GNUNET_asprintf (&name,
     44                      "%s_i18n",
     45                      field);
     46     i18n = json_object_get (object,
     47                             name);
     48     GNUNET_free (name);
     49   }
     50   if (NULL == i18n)
     51     return ret;
     52   {
     53     const char *key;
     54     json_t *value;
     55 
     56     json_object_foreach (i18n, key, value) {
     57       double q = TALER_pattern_matches (language_pattern,
     58                                         key);
     59       if (q > quality)
     60       {
     61         quality = q;
     62         ret = value;
     63       }
     64     }
     65   }
     66   return ret;
     67 }
     68 
     69 
     70 /**
     71  * Check that @a tag is a valid language tag.  Accepted are a
     72  * two- or three-letter language code (ISO 639-1, 639-2 or 639-3),
     73  * optionally followed by '_' or '-' and a two-letter country code
     74  * (ISO 3166-1 alpha-2) or a three-digit region code (UN M.49).
     75  * We do not care about capitalization.  For the syntax, see the
     76  * GNU Gettext manual, including appendix A for rare language
     77  * codes.
     78  *
     79  * @param tag language tag to check
     80  * @return true if @a tag is well-formed
     81  */
     82 static bool
     83 check_language_tag (const char *tag)
     84 {
     85   size_t len = strlen (tag);
     86   size_t off = 0;
     87 
     88   while ( (off < len) &&
     89           (0 != isalpha ((unsigned char) tag[off])) )
     90     off++;
     91   if ( (off < 2) ||
     92        (off > 3) )
     93     return false; /* language code must have 2 or 3 letters */
     94   if (off == len)
     95     return true; /* language code without country code */
     96   if ( ('_' != tag[off]) &&
     97        ('-' != tag[off]) )
     98     return false;
     99   off++;
    100   if (2 == len - off)
    101   {
    102     return ( (0 != isalpha ((unsigned char) tag[off])) &&
    103              (0 != isalpha ((unsigned char) tag[off + 1])) );
    104   }
    105   if (3 == len - off)
    106   {
    107     return ( (0 != isdigit ((unsigned char) tag[off])) &&
    108              (0 != isdigit ((unsigned char) tag[off + 1])) &&
    109              (0 != isdigit ((unsigned char) tag[off + 2])) );
    110   }
    111   return false;
    112 }
    113 
    114 
    115 bool
    116 TALER_JSON_check_i18n (const json_t *i18n)
    117 {
    118   const char *field;
    119   json_t *member;
    120 
    121   if (! json_is_object (i18n))
    122     return false;
    123   json_object_foreach ((json_t *) i18n, field, member)
    124   {
    125     if (! json_is_string (member))
    126       return false;
    127     if (! check_language_tag (field))
    128       return false;
    129   }
    130   return true;
    131 }
    132 
    133 
    134 /* end of i18n.c */