root/php/jlog.c

Revision 81ac86a15e3940ff0b787698853fb6a6157f800b, 15.4 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 7 years ago)

initial import with Ecelerity bits removed and some autoconf glue added in. Could certainly use some work on the build/install. Needs shared lib support for multiple platforms

  • Property mode set to 100644
Line 
1 /*
2    +----------------------------------------------------------------------+
3    | unknown license:                                                      |
4    +----------------------------------------------------------------------+
5    +----------------------------------------------------------------------+
6 */
7
8 /* $ Id: $ */
9
10 #include "php.h"
11 #include "php_ini.h"
12 #include "php_jlog.h"
13
14 #if HAVE_JLOG
15
16 typedef struct {
17   zend_object zo;
18   jlog_ctx *ctx;
19   char *path;
20   jlog_id start;
21   jlog_id last;
22   jlog_id end;
23   int auto_checkpoint;
24 } jlog_obj;
25
26 static zend_class_entry * Jlog_ce_ptr = NULL;
27 static zend_class_entry * Jlog_Writer_ce_ptr = NULL;
28 static zend_class_entry * Jlog_Reader_ce_ptr = NULL;
29 static zend_object_handlers jlog_object_handlers;
30
31
32 static void FREE_JLOG_OBJ(jlog_obj *intern)
33 {
34   if(intern) {
35     if(intern->ctx) {
36       jlog_ctx_close(intern->ctx);
37       intern->ctx = NULL;
38     }
39     if(intern->path) {
40       free(intern->path);
41     }
42   }
43 }
44
45 static void jlog_obj_dtor(void *object TSRMLS_DC)
46 {
47   zend_object *zo = (zend_object *) object;
48   jlog_obj *intern = (jlog_obj *) zo;
49   FREE_JLOG_OBJ(intern);
50   zend_object_std_dtor(&intern->zo TSRMLS_CC);
51   efree(intern);
52 }
53
54 zend_object_value jlog_objects_new(zend_class_entry *class_type TSRMLS_DC)
55 {
56   zend_object_value retval;
57   jlog_obj *intern;
58
59   intern = emalloc(sizeof(*intern));
60   memset(intern, 0, sizeof(*intern));
61  
62   zend_object_std_init(&intern->zo, class_type TSRMLS_CC);
63   retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, jlog_obj_dtor, NULL TSRMLS_CC);
64   retval.handlers = &jlog_object_handlers;
65   return retval;
66 }
67
68 /* {{{ Class definitions */
69
70 /* {{{ Class Jlog */
71
72
73 /* {{{ Methods */
74
75
76 /* {{{ proto object Jlog __construct(string path [, array options])
77  */
78 PHP_METHOD(Jlog, __construct)
79 {
80   zend_class_entry * _this_ce;
81   zval * _this_zval;
82   const char * path = NULL;
83   int path_len = 0;
84   int options = 0;
85   int size = 0;
86   jlog_obj *jo;
87
88   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &path, &path_len, &options, &size) == FAILURE) {
89     return;
90   }
91
92   _this_zval = getThis();
93   _this_ce = Z_OBJCE_P(_this_zval);
94   jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
95
96   jo->ctx = jlog_new(path);
97   jo->path = strdup(path);
98   if(options & O_CREAT) {
99     if(size) {
100       jlog_ctx_alter_journal_size(jo->ctx, size);
101     }
102     if(jlog_ctx_init(jo->ctx) != 0) {
103       if(jlog_ctx_err(jo->ctx) == JLOG_ERR_CREATE_EXISTS) {
104         if(options & O_EXCL) {
105           FREE_JLOG_OBJ(jo);
106           efree(jo);
107           php_error(E_WARNING, "file already exists: %s", path);
108         }
109       } else {
110         int err = jlog_ctx_err(jo->ctx);
111         const char *err_string = jlog_ctx_err_string(jo->ctx);
112         FREE_JLOG_OBJ(jo);
113         efree(jo);
114         php_error(E_WARNING, "error initializing jlog: %d %s", err, err_string);
115         RETURN_FALSE;
116       }
117     }
118     jlog_ctx_close(jo->ctx);
119     jo->ctx = jlog_new(path);
120     if(!jo->ctx) {
121       FREE_JLOG_OBJ(jo);
122       efree(jo);
123       php_error(E_WARNING, "jlog_new(%s) failed after successful init", path);
124       RETURN_FALSE;
125     }
126   }
127 }
128 /* }}} __construct */
129
130
131
132 /* {{{ proto bool add_subscriber(string subscriber [, int whence])
133    */
134 PHP_METHOD(Jlog, add_subscriber)
135 {
136         zend_class_entry * _this_ce;
137         zval * _this_zval = NULL;
138         const char * subscriber = NULL;
139         int subscriber_len = 0;
140         long whence = 0;
141     jlog_obj *jo;
142
143         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &_this_zval, Jlog_ce_ptr, &subscriber, &subscriber_len, &whence) == FAILURE) {
144                 return;
145         }
146
147         _this_ce = Z_OBJCE_P(_this_zval);
148         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
149   if(!jo || !jo->ctx || jlog_ctx_add_subscriber(jo->ctx, subscriber, whence) != 0)
150   {
151     RETURN_FALSE;
152   }
153         RETURN_TRUE;
154 }
155 /* }}} add_subscriber */
156
157
158
159 /* {{{ proto bool remove_subscriber(string subscriber)
160    */
161 PHP_METHOD(Jlog, remove_subscriber)
162 {
163         zend_class_entry * _this_ce;
164         zval * _this_zval = NULL;
165         const char * subscriber = NULL;
166         int subscriber_len = 0;
167     jlog_obj *jo;
168
169         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &_this_zval, Jlog_ce_ptr, &subscriber, &subscriber_len) == FAILURE) {
170                 return;
171         }
172
173         _this_ce = Z_OBJCE_P(_this_zval);
174         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
175   if(!jo || !jo->ctx || jlog_ctx_remove_subscriber(jo->ctx, subscriber) != 0)
176   {
177     RETURN_FALSE;
178   }
179         RETURN_TRUE;
180 }
181 /* }}} remove_subscriber */
182
183
184
185 /* {{{ proto array list_subscribers()
186    */
187 PHP_METHOD(Jlog, list_subscribers)
188 {
189         zend_class_entry * _this_ce;
190         zval * _this_zval = NULL;
191   jlog_obj *jo;
192   char **list;
193   int i;
194
195         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &_this_zval, Jlog_ce_ptr) == FAILURE) {
196                 return;
197         }
198
199         _this_ce = Z_OBJCE_P(_this_zval);
200         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
201   if(!jo || !jo->ctx) {
202     RETURN_NULL();
203   }
204         array_init(return_value);
205   jlog_ctx_list_subscribers(jo->ctx, &list);
206   for(i=0; list[i]; i++) {
207     add_index_string(return_value, i, list[i], 1);
208   }
209   jlog_ctx_list_subscribers_dispose(jo->ctx, list);
210 }
211 /* }}} list_subscribers */
212
213
214
215 /* {{{ proto int raw_size()
216    */
217 PHP_METHOD(Jlog, raw_size)
218 {
219   long size;
220         zend_class_entry * _this_ce;
221         zval * _this_zval = NULL;
222     jlog_obj *jo;
223
224         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &_this_zval, Jlog_ce_ptr) == FAILURE) {
225                 return;
226         }
227
228         _this_ce = Z_OBJCE_P(_this_zval);
229         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
230   if(!jo || !jo->ctx) {
231     php_error(E_WARNING, "no valid context");
232           RETURN_LONG(0);
233   }
234   size = jlog_raw_size(jo->ctx);
235   RETURN_LONG(size);
236 }
237 /* }}} raw_size */
238
239
240
241 /* {{{ proto void close()
242    */
243 PHP_METHOD(Jlog, close)
244 {
245         zend_class_entry * _this_ce;
246         zval * _this_zval = NULL;
247     jlog_obj *jo;
248
249         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &_this_zval, Jlog_ce_ptr) == FAILURE) {
250                 return;
251         }
252
253         _this_ce = Z_OBJCE_P(_this_zval);
254         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
255   if(!jo || !jo->ctx) { return; }
256   jlog_ctx_close(jo->ctx);
257   jo->ctx = NULL;
258 }
259 /* }}} close */
260
261
262 static zend_function_entry Jlog_methods[] = {
263         PHP_ME(Jlog, __construct, Jlog____construct_args, /**/ZEND_ACC_PUBLIC)
264         PHP_ME(Jlog, add_subscriber, Jlog__add_subscriber_args, /**/ZEND_ACC_PUBLIC)
265         PHP_ME(Jlog, remove_subscriber, Jlog__remove_subscriber_args, /**/ZEND_ACC_PUBLIC)
266         PHP_ME(Jlog, list_subscribers, NULL, /**/ZEND_ACC_PUBLIC)
267         PHP_ME(Jlog, raw_size, NULL, /**/ZEND_ACC_PUBLIC)
268         PHP_ME(Jlog, close, NULL, /**/ZEND_ACC_PUBLIC)
269         { NULL, NULL, NULL }
270 };
271
272 /* }}} Methods */
273
274 static void class_init_Jlog(TSRMLS_D)
275 {
276         zend_class_entry ce;
277
278         INIT_CLASS_ENTRY(ce, "Jlog", Jlog_methods);
279   ce.create_object = jlog_objects_new;
280         Jlog_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
281         Jlog_ce_ptr->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
282 }
283
284 /* }}} Class Jlog */
285
286 /* {{{ Class Jlog_Writer */
287
288
289 /* {{{ Methods */
290
291
292 /* {{{ proto object Jlog_Writer open()
293    */
294 PHP_METHOD(Jlog_Writer, open)
295 {
296         zend_class_entry * _this_ce;
297         zval * _this_zval = NULL;
298     jlog_obj *jo;
299
300         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &_this_zval, Jlog_Writer_ce_ptr) == FAILURE) {
301                 return;
302         }
303
304         _this_ce = Z_OBJCE_P(_this_zval);
305         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
306   if(!jo || !jo->ctx) {
307     RETURN_NULL();
308   }
309   if(jlog_ctx_open_writer(jo->ctx) != 0) {
310     php_error(E_WARNING, "jlog_ctx_open_writer failed");
311     RETURN_NULL();
312   }
313   ZVAL_ADDREF(_this_zval);
314   return_value = _this_zval;
315 }
316 /* }}} open */
317
318
319
320 /* {{{ proto bool write(string buffer)
321    */
322 PHP_METHOD(Jlog_Writer, write)
323 {
324         zend_class_entry * _this_ce;
325         zval * _this_zval = NULL;
326         const char * buffer = NULL;
327         int buffer_len = 0;
328     jlog_obj *jo;
329
330         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &_this_zval, Jlog_Writer_ce_ptr, &buffer, &buffer_len) == FAILURE) {
331                 return;
332         }
333
334         _this_ce = Z_OBJCE_P(_this_zval);
335         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
336   if(!jo || !jo->ctx) {
337           RETURN_FALSE;
338   }
339   if(jlog_ctx_write(jo->ctx, buffer, buffer_len) < 0) {
340     RETURN_FALSE;
341   }
342   RETURN_TRUE;
343 }
344 /* }}} write */
345
346
347 static zend_function_entry Jlog_Writer_methods[] = {
348         PHP_ME(Jlog_Writer, open, NULL, /**/ZEND_ACC_PUBLIC)
349         PHP_ME(Jlog_Writer, write, Jlog_Writer__write_args, /**/ZEND_ACC_PUBLIC)
350         { NULL, NULL, NULL }
351 };
352
353 /* }}} Methods */
354
355 static void class_init_Jlog_Writer(TSRMLS_D)
356 {
357         zend_class_entry ce;
358
359         INIT_CLASS_ENTRY(ce, "Jlog_Writer", Jlog_Writer_methods);
360   ce.create_object = jlog_objects_new;
361         Jlog_Reader_ce_ptr = zend_register_internal_class_ex(&ce, Jlog_ce_ptr, NULL TSRMLS_CC);
362 }
363
364 /* }}} Class Jlog_Writer */
365
366 /* {{{ Class Jlog_Reader */
367
368 /* {{{ Methods */
369
370
371 /* {{{ proto object Jlog_Reader open(string subscriber)
372    */
373 PHP_METHOD(Jlog_Reader, open)
374 {
375         zend_class_entry * _this_ce;
376         zval * _this_zval = NULL;
377         const char * subscriber = NULL;
378         int subscriber_len = 0;
379     jlog_obj *jo;
380
381         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &_this_zval, Jlog_Reader_ce_ptr, &subscriber, &subscriber_len) == FAILURE) {
382                 return;
383         }
384
385         _this_ce = Z_OBJCE_P(_this_zval);
386         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
387   if(!jo || !jo->ctx) {
388     RETURN_NULL();
389   }
390   if(jlog_ctx_open_reader(jo->ctx, subscriber) != 0) {
391     RETURN_NULL();
392   }
393   ZVAL_ADDREF(_this_zval);
394   return_value = _this_zval;
395 }
396 /* }}} open */
397
398
399
400 /* {{{ proto string read()
401  */
402 PHP_METHOD(Jlog_Reader, read)
403 {
404   zend_class_entry * _this_ce;
405   zval * _this_zval = NULL;
406   jlog_obj *jo;
407   const jlog_id epoch = { 0, 0 };
408   jlog_id cur;
409   jlog_message message;
410   int cnt;
411
412   if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &_this_zval, Jlog_Reader_ce_ptr) == FAILURE) {
413     return;
414   }
415
416   _this_ce = Z_OBJCE_P(_this_zval);
417   jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
418   if(!jo || !jo->ctx) {
419     RETURN_FALSE;
420   }
421   /* if start is unset, we need to read the interval (again) */
422   if(!memcmp(&jo->start, &epoch, sizeof(jlog_id)))
423   {
424     cnt = jlog_ctx_read_interval(jo->ctx, &jo->start, &jo->end);
425     if(cnt == -1) {
426       php_error(E_WARNING, "jlog_ctx_read_interval failed");
427     }
428     if(cnt == 0) {
429       jo->start = epoch;
430       jo->end = epoch;
431       RETURN_FALSE;
432     }
433   }
434   /* if last is unset, start at the beginning */
435   if(!memcmp(&jo->last, &epoch, sizeof(jlog_id))) {
436     cur = jo->start;
437   } else {
438     /* if we've already read the end, return; otherwise advance */
439     if (!memcmp(&jo->last, &jo->end, sizeof(jlog_id))) {
440       jo->start = epoch;
441       jo->end = epoch;
442       RETURN_FALSE;
443     } else {
444       cur = jo->last;
445       JLOG_ID_ADVANCE(&cur);
446     }
447   }
448
449   if(jlog_ctx_read_message(jo->ctx, &cur, &message) != 0) {
450     php_error(E_WARNING, "read failed");
451     RETURN_FALSE;
452   }
453   if(jo->auto_checkpoint) {
454     if(jlog_ctx_read_checkpoint(jo->ctx, &cur) != 0) {
455       php_error(E_WARNING, "checkpoint failed");
456       RETURN_FALSE;
457     }
458     /* we have to re-read the interval after a checkpoint */
459     jo->last = epoch;
460     jo->start = epoch;
461     jo->end = epoch;
462   } else {
463     /* update last */
464     jo->last = cur;
465     /* if we've reaached the end, clear interval so we'll re-read it */
466     if(!memcmp(&jo->last, &jo->end, sizeof(jlog_id))) {
467       jo->start = epoch;
468       jo->end = epoch;
469     }
470   }
471   RETURN_STRINGL(message.mess, message.mess_len, 1);
472 end:
473   ;
474 }
475
476 /* }}} read */
477
478
479
480 /* {{{ proto object Jlog_Reader checkpoint()
481    */
482 PHP_METHOD(Jlog_Reader, checkpoint)
483 {
484   jlog_id epoch = { 0, 0 };
485         zend_class_entry * _this_ce;
486         zval * _this_zval = NULL;
487     jlog_obj *jo;
488
489         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &_this_zval, Jlog_Reader_ce_ptr) == FAILURE) {
490                 return;
491         }
492
493         _this_ce = Z_OBJCE_P(_this_zval);
494         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
495   if(!jo || !jo->ctx) { RETURN_NULL(); }
496   if(memcmp(&jo->last, &epoch, sizeof(jlog_id)))
497   {
498     jlog_ctx_read_checkpoint(jo->ctx, &jo->last);
499     /* we have to re-read the interval after a checkpoint */
500     jo->last = epoch;
501     jo->start = epoch;
502     jo->end = epoch;
503   }
504   ZVAL_ADDREF(_this_zval);
505   return_value = _this_zval;
506 }
507 /* }}} checkpoint */
508
509
510
511 /* {{{ proto bool auto_checkpoint([bool state])
512    */
513 PHP_METHOD(Jlog_Reader, auto_checkpoint)
514 {
515         zend_class_entry * _this_ce;
516         zval * _this_zval = NULL;
517         zend_bool state = 0;
518     jlog_obj *jo;
519
520         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|b", &_this_zval, Jlog_Reader_ce_ptr, &state) == FAILURE) {
521                 return;
522         }
523
524   fprintf(stderr, "num_args = %d\n", ZEND_NUM_ARGS());
525         _this_ce = Z_OBJCE_P(_this_zval);
526         jo = (jlog_obj *) zend_object_store_get_object(_this_zval TSRMLS_CC);
527   if(!jo || !jo->ctx) { RETURN_NULL(); }
528   if(ZEND_NUM_ARGS() == 1) {
529     jo->auto_checkpoint = state;
530   }
531   RETURN_LONG(jo->auto_checkpoint);
532 }
533 /* }}} auto_checkpoint */
534
535
536 static zend_function_entry Jlog_Reader_methods[] = {
537         PHP_ME(Jlog_Reader, open, Jlog_Reader__open_args, /**/ZEND_ACC_PUBLIC)
538         PHP_ME(Jlog_Reader, read, NULL, /**/ZEND_ACC_PUBLIC)
539         PHP_ME(Jlog_Reader, checkpoint, NULL, /**/ZEND_ACC_PUBLIC)
540         PHP_ME(Jlog_Reader, auto_checkpoint, Jlog_Reader__auto_checkpoint_args, /**/ZEND_ACC_PUBLIC)
541         { NULL, NULL, NULL }
542 };
543
544 /* }}} Methods */
545
546 static void class_init_Jlog_Reader(TSRMLS_D)
547 {
548         zend_class_entry ce;
549
550         INIT_CLASS_ENTRY(ce, "Jlog_Reader", Jlog_Reader_methods);
551   ce.create_object = jlog_objects_new;
552         Jlog_Reader_ce_ptr = zend_register_internal_class_ex(&ce, Jlog_ce_ptr, NULL TSRMLS_CC);
553 }
554
555 /* }}} Class Jlog_Reader */
556
557 /* }}} Class definitions*/
558
559 /* {{{ jlog_functions[] */
560 function_entry jlog_functions[] = {
561         { NULL, NULL, NULL }
562 };
563 /* }}} */
564
565
566 /* {{{ jlog_module_entry
567  */
568 zend_module_entry jlog_module_entry = {
569         STANDARD_MODULE_HEADER,
570         "jlog",
571         jlog_functions,
572         PHP_MINIT(jlog),     /* Replace with NULL if there is nothing to do at php startup   */
573         PHP_MSHUTDOWN(jlog), /* Replace with NULL if there is nothing to do at php shutdown  */
574         PHP_RINIT(jlog),     /* Replace with NULL if there is nothing to do at request start */
575         PHP_RSHUTDOWN(jlog), /* Replace with NULL if there is nothing to do at request end   */
576         PHP_MINFO(jlog),
577         "0.0.1",
578         STANDARD_MODULE_PROPERTIES
579 };
580 /* }}} */
581
582 #ifdef COMPILE_DL_JLOG
583 ZEND_GET_MODULE(jlog)
584 #endif
585
586
587 /* {{{ PHP_MINIT_FUNCTION */
588 PHP_MINIT_FUNCTION(jlog)
589 {
590     zend_object_handlers *std_hnd = zend_get_std_object_handlers();
591
592     memcpy(&jlog_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
593     jlog_object_handlers.clone_obj = NULL;
594
595         class_init_Jlog(TSRMLS_C);
596         class_init_Jlog_Writer(TSRMLS_C);
597         class_init_Jlog_Reader(TSRMLS_C);
598    
599    
600         /* add your stuff here */
601
602         return SUCCESS;
603 }
604 /* }}} */
605
606
607 /* {{{ PHP_MSHUTDOWN_FUNCTION */
608 PHP_MSHUTDOWN_FUNCTION(jlog)
609 {
610
611         /* add your stuff here */
612
613         return SUCCESS;
614 }
615 /* }}} */
616
617
618 /* {{{ PHP_RINIT_FUNCTION */
619 PHP_RINIT_FUNCTION(jlog)
620 {
621         /* add your stuff here */
622
623         return SUCCESS;
624 }
625 /* }}} */
626
627
628 /* {{{ PHP_RSHUTDOWN_FUNCTION */
629 PHP_RSHUTDOWN_FUNCTION(jlog)
630 {
631         /* add your stuff here */
632
633         return SUCCESS;
634 }
635 /* }}} */
636
637
638 /* {{{ PHP_MINFO_FUNCTION */
639 PHP_MINFO_FUNCTION(jlog)
640 {
641         php_info_print_box_start(0);
642         php_printf("<p>A sample PHP extension</p>\n");
643         php_printf("<p>Version 0.0.1devel (2007-07-02)</p>\n");
644         php_info_print_box_end();
645         /* add your stuff here */
646
647 }
648 /* }}} */
649
650 #endif /* HAVE_JLOG */
651
652
653 /*
654  * Local variables:
655  * tab-width: 4
656  * c-basic-offset: 4
657  * End:
658  * vim600: et sw=2 ts=2 sts=2 ai bs=2 fdm=marker
659  */
Note: See TracBrowser for help on using the browser.