File: cddb_util.c

package info (click to toggle)
libcddb 1.3.2-6
  • links: PTS
  • area: main
  • in suites: bullseye, buster
  • size: 2,276 kB
  • sloc: sh: 10,946; ansic: 4,721; makefile: 44
file content (112 lines) | stat: -rw-r--r-- 3,338 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
    $Id: cddb_util.c,v 1.7 2006/10/15 06:52:50 airborne Exp $

    Copyright (C) 2004, 2005 Kris Verbeeck <airborne@advalvas.be>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the
    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA  02111-1307, USA.
*/

#include "cddb/cddb_ni.h"

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif


int cddb_str_iconv(iconv_t cd, ICONV_CONST char *in, char **out)
{
#ifdef HAVE_ICONV_H
    size_t inlen, outlen;
    int buflen, rc;
    int len;                    /* number of chars in buffer */
    char *buf;

    inlen = strlen(in);
    buflen = 0;
    buf = NULL;
    do {
        outlen = inlen * 2;
        buflen += outlen;
        /* iconv() below changes the buf pointer:
         * - decrement to point at beginning of buffer before realloc
         * - re-increment to point at first free position after realloc
         */
        len = buflen - outlen;
        buf = (char*)realloc(buf - len, buflen) + len;
        if (buf == NULL) {
            /* XXX: report out of memory error */
            return FALSE;
        }
        rc = iconv(cd, &in, &inlen, &buf, &outlen);
        if ((rc == -1) && (errno != E2BIG)) {
            free(buf);
            return FALSE;       /* conversion failed */
        }
    } while (inlen != 0);
    len = buflen - outlen;
    buf -= len;                 /* reposition at begin of buffer */
    /* make a copy just big enough for the result */
    *out = malloc(len + 1);
    memcpy(*out, buf, len);
    *(*out + len) = '\0';
    free(buf);
#endif
    return TRUE;
}

/* Base64 decoder ring */
static char b64_vec[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

/* This routine will not check for buffer overflows.  Make sure the
 * output buffer is big enough.
 */
void cddb_b64_encode(char *dst, const char *src)
{
    unsigned int triplet = 0;
    int i = 0;

    while (*src) {
        triplet = (triplet << 8) | *src++;
        i++;
        if (i < 3) {
            continue;
        }
        *dst++ = b64_vec[(triplet >> 18)];
        *dst++ = b64_vec[(triplet >> 12) & 0x3f];
        *dst++ = b64_vec[(triplet >>  6) & 0x3f];
        *dst++ = b64_vec[(triplet >>  0) & 0x3f];
        i = 0;
        triplet = 0;
    }
    switch (i) {
    case 1:
        *dst++ = b64_vec[(triplet >> 2)];
        *dst++ = b64_vec[(triplet << 4) & 0x3f];
        *(unsigned short *)dst = 0x3d3d; /* add == */
        dst += 2;
        break;
    case 2:
        *dst++ = b64_vec[(triplet >> 10)];
        *dst++ = b64_vec[(triplet >>  4) & 0x3f];
        *dst++ = b64_vec[(triplet <<  2) & 0x3f];
        *dst++ = '=';
        break;
    }
    *dst = '\0';
}