1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 2020-2021 Free Software Foundation, Inc.
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 3 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General
15    Public License along with this library.  If not, see
16    <http://www.gnu.org/licenses/>. */
17 
18 /*
19  * Functions for dealing with message part coordinates.
20  */
21 
22 #include <config.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <mailutils/message.h>
26 
27 int
mu_coord_alloc(mu_coord_t * ptr,size_t n)28 mu_coord_alloc (mu_coord_t *ptr, size_t n)
29 {
30   mu_coord_t p = calloc (n + 1, sizeof (p[0]));
31   if (!p)
32     return errno;
33   p[0] = n;
34   *ptr = p;
35   return 0;
36 }
37 
38 int
mu_coord_realloc(mu_coord_t * ptr,size_t n)39 mu_coord_realloc (mu_coord_t *ptr, size_t n)
40 {
41   if (!ptr)
42     return EINVAL;
43   if (!*ptr)
44     return mu_coord_alloc (ptr, n);
45   else
46     {
47       size_t i = mu_coord_length (*ptr);
48       if (i != n)
49 	{
50 	  mu_coord_t nc = realloc (*ptr, (n + 1) * sizeof (nc[0]));
51 	  if (nc == NULL)
52 	    return ENOMEM;
53 	  while (++i <= n)
54 	    nc[i] = 0;
55 	  nc[0] = n;
56 	  *ptr = nc;
57 	}
58     }
59   return 0;
60 }
61 
62 int
mu_coord_dup(mu_coord_t orig,mu_coord_t * copy)63 mu_coord_dup (mu_coord_t orig, mu_coord_t *copy)
64 {
65   size_t i, n = mu_coord_length (orig);
66   int rc = mu_coord_alloc (copy, n);
67   if (rc)
68     return rc;
69   for (i = 1; i <= n; i++)
70     (*copy)[i] = orig[i];
71   return 0;
72 }
73 
74 static void
revstr(char * s,char * e)75 revstr (char *s, char *e)
76 {
77   while (s < e)
78     {
79       char t = *s;
80       *s++ = *--e;
81       *e = t;
82     }
83 }
84 
85 char *
mu_coord_part_string(mu_coord_t c,size_t dim)86 mu_coord_part_string (mu_coord_t c, size_t dim)
87 {
88   size_t len = 0;
89   size_t i;
90   char *result, *p;
91 
92   for (i = 1; i <= dim; i++)
93     {
94       size_t n = c[i];
95       do
96 	len++;
97       while (n /= 10);
98       len++;
99     }
100 
101   result = malloc (len);
102   if (!result)
103     return NULL;
104   p = result;
105 
106   for (i = 1; i <= dim; i++)
107     {
108       char *s;
109       size_t n = c[i];
110       if (i > 1)
111 	*p++ = '.';
112       s = p;
113       do
114 	{
115 	  unsigned x = n % 10;
116 	  *p++ = x + '0';
117 	}
118       while (n /= 10);
119       revstr(s, p);
120     }
121   *p = 0;
122 
123   return result;
124 }
125