Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:21

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2020 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include <rtems/recorddump.h>
0033 
0034 #include <limits.h>
0035 #include <string.h>
0036 
0037 #include <rtems/base64.h>
0038 
0039 static void *dump_zalloc( void *opaque, unsigned items, unsigned size )
0040 {
0041   rtems_record_dump_base64_zlib_context *ctx;
0042   char                                  *mem_begin;
0043   size_t                                 mem_available;
0044 
0045   ctx = opaque;
0046   size *= items;
0047   mem_available = ctx->mem_available;
0048 
0049   if ( mem_available < size ) {
0050     return NULL;
0051   }
0052 
0053   mem_begin = ctx->mem_begin;
0054   ctx->mem_begin = mem_begin + size;
0055   ctx->mem_available = mem_available - size;
0056   return mem_begin;
0057 }
0058 
0059 static void dump_zfree( void *opaque, void *ptr )
0060 {
0061   (void) opaque;
0062   (void) ptr;
0063 }
0064 
0065 static void put_char( int c, void *arg )
0066 {
0067   rtems_record_dump_base64_zlib_context *ctx;
0068 
0069   ctx = arg;
0070 
0071   ( *ctx->put_char )( c, ctx->arg );
0072   ++ctx->out;
0073 
0074   if ( ctx->out >= 76 ) {
0075     ctx->out = 0;
0076     ( *ctx->put_char )( '\n', ctx->arg );
0077   }
0078 }
0079 
0080 static void chunk( void *arg, const void *data, size_t length )
0081 {
0082   rtems_record_dump_base64_zlib_context *ctx;
0083 
0084   ctx = arg;
0085   ctx->stream.next_in = RTEMS_DECONST( void *, data );
0086   ctx->stream.avail_in = length;
0087 
0088   while ( ctx->stream.avail_in > 0 ) {
0089     int err;
0090 
0091     err = deflate( &ctx->stream, Z_NO_FLUSH );
0092     if ( err != Z_OK ) {
0093       return;
0094     }
0095 
0096     if ( ctx->stream.avail_out == 0 ) {
0097       ctx->stream.next_out = &ctx->buf[ 0 ];
0098       ctx->stream.avail_out = sizeof( ctx->buf );
0099 
0100       _Base64_Encode( put_char, ctx, ctx->buf, sizeof( ctx->buf ), NULL, INT_MAX );
0101     }
0102   }
0103 }
0104 
0105 static void flush( rtems_record_dump_base64_zlib_context *ctx )
0106 {
0107   while ( true ) {
0108     int err;
0109 
0110     err = deflate( &ctx->stream, Z_FINISH );
0111     if ( err != Z_OK ) {
0112       break;
0113     }
0114 
0115     if ( ctx->stream.avail_out == 0 ) {
0116       ctx->stream.next_out = &ctx->buf[ 0 ];
0117       ctx->stream.avail_out = sizeof( ctx->buf );
0118 
0119       _Base64_Encode( put_char, ctx, ctx->buf, sizeof( ctx->buf ), NULL, INT_MAX );
0120     }
0121   }
0122 
0123   _Base64_Encode(
0124     put_char,
0125     ctx,
0126     ctx->buf,
0127     sizeof( ctx->buf ) - ctx->stream.avail_out,
0128     NULL,
0129     INT_MAX
0130   );
0131 }
0132 
0133 void rtems_record_dump_zlib_base64(
0134   rtems_record_dump_base64_zlib_context *ctx,
0135   void                                ( *put_char )( int, void * ),
0136   void                                  *arg
0137 )
0138 {
0139   int err;
0140 
0141   ctx->put_char = put_char;
0142   ctx->arg = arg;
0143   ctx->out = 0;
0144   ctx->stream.zalloc = dump_zalloc;
0145   ctx->stream.zfree = dump_zfree;
0146   ctx->stream.opaque = ctx;
0147   ctx->mem_begin = &ctx->mem[ 0 ];
0148   ctx->mem_available = sizeof( ctx->mem );
0149 
0150   err = deflateInit( &ctx->stream, Z_BEST_COMPRESSION );
0151   if (err != Z_OK) {
0152     return;
0153   }
0154 
0155   ctx->stream.next_out = &ctx->buf[ 0 ];
0156   ctx->stream.avail_out = sizeof( ctx->buf );
0157 
0158   rtems_record_dump( chunk, ctx );
0159   flush( ctx );
0160   deflateEnd( &ctx->stream );
0161 }