1 /* Creation date: 2008-04-06T02:35:32Z
2 * Authors: Don
3 */
4
5 /*
6
7 Copyright (c) 2007-2010 Don Owens <don@regexguy.com>. All rights reserved.
8
9 This is free software; you can redistribute it and/or modify it under
10 the Perl Artistic license. You should have received a copy of the
11 Artistic license with this distribution, in the file named
12 "Artistic". You may also obtain a copy from
13 http://regexguy.com/license/Artistic
14
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
19 */
20
21 /* $Header: /repository/projects/libjsonevt/utf32.c,v 1.3 2009-02-23 17:46:55 don Exp $ */
22
23 #include "utf32.h"
24
25 #define SAFE_SET_POINTER_VAL(ptr, val) if (ptr) { *(ptr) = val; }
26
27 uint32_t
utf32_bytes_to_unicode(const uint8_t * orig_buf,uint32_t buf_len,uint32_t * ret_len,uint32_t is_little_endian)28 utf32_bytes_to_unicode(const uint8_t *orig_buf, uint32_t buf_len, uint32_t *ret_len,
29 uint32_t is_little_endian) {
30
31 const uint8_t *s = orig_buf;
32
33 if (buf_len < 4) {
34 /* must be at least 4 bytes in a valid utf-32 sequence*/
35 SAFE_SET_POINTER_VAL(ret_len, 0);
36 return 0;
37 }
38
39 SAFE_SET_POINTER_VAL(ret_len, 4);
40
41 if (is_little_endian) {
42 return ( *s | (s[1] << 8) | (s[2] << 16) | (s[3] << 24) );
43 }
44 else {
45 return ( s[3] | (s[2] << 8) | (s[1] << 16) | (*s << 24) );
46 }
47
48 return 0;
49 }
50
51 uint32_t
utf32_unicode_to_bytes(uint32_t cp,uint8_t * out_buf,uint32_t output_little_endian)52 utf32_unicode_to_bytes(uint32_t cp, uint8_t *out_buf, uint32_t output_little_endian) {
53 uint8_t *d = out_buf;
54
55 /* 0xd800 .. 0xdfff are ill-formed */
56 if (cp >= 0xd800 && cp <= 0xdfff) {
57 *d = 0;
58 return 0;
59 }
60
61 if (output_little_endian) {
62 *d++ = cp & 0xff;
63 *d++ = (cp & 0xff00) >> 8;
64 *d++ = (cp & 0xff0000) >> 16;
65 *d++ = (cp & 0xff000000) >> 24;
66
67 return 4;
68 }
69 else {
70 *d++ = (cp & 0xff000000) >> 24;
71 *d++ = (cp & 0xff0000) >> 16;
72 *d++ = (cp & 0xff00) >> 8;
73 *d++ = cp & 0xff;
74
75 return 4;
76 }
77
78 return 0;
79 }
80
81
82