88 * Support for adding custom scheme handlers. */
99
1010static ic_scheme * first_scheme = 0 ;
11+ static int input_callbacks_registered = 0 ;
1112
12- int ic_match (char const * filename )
13+ static int ic_match (char const * filename );
14+ static void * ic_open (char const * filename );
15+ static int ic_read (void * context , char * buffer , int len );
16+ static int ic_close (void * context );
17+
18+ static void input_callbacks_register_once (void )
19+ {
20+ if (input_callbacks_registered )
21+ return ;
22+
23+ xmlRegisterInputCallbacks (ic_match , ic_open , ic_read , ic_close );
24+ input_callbacks_registered = 1 ;
25+ }
26+
27+ static char * ic_strdup (const char * string )
28+ {
29+ size_t length = strlen (string ) + 1 ;
30+ char * copy = ruby_xmalloc (length );
31+ memcpy (copy , string , length );
32+ return copy ;
33+ }
34+
35+ static void ic_scheme_free (ic_scheme * scheme )
36+ {
37+ rb_gc_unregister_address (& scheme -> class );
38+ ruby_xfree (scheme -> scheme_name );
39+ ruby_xfree (scheme );
40+ }
41+
42+ static int ic_match (char const * filename )
1343{
1444 ic_scheme * scheme ;
1545
@@ -27,7 +57,7 @@ int ic_match(char const *filename)
2757 return 0 ;
2858}
2959
30- void * ic_open (char const * filename )
60+ static void * ic_open (char const * filename )
3161{
3262 ic_doc_context * ic_doc ;
3363 ic_scheme * scheme ;
@@ -38,12 +68,11 @@ void* ic_open(char const *filename)
3868 {
3969 if (!xmlStrncasecmp (BAD_CAST filename , BAD_CAST scheme -> scheme_name , scheme -> name_len ))
4070 {
41- ic_doc = (ic_doc_context * ) malloc (sizeof (ic_doc_context ));
42-
4371 res = rb_funcall (scheme -> class , rb_intern ("document_query" ), 1 ,
4472 rb_str_new2 (filename ));
4573
46- ic_doc -> buffer = strdup (StringValuePtr (res ));
74+ ic_doc = ALLOC (ic_doc_context );
75+ ic_doc -> buffer = ic_strdup (StringValueCStr (res ));
4776
4877 ic_doc -> bpos = ic_doc -> buffer ;
4978 ic_doc -> remaining = (int )strlen (ic_doc -> buffer );
@@ -54,7 +83,7 @@ void* ic_open(char const *filename)
5483 return 0 ;
5584}
5685
57- int ic_read (void * context , char * buffer , int len )
86+ static int ic_read (void * context , char * buffer , int len )
5887{
5988 ic_doc_context * ic_doc ;
6089 int ret_len ;
@@ -75,7 +104,7 @@ int ic_read(void *context, char *buffer, int len)
75104 return ret_len ;
76105}
77106
78- int ic_close (void * context )
107+ static int ic_close (void * context )
79108{
80109 ruby_xfree (((ic_doc_context * ) context )-> buffer );
81110 ruby_xfree (context );
@@ -90,7 +119,7 @@ int ic_close(void *context)
90119 */
91120static VALUE input_callbacks_register_input_callbacks (VALUE self )
92121{
93- xmlRegisterInputCallbacks ( ic_match , ic_open , ic_read , ic_close );
122+ input_callbacks_register_once ( );
94123 return (Qtrue );
95124}
96125
@@ -107,11 +136,14 @@ static VALUE input_callbacks_add_scheme(VALUE self, VALUE scheme_name,
107136
108137 Check_Type (scheme_name , T_STRING );
109138
110- scheme = (ic_scheme * ) malloc (sizeof (ic_scheme ));
139+ input_callbacks_register_once ();
140+
141+ scheme = ALLOC (ic_scheme );
111142 scheme -> next_scheme = 0 ;
112- scheme -> scheme_name = strdup ( StringValuePtr (scheme_name )); /* TODO alloc, dealloc */
143+ scheme -> scheme_name = ic_strdup ( StringValueCStr (scheme_name ));
113144 scheme -> name_len = (int )strlen (scheme -> scheme_name );
114- scheme -> class = class ; /* TODO alloc, dealloc */
145+ scheme -> class = class ;
146+ rb_gc_register_address (& scheme -> class );
115147
116148 //fprintf( stderr, "registered: %s, %d, %s\n", scheme->scheme_name, scheme->name_len, scheme->class );
117149
@@ -150,9 +182,7 @@ static VALUE input_callbacks_remove_scheme(VALUE self, VALUE scheme_name)
150182 {
151183 save_scheme = first_scheme -> next_scheme ;
152184
153- ruby_xfree (first_scheme -> scheme_name );
154- ruby_xfree (first_scheme );
155-
185+ ic_scheme_free (first_scheme );
156186 first_scheme = save_scheme ;
157187 return Qtrue ;
158188 }
@@ -165,9 +195,7 @@ static VALUE input_callbacks_remove_scheme(VALUE self, VALUE scheme_name)
165195 {
166196 save_scheme = scheme -> next_scheme -> next_scheme ;
167197
168- ruby_xfree (scheme -> next_scheme -> scheme_name );
169- ruby_xfree (scheme -> next_scheme );
170-
198+ ic_scheme_free (scheme -> next_scheme );
171199 scheme -> next_scheme = save_scheme ;
172200 return Qtrue ;
173201 }
0 commit comments