PageRenderTime 83ms CodeModel.GetById 66ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/llbase32.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 238 lines | 57 code | 22 blank | 159 comment | 7 complexity | 3b8009b81986f59622acc8ee0c1e58a9 MD5 | raw file
  1/** 
  2 * @file llbase32.cpp
  3 * @brief base32 encoding that returns a std::string
  4 * @author James Cook
  5 *
  6 * Based on code from bitter
  7 * http://ghostwhitecrab.com/bitter/
  8 *
  9 * Some parts of this file are:
 10 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
 11 * Second Life Viewer Source Code
 12 * Copyright (C) 2010, Linden Research, Inc.
 13 * 
 14 * This library is free software; you can redistribute it and/or
 15 * modify it under the terms of the GNU Lesser General Public
 16 * License as published by the Free Software Foundation;
 17 * version 2.1 of the License only.
 18 * 
 19 * This library is distributed in the hope that it will be useful,
 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 22 * Lesser General Public License for more details.
 23 * 
 24 * You should have received a copy of the GNU Lesser General Public
 25 * License along with this library; if not, write to the Free Software
 26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 27 * 
 28 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 29 * $/LicenseInfo$
 30 */
 31
 32/**
 33 * Copyright (c) 2006 Christian Biere <christianbiere@gmx.de>
 34 * All rights reserved.
 35 *
 36 * Redistribution and use in source and binary forms, with or without
 37 * modification, are permitted provided that the following conditions
 38 * are met:
 39 *
 40 * 1. Redistributions of source code must retain the above copyright
 41 *    notice, this list of conditions and the following disclaimer.
 42 * 2. Redistributions in binary form must reproduce the above copyright
 43 *    notice, this list of conditions and the following disclaimer in the
 44 *    documentation and/or other materials provided with the distribution.
 45 * 3. Neither the name of the authors nor the names of its contributors
 46 *    may be used to endorse or promote products derived from this software
 47 *    without specific prior written permission.
 48 *
 49 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 52 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 59 * SUCH DAMAGE.
 60 */
 61
 62#include "linden_common.h"
 63
 64#include "llbase32.h"
 65
 66#include <string>
 67
 68// bitter - base32.c starts here
 69
 70/*
 71 * See RFC 3548 for details about Base 32 encoding:
 72 *  http://www.faqs.org/rfcs/rfc3548.html
 73 */
 74
 75static const char base32_alphabet[32] = {
 76  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
 77  'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
 78  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
 79  'Y', 'Z', '2', '3', '4', '5', '6', '7'
 80};
 81
 82size_t
 83base32_encode(char *dst, size_t size, const void *data, size_t len)
 84{
 85  size_t i = 0;
 86  const U8 *p = (const U8*)data;
 87  const char *end = &dst[size];
 88  char *q = dst;
 89
 90  do {
 91    size_t j, k;
 92    U8 x[5];
 93    char s[8];
 94
 95    switch (len - i) {
 96    case 4: k = 7; break;
 97    case 3: k = 5; break;
 98    case 2: k = 3; break;
 99    case 1: k = 2; break;
100    default:
101      k = 8;
102    }
103
104    for (j = 0; j < 5; j++)
105      x[j] = i < len ? p[i++] : 0;
106
107/*
108  +-------+-----------+--------+
109  | target| source    | source |
110  | byte  | bits      | byte   |
111  +-------+-----------+--------+
112  |     0 | 7 6 5 4 3 | 0      |
113  |     1 | 2 1 0 7 6 | 0-1    |
114  |     2 | 5 4 3 2 1 | 1      |
115  |     3 | 0 7 6 5 4 | 1-2    |
116  |     4 | 3 2 1 0 7 | 2-3    |
117  |     5 | 6 5 4 3 2 | 3      |
118  |     6 | 1 0 7 6 5 | 3-4    |
119  |     7 | 4 3 2 1 0 | 4      |
120  +-------+-----------+--------+
121  
122*/
123    
124    s[0] =  (x[0] >> 3);
125    s[1] = ((x[0] & 0x07) << 2) | (x[1] >> 6);
126    s[2] =  (x[1] >> 1) & 0x1f;
127    s[3] = ((x[1] & 0x01) << 4) | (x[2] >> 4);
128    s[4] = ((x[2] & 0x0f) << 1) | (x[3] >> 7);
129    s[5] =  (x[3] >> 2) & 0x1f;
130    s[6] = ((x[3] & 0x03) << 3) | (x[4] >> 5);
131    s[7] =   x[4] & 0x1f;
132
133    for (j = 0; j < k && q != end; j++)
134      *q++ = base32_alphabet[(U8) s[j]];
135
136  } while (i < len);
137
138  return q - dst;
139}
140
141/* *TODO: Implement base32 encode.
142
143static inline int
144ascii_toupper(int c)
145{
146  return c >= 97 && c <= 122 ? c - 32 : c;
147}
148
149static inline int
150ascii_tolower(int c)
151{
152  return c >= 65 && c <= 90 ? c + 32 : c;
153}
154
155
156static char base32_map[(unsigned char) -1];
157
158size_t
159base32_decode(char *dst, size_t size, const void *data, size_t len)
160{
161  const char *end = &dst[size];
162  const unsigned char *p = data;
163  char *q = dst;
164  size_t i;
165  unsigned max_pad = 3;
166
167  if (0 == base32_map[0]) {
168    for (i = 0; i < LL_ARRAY_SIZE(base32_map); i++) {
169      const char *x;
170      
171      x = memchr(base32_alphabet, ascii_toupper(i), sizeof base32_alphabet);
172      base32_map[i] = x ? (x - base32_alphabet) : (unsigned char) -1;
173    }
174  }
175  
176  for (i = 0; i < len && max_pad > 0; i++) {
177    unsigned char c;
178    char s[8];
179    size_t j;
180
181    c = p[i];
182    if ('=' == c) {
183      max_pad--;
184      c = 0;
185    } else {
186      c = base32_map[c];
187      if ((unsigned char) -1 == c) {
188        return -1;
189      }
190    }
191
192    j = i % LL_ARRAY_SIZE(s);
193    s[j] = c;
194
195    if (7 == j) {
196      char b[5];
197
198      b[0] = ((s[0] << 3) & 0xf8) | ((s[1] >> 2) & 0x07);
199      b[1] = ((s[1] & 0x03) << 6) | ((s[2] & 0x1f) << 1) | ((s[3] >> 4) & 1);
200      b[2] = ((s[3] & 0x0f) << 4) | ((s[4] >> 1) & 0x0f);
201      b[3] = ((s[4] & 1) << 7) | ((s[5] & 0x1f) << 2) | ((s[6] >> 3) & 0x03);
202      b[4] = ((s[6] & 0x07) << 5) | (s[7] & 0x1f);
203
204      for (j = 0; j < LL_ARRAY_SIZE(b); j++) {
205        if (q != end)
206          *q = b[j];
207        q++;
208      }
209    }
210  }
211
212  return q - dst;
213}
214*/
215
216
217// The following is
218// Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
219// static
220std::string LLBase32::encode(const U8* input, size_t input_size)
221{
222	std::string output;
223	if (input)
224	{
225		// Each 5 byte chunk of input is represented by an
226		// 8 byte chunk of output.
227		size_t input_chunks = (input_size + 4) / 5;
228		size_t output_size = input_chunks * 8;
229
230		output.resize(output_size);
231
232		size_t encoded = base32_encode(&output[0], output_size, input, input_size);
233
234		llinfos << "encoded " << encoded << " into buffer of size "
235			<< output_size << llendl;
236	}
237	return output;
238}