From d78eafbc5889e1f4602116cf6627b1f0dc1da100 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 4 Aug 2011 13:32:15 +0200 Subject: [PATCH] Base64 utilities public --- include/yaz/Makefile.am | 3 +- include/yaz/base64.h | 75 ++++++++++++++++++++++++++++++++ src/Makefile.am | 2 +- src/base64.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++ src/http.c | 52 +--------------------- src/srwutil.c | 47 +------------------- win/makefile | 1 + 7 files changed, 192 insertions(+), 99 deletions(-) create mode 100644 include/yaz/base64.h create mode 100644 src/base64.c diff --git a/include/yaz/Makefile.am b/include/yaz/Makefile.am index d43ed8f..823a8dd 100644 --- a/include/yaz/Makefile.am +++ b/include/yaz/Makefile.am @@ -3,7 +3,8 @@ noinst_HEADERS = icu_I18N.h -pkginclude_HEADERS= backend.h ccl.h ccl_xml.h cql.h rpn2cql.h rpn2solr.h \ +pkginclude_HEADERS= backend.h base64.h \ + ccl.h ccl_xml.h cql.h rpn2cql.h rpn2solr.h \ solr.h comstack.h \ diagbib1.h diagsrw.h diagsru_update.h sortspec.h log.h logrpn.h marcdisp.h \ nmem.h nmem_xml.h odr.h errno.h facet.h \ diff --git a/include/yaz/base64.h b/include/yaz/base64.h new file mode 100644 index 0000000..8db22dd --- /dev/null +++ b/include/yaz/base64.h @@ -0,0 +1,75 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2011 Index Data. + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Index Data nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file base64.h + * \brief Header for Base64 utilities + */ + +#ifndef YAZ_BASE64_H +#define YAZ_BASE64_H + +#include + +YAZ_BEGIN_CDECL + +/** \brief encodes Base64 string + \param in input string + \param out resulting Base64 string + + The out buffer should at least be of size: + + (strlen(in)*8) / 6 + 12 +*/ +YAZ_EXPORT +void yaz_base64encode(const char *in, char *out); + +/** \brief decodes Base64 string + \param in input Base64 encoded string + \param out result string + \retval 0 OK + \retval -1 invalid character + + The out buffer should at least be of size: + + strlen(in) +*/ +YAZ_EXPORT +int yaz_base64decode(const char *in, char *out); + +YAZ_END_CDECL + +#endif +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/Makefile.am b/src/Makefile.am index fc22046..8f66427 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -71,7 +71,7 @@ GEN_FILES = oid_std.c \ z-charneg.c \ ill-core.c item-req.c oclc-ill-req-ext.c -libyaz_la_SOURCES=version.c options.c log.c \ +libyaz_la_SOURCES=base64.c version.c options.c log.c \ $(GEN_FILES) \ marcdisp.c marc_read_xml.c marc_read_iso2709.c marc_read_line.c \ wrbuf.c oid_db.c errno.c \ diff --git a/src/base64.c b/src/base64.c new file mode 100644 index 0000000..d007a34 --- /dev/null +++ b/src/base64.c @@ -0,0 +1,111 @@ +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2011 Index Data + * See the file LICENSE for details. + */ +/** + * \file base64.c + * \brief Base64 encode/decode utilities + */ +#if HAVE_CONFIG_H +#include +#endif + +#include +#include + +void yaz_base64encode(const char *in, char *out) +{ + static char encoding[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + unsigned char buf[3]; + long n; + + while (*in != 0) + { + const char *pad = 0; + buf[0] = in[0]; + buf[1] = in[1]; + if (in[1] == 0) + { + buf[2] = 0; + pad = "=="; + } + else + { + buf[2] = in[2]; + if (in[2] == 0) + pad = "="; + } + + /* Treat three eight-bit numbers as on 24-bit number */ + n = (buf[0] << 16) + (buf[1] << 8) + buf[2]; + + /* Write the six-bit chunks out as four encoded characters */ + *out++ = encoding[(n >> 18) & 63]; + *out++ = encoding[(n >> 12) & 63]; + if (in[1] != 0) + *out++ = encoding[(n >> 6) & 63]; + if (in[1] != 0 && in[2] != 0) + *out++ = encoding[n & 63]; + + if (pad != 0) { + while (*pad != 0) + *out++ = *pad++; + break; + } + in += 3; + } + *out++ = 0; +} + +int yaz_base64decode(const char *in, char *out) +{ + const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/"; + int len = strlen(in); + + while (len >= 4) + { + char i0, i1, i2, i3; + char *p; + + if (!(p = strchr(map, in[0]))) + return -1; + i0 = p - map; + len--; + if (!(p = strchr(map, in[1]))) + return -1; + i1 = p - map; + len--; + *(out++) = i0 << 2 | i1 >> 4; + if (in[2] == '=') + break; + if (!(p = strchr(map, in[2]))) + return -1; + i2 = p - map; + len--; + *(out++) = i1 << 4 | i2 >> 2; + if (in[3] == '=') + break; + if (!(p = strchr(map, in[3]))) + return -1; + i3 = p - map; + len--; + *(out++) = i2 << 6 | i3; + + in += 4; + } + + *out = '\0'; + return 0; +} + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/http.c b/src/http.c index c05dc02..e6a04a5 100644 --- a/src/http.c +++ b/src/http.c @@ -15,63 +15,13 @@ #include #include #include +#include #ifdef WIN32 #define strncasecmp _strnicmp #define strcasecmp _stricmp #endif - -/* - * This function's counterpart, yaz_base64decode(), is in srwutil.c. - * I feel bad that they're not together, but each function is only - * needed in one place, and those places are not together. Maybe one - * day we'll move them into a new httputil.c, and declare them in a - * corresponding httputil.h - */ -static void yaz_base64encode(const char *in, char *out) -{ - static char encoding[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - unsigned char buf[3]; - long n; - - while (*in != 0) { - char *pad = 0; - buf[0] = in[0]; - buf[1] = in[1]; - if (in[1] == 0) { - buf[2] = 0; - pad = "=="; - } else { - buf[2] = in[2]; - if (in[2] == 0) - pad = "="; - } - - /* Treat three eight-bit numbers as on 24-bit number */ - n = (buf[0] << 16) + (buf[1] << 8) + buf[2]; - - /* Write the six-bit chunks out as four encoded characters */ - *out++ = encoding[(n >> 18) & 63]; - *out++ = encoding[(n >> 12) & 63]; - if (in[1] != 0) - *out++ = encoding[(n >> 6) & 63]; - if (in[1] != 0 && in[2] != 0) - *out++ = encoding[n & 63]; - - if (pad != 0) { - while (*pad != 0) - *out++ = *pad++; - break; - } - in += 3; - } - - *out++ = 0; -} - - static int decode_headers_content(ODR o, int off, Z_HTTP_Header **headers, char **content_buf, int *content_len) { diff --git a/src/srwutil.c b/src/srwutil.c index b906ec9..a04516a 100644 --- a/src/srwutil.c +++ b/src/srwutil.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "sru-p.h" @@ -85,52 +86,6 @@ const char *yaz_element_attribute_value_get(xmlNodePtr ptr, } #endif -static int yaz_base64decode(const char *in, char *out) -{ - const char *map = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz0123456789+/"; - int olen = 0; - int len = strlen(in); - - while (len >= 4) - { - char i0, i1, i2, i3; - char *p; - - if (!(p = strchr(map, in[0]))) - return 0; - i0 = p - map; - len--; - if (!(p = strchr(map, in[1]))) - return 0; - i1 = p - map; - len--; - *(out++) = i0 << 2 | i1 >> 4; - olen++; - if (in[2] == '=') - break; - if (!(p = strchr(map, in[2]))) - return 0; - i2 = p - map; - len--; - *(out++) = i1 << 4 | i2 >> 2; - olen++; - if (in[3] == '=') - break; - if (!(p = strchr(map, in[3]))) - return 0; - i3 = p - map; - len--; - *(out++) = i2 << 6 | i3; - olen++; - - in += 4; - } - - *out = '\0'; - return olen; -} - int yaz_srw_check_content_type(Z_HTTP_Response *hres) { const char *content_type = z_HTTP_header_lookup(hres->headers, diff --git a/win/makefile b/win/makefile index 54e3881..3f8cc6f 100644 --- a/win/makefile +++ b/win/makefile @@ -395,6 +395,7 @@ TEST_MUTEX_OBJS = \ $(OBJDIR)\test_mutex.obj MISC_OBJS= \ + $(OBJDIR)\base64.obj \ $(OBJDIR)\version.obj \ $(OBJDIR)\oid_std.obj \ $(OBJDIR)\eventl.obj \ -- 1.7.10.4