1 /*
2 ** Copyright 2011 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 **
5 */
6 
7 #include	"unicode_config.h"
8 #include	"courier-unicode.h"
9 #include	<stdlib.h>
10 #include	<string.h>
11 
unicode_buf_init(struct unicode_buf * p,size_t max)12 void unicode_buf_init(struct unicode_buf *p, size_t max)
13 {
14 	p->ptr=0;
15 	p->size=0;
16 	p->len=0;
17 	p->max=max;
18 }
19 
unicode_buf_deinit(struct unicode_buf * p)20 void unicode_buf_deinit(struct unicode_buf *p)
21 {
22 	if (p->ptr)
23 		free(p->ptr);
24 }
25 
unicode_buf_append(struct unicode_buf * p,const char32_t * uc,size_t l)26 int unicode_buf_append(struct unicode_buf *p,
27 		       const char32_t *uc, size_t l)
28 {
29 	if (l > p->max-p->len)
30 		l=p->max-p->len;
31 
32 	if (p->len + l > p->size)
33 	{
34 		size_t n=(p->len + l) * 2;
35 		char32_t *newp;
36 
37 		if (n < 256)
38 			n=256;
39 
40 		if (n > p->max)
41 			n=p->max;
42 
43 		newp=p->ptr ? realloc(p->ptr, n * sizeof(char32_t))
44 			: malloc(n * sizeof(char32_t));
45 
46 		if (!newp)
47 			return -1;
48 
49 		p->ptr=newp;
50 		p->size=n;
51 	}
52 
53 	memcpy(p->ptr + p->len, uc, l * sizeof(char32_t));
54 
55 	p->len += l;
56 	return 0;
57 }
58 
unicode_buf_append_char(struct unicode_buf * dst,const char * str,size_t cnt)59 void unicode_buf_append_char(struct unicode_buf *dst,
60 			     const char *str,
61 			     size_t cnt)
62 {
63 	char32_t unicode_buf[256];
64 
65 	while (cnt)
66 	{
67 		size_t n=sizeof(unicode_buf)/sizeof(unicode_buf[0]), i;
68 
69 		if (n > cnt)
70 			n=cnt;
71 
72 		for (i=0; i<n; ++i)
73 			unicode_buf[i]=(unsigned char)str[i];
74 
75 		str += n;
76 		cnt -= n;
77 		unicode_buf_append(dst, unicode_buf, i);
78 	}
79 }
80 
unicode_buf_remove(struct unicode_buf * p,size_t pos,size_t cnt)81 void unicode_buf_remove(struct unicode_buf *p,
82 			size_t pos,
83 			size_t cnt)
84 {
85 	if (pos > p->len)
86 		pos=p->len;
87 
88 	if (cnt > p->len-pos)
89 		cnt=p->len-pos;
90 
91 	if (cnt)
92 		memmove(p->ptr+pos, p->ptr+pos+cnt,
93 			(p->len-pos-cnt) * sizeof(char32_t));
94 	p->len -= cnt;
95 }
96 
unicode_buf_cmp(const struct unicode_buf * a,const struct unicode_buf * b)97 int unicode_buf_cmp(const struct unicode_buf *a,
98 		    const struct unicode_buf *b)
99 {
100 	size_t i;
101 
102 	for (i=0; i<a->len && i<b->len; i++)
103 	{
104 		if (a->ptr[i] < b->ptr[i])
105 			return -1;
106 		if (a->ptr[i] > b->ptr[i])
107 			return 1;
108 	}
109 
110 	return (a->len < b->len ? -1:a->len > b->len ? 1:0);
111 }
112 
unicode_buf_cmp_str(const struct unicode_buf * p,const char * c,size_t cl)113 int unicode_buf_cmp_str(const struct unicode_buf *p, const char *c,
114 			size_t cl)
115 {
116 	size_t i;
117 
118 	for (i=0; i<p->len && i < cl; ++i)
119 	{
120 		if (p->ptr[i] < c[i])
121 			return -1;
122 
123 		if (p->ptr[i] > c[i])
124 			return 1;
125 	}
126 
127 	return (p->len < cl ? -1: p->len > cl ? 1:0);
128 }
129