home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume27 / runes / part01 / libc / utf2.c < prev   
Encoding:
C/C++ Source or Header  |  1993-09-07  |  4.0 KB  |  149 lines

  1. /*-
  2.  * Copyright (c) 1993
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Paul Borman at Krystal Technologies.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #if defined(LIBC_SCCS) && !defined(lint)
  38. static char sccsid[] = "@(#)utf2.c    8.1 (Berkeley) 6/4/93";
  39. #endif /* LIBC_SCCS and not lint */
  40.  
  41. #include <errno.h>
  42. #include <rune.h>
  43. #include <stddef.h>
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46.  
  47. rune_t    _UTF2_sgetrune __P((const char *, size_t, char const **));
  48. int    _UTF2_sputrune __P((rune_t, char *, size_t, char **));
  49.  
  50. static _utf_count[16] = {
  51.     1, 1, 1, 1, 1, 1, 1, 1,
  52.     0, 0, 0, 0, 2, 2, 3, 0,
  53. };
  54.  
  55. int
  56. _UTF2_init(rl)
  57.     _RuneLocale *rl;
  58. {
  59.     rl->sgetrune = _UTF2_sgetrune;
  60.     rl->sputrune = _UTF2_sputrune;
  61.     _CurrentRuneLocale = rl;
  62.     __mb_cur_max = 3;
  63.     return (0);
  64. }
  65.  
  66. rune_t
  67. _UTF2_sgetrune(string, n, result)
  68.     const char *string;
  69.     size_t n;
  70.     char const **result;
  71. {
  72.     int c;
  73.  
  74.     if (n < 1 || (c = _utf_count[(*string >> 4) & 0xf]) > n) {
  75.         if (result)
  76.             *result = string;
  77.         return (_INVALID_RUNE);
  78.     }
  79.     switch (c) {
  80.     case 1:
  81.         if (result)
  82.             *result = string + 1;
  83.         return (*string & 0xff);
  84.     case 2:
  85.         if ((string[1] & 0xC0) != 0x80)
  86.             goto encoding_error;
  87.         if (result)
  88.             *result = string + 2;
  89.         return (((string[0] & 0x1F) << 6) | (string[1] & 0x3F));
  90.     case 3:
  91.         if ((string[1] & 0xC0) != 0x80 || (string[2] & 0xC0) != 0x80)
  92.             goto encoding_error;
  93.         if (result)
  94.             *result = string + 3;
  95.         return (((string[0] & 0x1F) << 12) | ((string[1] & 0x3F) << 6)
  96.             | (string[2] & 0x3F));
  97.     default:
  98. encoding_error:    if (result)
  99.             *result = string + 1;
  100.         return (_INVALID_RUNE);
  101.     }
  102. }
  103.  
  104. int
  105. _UTF2_sputrune(c, string, n, result)
  106.     rune_t c;
  107.     char *string, **result;
  108.     size_t n;
  109. {
  110.     if (c & 0xF800) {
  111.         if (n >= 3) {
  112.             if (string) {
  113.                 string[0] = 0xE0 | ((c >> 12) & 0x0F);
  114.                 string[1] = 0x80 | ((c >> 6) & 0x3F);
  115.                 string[2] = 0x80 | ((c) & 0x3F);
  116.             }
  117.             if (result)
  118.                 *result = string + 3;
  119.         } else
  120.             if (result)
  121.                 *result = NULL;
  122.  
  123.         return (3);
  124.     } else
  125.         if (c & 0x0780) {
  126.             if (n >= 2) {
  127.                 if (string) {
  128.                     string[0] = 0xC0 | ((c >> 6) & 0x1F);
  129.                     string[1] = 0x80 | ((c) & 0x3F);
  130.                 }
  131.                 if (result)
  132.                     *result = string + 2;
  133.             } else
  134.                 if (result)
  135.                     *result = NULL;
  136.             return (2);
  137.         } else {
  138.             if (n >= 1) {
  139.                 if (string)
  140.                     string[0] = c;
  141.                 if (result)
  142.                     *result = string + 1;
  143.             } else
  144.                 if (result)
  145.                     *result = NULL;
  146.             return (1);
  147.         }
  148. }
  149.