summaryrefslogtreecommitdiff
path: root/enc/trans/newline.trans
blob: 7b10d368b1b194dd475a2827a5a742688b2bfb90 (plain)
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
#include "transcode_data.h"

<%
  map_normalize = {}
  map_normalize["{00-ff}"] = :func_so

  transcode_generate_node(ActionMap.parse(map_normalize), "universal_newline")

  map_crlf = {}
  map_crlf["{00-09,0b-ff}"] = :nomap
  map_crlf["0a"] = "0d0a"

  transcode_generate_node(ActionMap.parse(map_crlf), "crlf_newline")

  map_cr = {}
  map_cr["{00-09,0b-ff}"] = :nomap
  map_cr["0a"] = "0d"

  transcode_generate_node(ActionMap.parse(map_cr), "cr_newline")
%>

<%= transcode_generated_code %>

#define NORMAL 0
#define JUST_AFTER_CR 1

static int
universal_newline_init(void *statep)
{
    unsigned char *sp = statep;
    *sp = NORMAL;
    return 0;
}

static int
fun_so_universal_newline(void *statep, const unsigned char* s, size_t l, unsigned char* o)
{
    unsigned char *sp = statep;
    int len;
    if (s[0] == '\n') {
        if (*sp == NORMAL) {
            o[0] = '\n';
            len = 1;
        }
        else { /* JUST_AFTER_CR */
            len = 0;
        }
        *sp = NORMAL;
    }
    else if (s[0] == '\r') {
        o[0] = '\n';
        len = 1;
        *sp = JUST_AFTER_CR;
    }
    else {
        o[0] = s[0];
        len = 1;
        *sp = NORMAL;
    }
    return len;
}

static const rb_transcoder
rb_universal_newline = {
    "universal_newline", "", universal_newline,
    TRANSCODE_TABLE_INFO,
    1, /* input_unit_length */
    1, /* max_input */
    1, /* max_output */
    stateful_decoder, /* stateful_type */
    1, universal_newline_init, universal_newline_init, /* state_size, state_init, state_fini */
    NULL, NULL, NULL, fun_so_universal_newline
};

static const rb_transcoder
rb_crlf_newline = {
    "", "crlf_newline", crlf_newline,
    TRANSCODE_TABLE_INFO,
    1, /* input_unit_length */
    1, /* max_input */
    2, /* max_output */
    stateless_converter, /* stateful_type */
    0, NULL, NULL, /* state_size, state_init, state_fini */
    NULL, NULL, NULL, NULL
};

static const rb_transcoder
rb_cr_newline = {
    "", "cr_newline", cr_newline,
    TRANSCODE_TABLE_INFO,
    1, /* input_unit_length */
    1, /* max_input */
    1, /* max_output */
    stateless_converter, /* stateful_type */
    0, NULL, NULL, /* state_size, state_init, state_fini */
    NULL, NULL, NULL, NULL
};

void
Init_newline(void)
{
    rb_register_transcoder(&rb_universal_newline);
    rb_register_transcoder(&rb_crlf_newline);
    rb_register_transcoder(&rb_cr_newline);
}