File: cencode.c

package info (click to toggle)
p4est 2.3.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,536 kB
  • sloc: ansic: 87,528; makefile: 855; sh: 635; perl: 272; python: 226; awk: 40; javascript: 23
file content (124 lines) | stat: -rw-r--r-- 3,242 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

/*
 * adapted from libb64 by CB
 */

/*
cencoder.c - c source to a base64 encoding algorithm implementation

This is part of the libb64 project, and has been placed in the public domain.
For details, see http://sourceforge.net/projects/libb64
*/

#include "libb64.h"

const int           CHARS_PER_LINE = 72;

static inline char
base64_encode_value (char value_in)
{
  static const char  *encoding =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

  return value_in > 63 ? '=' : encoding[(int) value_in];
}

void
base64_init_encodestate (base64_encodestate * state_in)
{
  state_in->step = step_A;
  state_in->result = 0;
  state_in->stepcount = 0;
}

size_t
base64_encode_block (const char *plaintext_in, size_t length_in,
                     char *code_out, base64_encodestate * state_in)
{
  /*@unused@ */
  const char         *plainchar = plaintext_in;
  /*@unused@ */
  const char         *const plaintextend = plaintext_in + length_in;
  char               *codechar = code_out;
  char                result;
  /*@unused@ */
  char                fragment;

  result = state_in->result;

  switch (state_in->step) {

#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"

    while (1) {
  case step_A:
      if (plainchar == plaintextend) {
        state_in->result = result;
        state_in->step = step_A;
        return (size_t) (codechar - code_out);
      }
      fragment = *plainchar++;
      result = (char) ((fragment & 0x0fc) >> 2);
      *codechar++ = base64_encode_value (result);
      result = (char) ((fragment & 0x003) << 4);
  case step_B:
      if (plainchar == plaintextend) {
        state_in->result = result;
        state_in->step = step_B;
        return (size_t) (codechar - code_out);
      }
      fragment = *plainchar++;
      result = (char) (result | ((fragment & 0x0f0) >> 4));
      *codechar++ = base64_encode_value (result);
      result = (char) ((fragment & 0x00f) << 2);
  case step_C:
      if (plainchar == plaintextend) {
        state_in->result = result;
        state_in->step = step_C;
        return (size_t) (codechar - code_out);
      }
      fragment = *plainchar++;
      result = (char) (result | ((fragment & 0x0c0) >> 6));
      *codechar++ = base64_encode_value (result);
      result = (char) ((fragment & 0x03f) >> 0);
      *codechar++ = base64_encode_value (result);

      ++(state_in->stepcount);
      /* CB: disable wrapping by default */
#ifdef SC_BASE64_WRAP
      if (state_in->stepcount == CHARS_PER_LINE / 4) {
        *codechar++ = '\n';
        state_in->stepcount = 0;
      }
#endif
    }
  }
  /* control should not reach here */
  return (size_t) (codechar - code_out);
}

size_t
base64_encode_blockend (char *code_out, base64_encodestate * state_in)
{
  char               *codechar = code_out;

  switch (state_in->step) {
  case step_B:
    *codechar++ = base64_encode_value (state_in->result);
    *codechar++ = '=';
    *codechar++ = '=';
    break;
  case step_C:
    *codechar++ = base64_encode_value (state_in->result);
    *codechar++ = '=';
    break;
  case step_A:
    break;
  }
  /* CB: remove final newline by default */
#ifdef SC_BASE64_WRAP
  *codechar++ = '\n';
#endif

  return (size_t) (codechar - code_out);
}