1/*
2 * Copyright (c) 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "windlocl.h"
35#include <assert.h>
36
37static int
38put_char(uint32_t *out, size_t *o, uint32_t c, size_t out_len)
39{
40    if (*o >= out_len)
41	return 1;
42    out[*o] = c;
43    (*o)++;
44    return 0;
45}
46
47int
48_wind_ldap_case_exact_attribute(const uint32_t *tmp,
49				size_t olen,
50				uint32_t *out,
51				size_t *out_len)
52{
53    size_t o = 0, i = 0;
54
55    if (olen == 0) {
56	*out_len = 0;
57	return 0;
58    }
59
60    if (put_char(out, &o, 0x20, *out_len))
61	return WIND_ERR_OVERRUN;
62    while(i < olen && tmp[i] == 0x20) /* skip initial spaces */
63	i++;
64
65    while (i < olen) {
66	if (tmp[i] == 0x20) {
67	    if (put_char(out, &o, 0x20, *out_len) ||
68		put_char(out, &o, 0x20, *out_len))
69		return WIND_ERR_OVERRUN;
70	    while(i < olen && tmp[i] == 0x20) /* skip middle spaces */
71		i++;
72	} else {
73	    if (put_char(out, &o, tmp[i++], *out_len))
74		return WIND_ERR_OVERRUN;
75	}
76    }
77    assert(o > 0);
78
79    /* only one spaces at the end */
80    if (o == 1 && out[0] == 0x20)
81	o = 0;
82    else if (out[o - 1] == 0x20) {
83	if (out[o - 2] == 0x20)
84	    o--;
85    } else
86	put_char(out, &o, 0x20, *out_len);
87
88    *out_len = o;
89
90    return 0;
91}
92