Ticket #43: 0005-fix-XmlPushParser-so-it-cleans-up-on-reset-thanks-F.patch
| File 0005-fix-XmlPushParser-so-it-cleans-up-on-reset-thanks-F.patch, 3.5 kB (added by tmm1, 5 months ago) |
|---|
-
a/vendor/eventmachine_xmlpushparser/ext/rubymain.cpp
old new 45 45 46 46 void ConsumeData (const char *, int); 47 47 void Close(); 48 void ScheduleReset(); 48 49 49 50 void SaxStartDocument(); 50 51 void SaxEndDocument(); … … 56 57 private: 57 58 VALUE Myself; 58 59 xmlParserCtxtPtr Context; 60 bool bReset; 59 61 }; 60 62 61 63 … … 139 141 ****************************************/ 140 142 141 143 RubyXmlPushParser_t::RubyXmlPushParser_t (VALUE v): 142 Myself (v) 144 Myself (v), 145 bReset (false) 143 146 { 144 147 /* Note that we're bypassing the typical convention of passing the 145 148 * first four bytes of the document to the parser-create function. … … 167 170 * the encoding of a new document), the library's internal buffers 168 171 * are very small. 169 172 */ 170 while (length > 0) { 171 int l = length; 172 if (l > 50) 173 l = 50; 174 xmlParseChunk (Context, data, l, 0); 175 data += l; 176 length -= l; 173 for (int i=0; i < length; i++) { 174 if (bReset) { 175 // don't send a good-bye kiss to the existing context because it'll 176 // probably kick out a malformation error. 177 xmlFreeParserCtxt (Context); 178 Context = xmlCreatePushParserCtxt (&saxHandler, (void*)this, "", 0, ""); 179 if (!Context) 180 throw std::runtime_error ("no push-parser context"); 181 bReset = false; 182 } 183 xmlParseChunk (Context, data+i, 1, 0); 177 184 } 178 185 } 179 186 180 187 188 /********************************** 189 RubyXmlPushParser_t::ScheduleReset 190 **********************************/ 191 192 void RubyXmlPushParser_t::ScheduleReset() 193 { 194 bReset = true; 195 } 196 181 197 /************************** 182 198 RubyXmlPushParser_t::Close 183 199 **************************/ … … 281 297 282 298 void RubyXmlPushParser_t::SaxError() 283 299 { 284 rb_funcall (Myself, rb_intern ("error"), 1, INT2FIX (xmlCtxtGetLastError (Context)->code)); 285 rb_funcall (Myself, rb_intern ("close_connection"), 0); 300 int e = xmlCtxtGetLastError (Context)->code; 301 if (e == XML_ERR_DOCUMENT_END) 302 ; 303 else { 304 rb_funcall (Myself, rb_intern ("error"), 1, INT2FIX (e)); 305 rb_funcall (Myself, rb_intern ("close_connection"), 0); 306 } 286 307 } 287 308 288 309 /*********** … … 320 341 321 342 static VALUE t_unbind (VALUE self) 322 343 { 323 RubyXmlPushParser_t *pp = new RubyXmlPushParser_t (self);344 RubyXmlPushParser_t *pp = (RubyXmlPushParser_t*)(NUM2INT (rb_ivar_get (self, rb_intern ("@xml__push__parser__object")))); 324 345 if (!pp) 325 346 throw std::runtime_error ("no xml push-parser object"); 326 347 pp->Close(); 327 348 return Qnil; 328 349 } 329 350 351 352 /************** 353 t_reset_parser 354 **************/ 355 356 static VALUE t_reset_parser (VALUE self) 357 { 358 RubyXmlPushParser_t *pp = (RubyXmlPushParser_t*)(NUM2INT (rb_ivar_get (self, rb_intern ("@xml__push__parser__object")))); 359 if (!pp) 360 throw std::runtime_error ("no xml push-parser object"); 361 pp->ScheduleReset(); 362 363 return Qnil; 364 } 365 330 366 /**************** 331 367 t_start_document 332 368 ****************/ … … 426 462 rb_define_method (XmlModule, "end_element", (VALUE(*)(...))t_end_element, 1); 427 463 rb_define_method (XmlModule, "characters", (VALUE(*)(...))t_characters, 1); 428 464 rb_define_method (XmlModule, "error", (VALUE(*)(...))t_error, 1); 429 } 430 465 rb_define_method (XmlModule, "reset_parser", (VALUE(*)(...))t_reset_parser, 0); 466 }
