score: Add _IO_Base64url()

Update #4267.
This commit is contained in:
Sebastian Huber
2021-02-23 13:25:00 +01:00
parent da8ad67e88
commit 5f8bc839e8
3 changed files with 94 additions and 25 deletions

View File

@@ -64,15 +64,21 @@ int _IO_Vprintf(
* After word length of output characters produced by the encoding a word break * After word length of output characters produced by the encoding a word break
* is produced. * is produced.
* *
* @param put_char The put character function. * @param put_char is the put character function used to output the encoded
* @param arg The argument passed to the put character function. * source buffer.
* @param src The pointer to the source buffer begin. *
* @param srclen The length of the source buffer in bytes. * @param arg is the argument passed to the put character function.
* @param wordbreak The word break string. *
* @param wordlen The word length in bytes. If the word length is less than * @param src is the pointer to the source buffer begin.
*
* @param srclen is the length of the source buffer in bytes.
*
* @param wordbreak is the word break string.
*
* @param wordlen is the word length in bytes. If the word length is less than
* four, then a word length of four will be used. * four, then a word length of four will be used.
* *
* @return The count of output characters. * @return Returns the count of output characters.
*/ */
int _IO_Base64( int _IO_Base64(
IO_Put_char put_char, IO_Put_char put_char,
@@ -83,6 +89,37 @@ int _IO_Base64(
int wordlen int wordlen
); );
/**
* @brief Outputs the source buffer in base64url encoding.
*
* After word length of output characters produced by the encoding a word break
* is produced.
*
* @param put_char is the put character function used to output the encoded
* source buffer.
*
* @param arg is the argument passed to the put character function.
*
* @param src is the pointer to the source buffer begin.
*
* @param srclen is the length of the source buffer in bytes.
*
* @param wordbreak is the word break string.
*
* @param wordlen is the word length in bytes. If the word length is less than
* four, then a word length of four will be used.
*
* @return Returns the count of output characters.
*/
int _IO_Base64url(
IO_Put_char put_char,
void *arg,
const void *src,
size_t len,
const char *wordbreak,
int wordlen
);
/** @} */ /** @} */
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -6,11 +6,11 @@
* @ingroup RTEMSScoreIO * @ingroup RTEMSScoreIO
* *
* @brief This source file contains the implementation of * @brief This source file contains the implementation of
* _IO_Base64(). * _IO_Base64() and _IO_Base64url().
*/ */
/* /*
* Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de) * Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de)
* Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001, 2003 Internet Software Consortium. * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
* *
@@ -29,17 +29,15 @@
#include <rtems/score/io.h> #include <rtems/score/io.h>
static const char base64[] = static void
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; _IO_Put(int c, void *arg, IO_Put_char put_char)
static void _IO_Put(int c, void *arg, IO_Put_char put_char)
{ {
(*put_char)(c, arg); (*put_char)(c, arg);
} }
int static int
_IO_Base64(IO_Put_char put_char, void *arg, const void *src, size_t srclen, _IO_Base64_with_encoding(IO_Put_char put_char, void *arg, const void *src,
const char *wordbreak, int wordlen) size_t srclen, const char *wordbreak, int wordlen, const char *encoding)
{ {
unsigned int loops = 0; unsigned int loops = 0;
const unsigned char *in = src; const unsigned char *in = src;
@@ -50,12 +48,12 @@ _IO_Base64(IO_Put_char put_char, void *arg, const void *src, size_t srclen,
} }
while (srclen > 2) { while (srclen > 2) {
_IO_Put(base64[(in[0]>>2)&0x3f], arg, put_char); _IO_Put(encoding[(in[0]>>2)&0x3f], arg, put_char);
_IO_Put(base64[((in[0]<<4)&0x30)| _IO_Put(encoding[((in[0]<<4)&0x30)|
((in[1]>>4)&0x0f)], arg, put_char); ((in[1]>>4)&0x0f)], arg, put_char);
_IO_Put(base64[((in[1]<<2)&0x3c)| _IO_Put(encoding[((in[1]<<2)&0x3c)|
((in[2]>>6)&0x03)], arg, put_char); ((in[2]>>6)&0x03)], arg, put_char);
_IO_Put(base64[in[2]&0x3f], arg, put_char); _IO_Put(encoding[in[2]&0x3f], arg, put_char);
in += 3; in += 3;
srclen -= 3; srclen -= 3;
out += 4; out += 4;
@@ -74,18 +72,40 @@ _IO_Base64(IO_Put_char put_char, void *arg, const void *src, size_t srclen,
} }
} }
if (srclen == 2) { if (srclen == 2) {
_IO_Put(base64[(in[0]>>2)&0x3f], arg, put_char); _IO_Put(encoding[(in[0]>>2)&0x3f], arg, put_char);
_IO_Put(base64[((in[0]<<4)&0x30)| _IO_Put(encoding[((in[0]<<4)&0x30)|
((in[1]>>4)&0x0f)], arg, put_char); ((in[1]>>4)&0x0f)], arg, put_char);
_IO_Put(base64[((in[1]<<2)&0x3c)], arg, put_char); _IO_Put(encoding[((in[1]<<2)&0x3c)], arg, put_char);
_IO_Put('=', arg, put_char); _IO_Put('=', arg, put_char);
out += 4; out += 4;
} else if (srclen == 1) { } else if (srclen == 1) {
_IO_Put(base64[(in[0]>>2)&0x3f], arg, put_char); _IO_Put(encoding[(in[0]>>2)&0x3f], arg, put_char);
_IO_Put(base64[((in[0]<<4)&0x30)], arg, put_char); _IO_Put(encoding[((in[0]<<4)&0x30)], arg, put_char);
_IO_Put('=', arg, put_char); _IO_Put('=', arg, put_char);
_IO_Put('=', arg, put_char); _IO_Put('=', arg, put_char);
out += 4; out += 4;
} }
return out; return out;
} }
static const char base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
int
_IO_Base64(IO_Put_char put_char, void *arg, const void *src, size_t srclen,
const char *wordbreak, int wordlen)
{
return _IO_Base64_with_encoding(put_char, arg, src, srclen, wordbreak,
wordlen, base64);
}
static const char base64url[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";
int
_IO_Base64url(IO_Put_char put_char, void *arg, const void *src, size_t srclen,
const char *wordbreak, int wordlen)
{
return _IO_Base64_with_encoding(put_char, arg, src, srclen, wordbreak,
wordlen, base64url);
}

View File

@@ -242,6 +242,17 @@ static void test_io_base64( test_context *ctx )
rtems_test_assert( n == 0 ); rtems_test_assert( n == 0 );
} }
static void test_io_base64url( test_context *ctx )
{
unsigned char buf[] = { 0, 0, 62, 0, 0, 63 };
int n;
clear( ctx );
n = _IO_Base64url( put_char, ctx, buf, sizeof( buf ), "\n", 0 );
rtems_test_assert( n == 9 );
rtems_test_assert( strcmp( ctx->buf, "AAA-\nAAA_" ) == 0 );
}
static rtems_task Init( static rtems_task Init(
rtems_task_argument argument rtems_task_argument argument
) )
@@ -257,6 +268,7 @@ static rtems_task Init(
do_getchark(); do_getchark();
test_io_printf(&test_instance); test_io_printf(&test_instance);
test_io_base64(&test_instance); test_io_base64(&test_instance);
test_io_base64url(&test_instance);
TEST_END(); TEST_END();
rtems_test_exit( 0 ); rtems_test_exit( 0 );