New upstream release:
[debian/iodine.git] / src / encoding.c
1 /*
2  * Copyright (c) 2006-2007 Bjorn Andersson <flex@kryo.se>, Erik Ekman <yarrick@kryo.se>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <string.h>
18 #include "encoding.h"
19
20
21 int
22 unpack_data(char *buf, size_t buflen, char *data, size_t datalen, struct encoder *enc)
23 {
24         if (!enc->eats_dots())
25                 datalen = inline_undotify(data, datalen);
26         return enc->decode(buf, &buflen, data, datalen);
27 }
28
29 int 
30 inline_dotify(char *buf, size_t buflen)
31 {
32         unsigned dots;
33         unsigned pos;
34         unsigned total;
35         char *reader, *writer;
36
37         total = strlen(buf);
38         dots = total / 62;
39
40         writer = buf;
41         writer += total;
42         writer += dots;
43
44         total += dots;
45         if (strlen(buf) + dots > buflen) {
46                 writer = buf;
47                 writer += buflen;
48                 total = buflen;
49         }
50
51         reader = writer - dots;
52         pos = (unsigned) (reader - buf) + 1;
53
54         while (dots) {
55                 if (pos % 62 == 0) {
56                         *writer-- = '.';
57                         dots--;
58                 }
59                 *writer-- = *reader--;
60                 pos--;
61         }
62
63         /* return new length of string */
64         return total;
65 }
66
67 int 
68 inline_undotify(char *buf, size_t len)
69 {
70         unsigned pos;
71         unsigned dots;
72         char *reader, *writer;
73
74         writer = buf;
75         reader = writer;
76
77         pos = 0;
78         dots = 0;
79
80         while (pos < len) {
81                 if (*reader == '.') {
82                         reader++;
83                         pos++;
84                         dots++;
85                         continue;
86                 }
87                 *writer++ = *reader++;
88                 pos++;
89         }
90         
91         /* return new length of string */
92         return len - dots;
93 }