[862] in BarnOwl Developers

home help back first fref pref prev next nref lref last post

[D-O-H] r850 - branches/barnowl_sqlite/owl

daemon@ATHENA.MIT.EDU (nelhage@MIT.EDU)
Thu Oct 29 18:10:30 2009

Resent-From: nelhage@mit.edu
Resent-To: barnowl-dev-mtg@charon.mit.edu
To: dirty-owl-hackers@mit.edu
From: nelhage@MIT.EDU
Reply-to: dirty-owl-hackers@MIT.EDU
Date: Sat, 12 Jan 2008 03:43:25 -0500 (EST)

Author: nelhage
Date: 2008-01-12 03:43:25 -0500 (Sat, 12 Jan 2008)
New Revision: 850

Modified:
   branches/barnowl_sqlite/owl/filter.c
   branches/barnowl_sqlite/owl/message.c
   branches/barnowl_sqlite/owl/owl.h
   branches/barnowl_sqlite/owl/perlconfig.c
   branches/barnowl_sqlite/owl/perlwrap.pm
Log:
Remember that messages-are-perl-objects idea from way back when?

Modified: branches/barnowl_sqlite/owl/filter.c
===================================================================
--- branches/barnowl_sqlite/owl/filter.c	2008-01-12 07:26:49 UTC (rev 849)
+++ branches/barnowl_sqlite/owl/filter.c	2008-01-12 08:43:25 UTC (rev 850)
@@ -306,20 +306,20 @@
 
 int owl_filter_regtest(void) {
   int numfailed=0;
-  owl_message m;
+  owl_message *m = owl_message_new();;
   owl_filter f1, f2, f3, f4;
 
   owl_list_create(&(g.filterlist));
-  owl_message_init(&m);
-  owl_message_set_type_zephyr(&m);
-  owl_message_set_direction_in(&m);
-  owl_message_set_class(&m, "owl");
-  owl_message_set_instance(&m, "tester");
-  owl_message_set_sender(&m, "owl-user");
-  owl_message_set_recipient(&m, "joe");
-  owl_message_set_attribute(&m, "foo", "bar");
+  owl_message_init(m);
+  owl_message_set_type_zephyr(m);
+  owl_message_set_direction_in(m);
+  owl_message_set_class(m, "owl");
+  owl_message_set_instance(m, "tester");
+  owl_message_set_sender(m, "owl-user");
+  owl_message_set_recipient(m, "joe");
+  owl_message_set_attribute(m, "foo", "bar");
 
-#define TEST_FILTER(f, e) numfailed += owl_filter_test_string(f, &m, e)
+#define TEST_FILTER(f, e) numfailed += owl_filter_test_string(f, m, e)
 
 
   TEST_FILTER("true", 1);

Modified: branches/barnowl_sqlite/owl/message.c
===================================================================
--- branches/barnowl_sqlite/owl/message.c	2008-01-12 07:26:49 UTC (rev 849)
+++ branches/barnowl_sqlite/owl/message.c	2008-01-12 08:43:25 UTC (rev 850)
@@ -8,6 +8,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <time.h>
+#define OWL_PERL
 #include "owl.h"
 
 static const char fileIdent[] = "$Id$";
@@ -16,25 +17,48 @@
 static owl_fmtext_cache * fmtext_cache_next = fmtext_cache;
 
 owl_message *owl_message_new() {
-  return (owl_message*)owl_malloc(sizeof(owl_message));
+  dSP;
+  SV *msg;
+  int count;
+
+  ENTER;
+  SAVETMPS;
+
+  PUSHMARK(SP);
+  XPUSHs(sv_2mortal(newSVpv("BarnOwl::Message", 0)));
+  PUTBACK;
+
+  count = call_method("new", G_SCALAR|G_EVAL|G_KEEPERR);
+
+  SPAGAIN;
+
+  if (SvTRUE(ERRSV)) {
+    printf("Ooops: %s\n", SvPV_nolen(ERRSV));
+    exit(-1);
+  }
+
+  msg = POPs;
+  SvREFCNT_inc(msg);
+
+  PUTBACK;
+  FREETMPS;
+  LEAVE;
+
+  return (owl_message*)msg;
 }
 
 void owl_message_init(owl_message *m)
 {
-  m->id=owl_global_get_nextmsgid(&g);
-  owl_message_set_direction_none(m);
-  m->delete=0;
-  m->zwriteline=NULL;
 
-  owl_message_set_hostname(m, "");
-  owl_list_create(&(m->attributes));
-  
-  /* save the time */
-  m->time=time(NULL);
-  m->timestr=owl_strdup(ctime(&(m->time)));
-  m->timestr[strlen(m->timestr)-1]='\0';
+}
 
-  m->fmtext = NULL;
+SV* owl_message_get_attribute_internal(owl_message *m, char *attrname)
+{
+  HV * hash = (HV*)SvRV((SV*)m);
+  SV **attr = hv_fetch(hash, attrname, strlen(attrname), 0);
+  if(attr == NULL)
+    return NULL;
+  return *attr;
 }
 
 /* add the named attribute to the message.  If an attribute with the
@@ -42,26 +66,9 @@
  */
 void owl_message_set_attribute(owl_message *m, char *attrname, char *attrvalue)
 {
-  int i, j;
-  owl_pair *p = NULL, *pair = NULL;
-
-  /* look for an existing pair with this key, */
-  j=owl_list_get_size(&(m->attributes));
-  for (i=0; i<j; i++) {
-    p=owl_list_get_element(&(m->attributes), i);
-    if (!strcmp(owl_pair_get_key(p), attrname)) {
-      owl_free(owl_pair_get_value(p));
-      pair = p;
-      break;
-    }
-  }
-
-  if(pair ==  NULL) {
-    pair = owl_malloc(sizeof(owl_pair));
-    owl_pair_create(pair, owl_global_intern(&g, attrname), NULL);
-    owl_list_append_element(&(m->attributes), pair);
-  }
-  owl_pair_set_value(pair, owl_strdup(attrvalue));
+  char *argv[] = {attrname, attrvalue, NULL};
+  char *rv = owl_perlconfig_message_call_method(m, "__set_attribute", 2, argv);
+  if(rv) owl_free(rv);
 }
 
 /* return the value associated with the named attribute, or NULL if
@@ -69,23 +76,24 @@
  */
 char *owl_message_get_attribute_value(owl_message *m, char *attrname)
 {
-  int i, j;
-  owl_pair *p;
+  SV *attr = owl_message_get_attribute_internal(m, attrname);
+  if(attr == NULL || !SvOK(attr)) return NULL;
+  return SvPV_nolen(attr);
+}
 
-  j=owl_list_get_size(&(m->attributes));
-  for (i=0; i<j; i++) {
-    p=owl_list_get_element(&(m->attributes), i);
-    if (!strcmp(owl_pair_get_key(p), attrname)) {
-      return(owl_pair_get_value(p));
-    }
-  }
+char *owl_message_get_attribute_value_nonull(owl_message *m, char *attrname)
+{
+  char *att = owl_message_get_attribute_value(m, attrname);
+  if(att == NULL) return "";
+  return att;
+}
 
-  /*
-  owl_function_debugmsg("No attribute %s found for message %i",
-			attrname,
-			owl_message_get_id(m));
-  */
-  return(NULL);
+int owl_message_get_attribute_int(owl_message *m, char *attrname)
+{
+  SV* attr = owl_message_get_attribute_internal(m, attrname);
+  if(attr == NULL)
+    return 0;
+  return SvIV(attr);
 }
 
 /* We cheat and indent it for now, since we really want this for
@@ -99,7 +107,8 @@
 
   owl_fmtext_init_null(fm);
 
-  j=owl_list_get_size(&(m->attributes));
+  // XXX TODO FIXME
+  /*  j=owl_list_get_size(&(m->attributes));
   for (i=0; i<j; i++) {
     p=owl_list_get_element(&(m->attributes), i);
     buff=owl_sprintf("  %-15.15s: %-35.35s\n", owl_pair_get_key(p), owl_pair_get_value(p));
@@ -110,11 +119,11 @@
     }
     owl_fmtext_append_normal(fm, buff);
     owl_free(buff);
-  }
+    }*/
 }
 
 int owl_message_get_id(owl_message *m) {
-  return m->id;
+  return owl_message_get_attribute_int(m, "id");
 }
 
 void owl_message_set_class(owl_message *m, char *class)
@@ -276,31 +285,57 @@
 
 void owl_message_set_isprivate(owl_message *m)
 {
-  owl_message_set_attribute(m, "isprivate", "true");
+  owl_message_set_attribute(m, "private", "true");
 }
 
 int owl_message_is_private(owl_message *m)
 {
   char *res;
 
-  res=owl_message_get_attribute_value(m, "isprivate");
+  res=owl_message_get_attribute_value(m, "private");
   if (!res) return(0);
   return !strcmp(res, "true");
 }
 
+/*
+  A note on times: For backwards compatibility with owl, we store the
+  ``timestr'' (ctime) under the ``time'' key in the has, and the
+  numeric time as ``_time''. Setting the numeric time automatically
+  recomputes the timestr.
+ */
+void owl_message_set_time(owl_message *m, time_t tm)
+{
+  char * timestr;
+  timestr = owl_sprintf("%d", tm);
+  owl_message_set_attribute(m, "_time", timestr);
+  owl_free(timestr);
+  timestr = owl_strdup(ctime(&tm));
+  /* Chop the newline */
+  timestr[strlen(timestr)-1] = 0;
+  owl_message_set_attribute(m, "time", timestr);
+  owl_free(timestr);
+}
+
+time_t owl_message_get_time(owl_message *m)
+{
+  return (time_t)owl_message_get_attribute_int(m, "_time");
+}
+
 char *owl_message_get_timestr(owl_message *m)
 {
-  if (m->timestr) return(m->timestr);
-  return("");
+  char *tm = owl_message_get_attribute_value(m, "time");
+  if(tm == NULL) return "";
+  return tm;
 }
 
 /* caller must free the return */
 char *owl_message_get_shorttimestr(owl_message *m)
 {
   struct tm *tmstruct;
+  time_t time = owl_message_get_time(m);
   char *out;
 
-  tmstruct=localtime(&(m->time));
+  tmstruct=localtime(&time);
   out=owl_sprintf("%2.2i:%2.2i", tmstruct->tm_hour, tmstruct->tm_min);
   if (out) return(out);
   return("??:??");
@@ -308,27 +343,40 @@
 
 void owl_message_set_type_admin(owl_message *m)
 {
-  owl_message_set_attribute(m, "type", "admin");
+  owl_message_set_type(m, "admin");
 }
 
 void owl_message_set_type_loopback(owl_message *m)
 {
-  owl_message_set_attribute(m, "type", "loopback");
+  owl_message_set_type(m, "loopback");
 }
 
 void owl_message_set_type_zephyr(owl_message *m)
 {
-  owl_message_set_attribute(m, "type", "zephyr");
+  owl_message_set_type(m, "zephyr");
 }
 
 void owl_message_set_type_aim(owl_message *m)
 {
-  owl_message_set_attribute(m, "type", "AIM");
+  owl_message_set_type(m, "AIM");
 }
 
 void owl_message_set_type(owl_message *m, char* type)
 {
+  char *blessas;
+  HV *stash;
   owl_message_set_attribute(m, "type", type);
+  type = owl_strdup(type);
+  type[0] = toupper(type[0]);
+  blessas = owl_sprintf("BarnOwl::Message::%s", type);
+  stash = gv_stashpv(blessas, 0);
+  if(!stash) {
+    owl_function_error("No such class: %s for message type %s", blessas, owl_message_get_type(m));
+    stash = gv_stashpv("BarnOwl::Message", 1);
+  }
+  sv_bless(m, stash);
+  owl_free(type);
+  owl_free(blessas);
 }
 
 int owl_message_is_type(owl_message *m, char *type) {
@@ -377,94 +425,75 @@
 
 void owl_message_set_direction_in(owl_message *m)
 {
-  m->direction=OWL_MESSAGE_DIRECTION_IN;
+  owl_message_set_direction(m, OWL_MESSAGE_DIRECTION_IN);
 }
 
 void owl_message_set_direction_out(owl_message *m)
 {
-  m->direction=OWL_MESSAGE_DIRECTION_OUT;
+  owl_message_set_direction(m, OWL_MESSAGE_DIRECTION_OUT);
 }
 
 void owl_message_set_direction_none(owl_message *m)
 {
-  m->direction=OWL_MESSAGE_DIRECTION_NONE;
+  owl_message_set_direction(m, OWL_MESSAGE_DIRECTION_NONE);
 }
 
-void owl_message_set_direction(owl_message *m, int direction)
+void owl_message_set_direction(owl_message *m, char *direction)
 {
-  m->direction=direction;
+  owl_message_set_attribute(m, "direction", direction);
 }
 
 int owl_message_is_direction_in(owl_message *m)
 {
-  if (m->direction==OWL_MESSAGE_DIRECTION_IN) return(1);
-  return(0);
+  return !strcmp(owl_message_get_direction(m), OWL_MESSAGE_DIRECTION_IN);
 }
 
 int owl_message_is_direction_out(owl_message *m)
 {
-  if (m->direction==OWL_MESSAGE_DIRECTION_OUT) return(1);
-  return(0);
+  return !strcmp(owl_message_get_direction(m), OWL_MESSAGE_DIRECTION_OUT);
 }
 
 int owl_message_is_direction_none(owl_message *m)
 {
-  if (m->direction==OWL_MESSAGE_DIRECTION_NONE) return(1);
-  return(0);
+  return !strcmp(owl_message_get_direction(m), OWL_MESSAGE_DIRECTION_NONE);
 }
 
 void owl_message_mark_delete(owl_message *m)
 {
   if (m == NULL) return;
-  m->delete=1;
+  owl_message_set_attribute(m, "deleted", "1");
 }
 
 void owl_message_unmark_delete(owl_message *m)
 {
   if (m == NULL) return;
-  m->delete=0;
+  owl_message_set_attribute(m, "deleted", "0");
 }
 
 char *owl_message_get_zwriteline(owl_message *m)
 {
-  if(!m->zwriteline)
-    return "";
-  return(m->zwriteline);
+  return owl_message_get_attribute_value_nonull(m, "zwriteline");
 }
 
 void owl_message_set_zwriteline(owl_message *m, char *line)
 {
-  if(m->zwriteline) owl_free(m->zwriteline);
-  m->zwriteline=strdup(line);
+  owl_message_set_attribute(m, "zwriteline", line);
 }
 
 int owl_message_is_delete(owl_message *m)
 {
   if (m == NULL) return(0);
-  if (m->delete==1) return(1);
-  return(0);
+  return owl_message_get_attribute_int(m, "deleted");
 }
 
-#ifdef HAVE_LIBZEPHYR
-ZNotice_t *owl_message_get_notice(owl_message *m) /*noproto*/
-{
-  return(&(m->notice));
-}
-#else
-void *owl_message_get_notice(owl_message *m) /*noproto*/
-{
-  return(NULL);
-}
-#endif
-
 void owl_message_set_hostname(owl_message *m, char *hostname)
 {
-  m->hostname=owl_global_intern(&g, hostname);
+  owl_message_set_attribute(m, "hostname", hostname);
 }
 
 char *owl_message_get_hostname(owl_message *m)
 {
-  return(m->hostname);
+  return owl_message_get_attribute_value_nonull(m, "hostname");
 }
 
 int owl_message_is_personal(owl_message *m)
@@ -624,29 +653,11 @@
 }
 
 char *owl_message_get_direction(owl_message *m) {
-  switch (m->direction) {
-  case OWL_MESSAGE_DIRECTION_IN:
-    return("in");
-  case OWL_MESSAGE_DIRECTION_OUT:
-    return("out");
-  case OWL_MESSAGE_DIRECTION_NONE:
-    return("none");
-  default:
-    return("unknown");
-  }
+  char *dir =  owl_message_get_attribute_value(m, "direction");
+  if(dir == NULL) return "unknown";
+  return dir;
 }
 
-int owl_message_parse_direction(char *d) {
-  if(!strcmp(d, "in")) {
-    return OWL_MESSAGE_DIRECTION_IN;
-  } else if(!strcmp(d, "out")) {
-    return OWL_MESSAGE_DIRECTION_OUT;
-  } else {
-    return OWL_MESSAGE_DIRECTION_NONE;
-  }
-}
-
-
 char *owl_message_get_login(owl_message *m) {
   if (owl_message_is_login(m)) {
     return "login";
@@ -676,7 +687,7 @@
  *                 0 it's not a login/logout message
  *                 1 it's a login message
  */
-void owl_message_create_aim(owl_message *m, char *sender, char *recipient, char *text, int direction, int loginout)
+void owl_message_create_aim(owl_message *m, char *sender, char *recipient, char *text, char *direction, int loginout)
 {
   owl_message_init(m);
   owl_message_set_body(m, text);
@@ -684,11 +695,7 @@
   owl_message_set_recipient(m, recipient);
   owl_message_set_type_aim(m);
 
-  if (direction==OWL_MESSAGE_DIRECTION_IN) {
-    owl_message_set_direction_in(m);
-  } else if (direction==OWL_MESSAGE_DIRECTION_OUT) {
-    owl_message_set_direction_out(m);
-  }
+  owl_message_set_direction(m, direction);
 
   /* for now all messages that aren't loginout are private */
   if (!loginout) {
@@ -726,24 +733,14 @@
 {
   struct hostent *hent;
   char *ptr, *tmp, *tmp2;
-  int len;
+  int i,j,len;
 
   owl_message_init(m);
   
   owl_message_set_type_zephyr(m);
   owl_message_set_direction_in(m);
-  
-  /* first save the full notice */
-  memcpy(&(m->notice), n, sizeof(ZNotice_t));
 
-  /* a little gross, we'll replace \r's with ' ' for now */
-  owl_zephyr_hackaway_cr(&(m->notice));
-  
-  /* save the time, we need to nuke the string saved by message_init */
-  if (m->timestr) owl_free(m->timestr);
-  m->time=n->z_time.tv_sec;
-  m->timestr=owl_strdup(ctime(&(m->time)));
-  m->timestr[strlen(m->timestr)-1]='\0';
+  owl_message_set_time(m, n->z_time.tv_sec);
 
   /* set other info */
   owl_message_set_sender(m, n->z_sender);
@@ -796,8 +793,6 @@
     owl_message_set_attribute(m, "isauto", "");
   }
 
-  m->zwriteline=strdup("");
-
   /* save the hostname */
   owl_function_debugmsg("About to do gethostbyaddr");
   hent=gethostbyaddr((char *) &(n->z_uid.zuid_addr), sizeof(n->z_uid.zuid_addr), AF_INET);
@@ -818,6 +813,21 @@
   }
   owl_free(tmp);
 
+  /* Save the fields */
+  AV *av_zfields;
+
+  av_zfields = newAV();
+  j=owl_zephyr_get_num_fields(n);
+  for (i=0; i<j; i++) {
+    ptr=owl_zephyr_get_field(n, i+1);
+    av_push(av_zfields, newSVpvn(ptr, strlen(ptr)));
+    owl_free(ptr);
+  }
+  hv_store((HV*)SvRV(m), "fields", strlen("fields"), newRV_noinc((SV*)av_zfields), 0);
+
+  /* Auth */
+  owl_message_set_attribute(m, "auth", owl_zephyr_get_authstr(n));
+
 #ifdef OWL_ENABLE_ZCRYPT
   /* if zcrypt is enabled try to decrypt the message */
   if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
@@ -837,12 +847,26 @@
 
 int owl_message_get_num_fields(owl_message *m)
 {
-  return owl_zephyr_get_num_fields(owl_message_get_notice(m));
+  SV * ref_fields;
+  AV * fields;
+  ref_fields = owl_message_get_attribute_internal(m, "fields");
+  if(!ref_fields || !SvROK(ref_fields)) return 0;
+  fields = (AV*)(SvRV(ref_fields));
+  return av_len(fields) + 1;
 }
 
 char *owl_message_get_field(owl_message *m, int n)
 {
-  return owl_zephyr_get_field(owl_message_get_notice(m), n);
+  n--;
+  SV * ref_fields;
+  AV * fields;
+  SV ** f;
+  ref_fields = owl_message_get_attribute_internal(m, "fields");
+  if(!ref_fields || !SvROK(ref_fields)) return "";
+  fields = (AV*)SvRV(ref_fields);
+  f = av_fetch(fields, n, 0);
+  if(!f) return "";
+  return owl_strdup(SvPV_nolen(*f));
 }
 #else
 void owl_message_create_from_znotice(owl_message *m, void *n)
@@ -855,10 +879,6 @@
 {
   char *longuser, *ptr;
 
-#ifdef HAVE_LIBZEPHYR
-  memset(&(m->notice), 0, sizeof(ZNotice_t));
-#endif
-  
   longuser=long_zuser(user);
   
   owl_message_init(m);
@@ -888,8 +908,6 @@
     owl_message_set_realm(m, owl_zephyr_get_realm());
   }
 
-  m->zwriteline=strdup("");
-
   owl_message_set_body(m, "<uninitialized>");
 
   /* save the hostname */
@@ -921,7 +939,7 @@
   }
   owl_message_set_opcode(m, owl_zwrite_get_opcode(&z));
   owl_message_set_realm(m, owl_zwrite_get_realm(&z)); /* also a hack, but not here */
-  m->zwriteline=owl_strdup(line);
+  owl_message_set_zwriteline(m, line);
   owl_message_set_body(m, body);
   owl_message_set_zsig(m, zsig);
   
@@ -954,27 +972,8 @@
 
 void owl_message_free(owl_message *m)
 {
-  int i, j;
-  owl_pair *p;
-#ifdef HAVE_LIBZEPHYR    
-  if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) {
-    ZFreeNotice(&(m->notice));
-  }
-#endif
-  if (m->timestr) owl_free(m->timestr);
-  if (m->zwriteline) owl_free(m->zwriteline);
-
-  /* free all the attributes */
-  j=owl_list_get_size(&(m->attributes));
-  for (i=0; i<j; i++) {
-    p=owl_list_get_element(&(m->attributes), i);
-    owl_free(owl_pair_get_value(p));
-    owl_free(p);
-  }
-
-  owl_list_free_simple(&(m->attributes));
- 
   owl_message_invalidate_format(m);
+  SvREFCNT_dec((SV*)m);
 }
 
 
@@ -1008,19 +1007,25 @@
   owl_fmtext_cache * fmtext = owl_message_get_fmtext_cache(m);
   if(fmtext) {
     fmtext->message_id = NO_MESSAGE;
-    owl_fmtext_clear(&(m->fmtext->fmtext));
+    owl_fmtext_clear(&(fmtext->fmtext));
     owl_message_set_fmtext_cache(m, NULL);
   }
 }
 
 owl_fmtext_cache *owl_message_get_fmtext_cache(owl_message *m)
 {
-  return m->fmtext;
+  SV *fmtext = owl_message_get_attribute_internal(m, "__fmtext");
+  if(fmtext && SvROK(fmtext))
+    return INT2PTR(owl_fmtext_cache*, SvIV(SvRV(fmtext)));
+  return NULL;
 }
 
 void owl_message_set_fmtext_cache(owl_message *m, owl_fmtext_cache *fm)
 {
-  m->fmtext = fm;
+  SV *fmtext = newSV(0);
+  sv_setref_pv(fmtext, Nullch, fm);
+  HV *hash = (HV*)SvRV((SV*)m);
+  hv_store(hash, "__fmtext", strlen("__fmtext"), fmtext, 0);
 }
 
 owl_fmtext *owl_message_get_fmtext(owl_message *m)

Modified: branches/barnowl_sqlite/owl/owl.h
===================================================================
--- branches/barnowl_sqlite/owl/owl.h	2008-01-12 07:26:49 UTC (rev 849)
+++ branches/barnowl_sqlite/owl/owl.h	2008-01-12 08:43:25 UTC (rev 850)
@@ -64,6 +64,8 @@
 typedef void WINDOW;
 /* logout is defined in FreeBSD. */
 #define logout logout_
+/* aim.h defines bool */
+#define HAS_BOOL
 #include <perl.h>
 #undef logout
 #include "XSUB.h"
@@ -73,14 +75,14 @@
 
 static const char owl_h_fileIdent[] = "$Id$";
 
-#define STRINGIFY(x) _STRINGIFY(x)
+#define BARNOWL_STRINGIFY(x) _STRINGIFY(x)
 #define _STRINGIFY(x) #x
 
 #ifndef OWL_SVN_REVNO
 #define OWL_SVN_REVNO ????
 #endif
 
-#define OWL_VERSION_STRING "r" STRINGIFY(OWL_SVN_REVNO)
+#define OWL_VERSION_STRING "r" BARNOWL_STRINGIFY(OWL_SVN_REVNO)
 
 
 /* Feature that is being tested to redirect stderr through a pipe. 
@@ -118,9 +120,9 @@
 #define OWL_PROTOCOL_YAHOO          4
 #define OWL_PROTOCOL_MSN            5
 
-#define OWL_MESSAGE_DIRECTION_NONE  0
-#define OWL_MESSAGE_DIRECTION_IN    1
-#define OWL_MESSAGE_DIRECTION_OUT   2
+#define OWL_MESSAGE_DIRECTION_NONE  "none"
+#define OWL_MESSAGE_DIRECTION_IN    "in"
+#define OWL_MESSAGE_DIRECTION_OUT   "out"
 
 #define OWL_MUX_READ   1
 #define OWL_MUX_WRITE  2
@@ -334,8 +336,8 @@
 
 struct _owl_fmtext_cache;
 
-// typedef SV owl_message;
-typedef struct _owl_message {
+typedef SV owl_message;
+/* typedef struct _owl_message {
   int id;
   int direction;
 #ifdef HAVE_LIBZEPHYR
@@ -348,7 +350,7 @@
   char *timestr;
   time_t time;
   char *zwriteline;
-} owl_message;
+  } owl_message; */
 
 #define OWL_FMTEXT_CACHE_SIZE 1000
 /* We cache the saved fmtexts for the last bunch of messages we

Modified: branches/barnowl_sqlite/owl/perlconfig.c
===================================================================
--- branches/barnowl_sqlite/owl/perlconfig.c	2008-01-12 07:26:49 UTC (rev 849)
+++ branches/barnowl_sqlite/owl/perlconfig.c	2008-01-12 08:43:25 UTC (rev 850)
@@ -27,90 +27,7 @@
 
 SV *owl_perlconfig_message2hashref(owl_message *m)
 {
-  HV *h, *stash;
-  SV *hr;
-  char *ptr, *blessas, *type;
-  int i, j;
-  owl_pair *pair;
-  owl_filter *wrap;
-
-  if (!m) return &PL_sv_undef;
-  wrap = owl_global_get_filter(&g, "wordwrap");
-  if(!wrap) {
-      owl_function_error("wrap filter is not defined");
-      return &PL_sv_undef;
-  }
-
-  h = newHV();
-
-#define MSG2H(h,field) hv_store(h, #field, strlen(#field), \
-			      newSVpv(owl_message_get_##field(m),0), 0)
-
-  if (owl_message_is_type_zephyr(m)
-      && owl_message_is_direction_in(m)) {
-    /* Handle zephyr-specific fields... */
-    AV *av_zfields;
-
-    av_zfields = newAV();
-    j=owl_zephyr_get_num_fields(owl_message_get_notice(m));
-    for (i=0; i<j; i++) {
-      ptr=owl_zephyr_get_field(owl_message_get_notice(m), i+1);
-      av_push(av_zfields, newSVpvn(ptr, strlen(ptr)));
-      owl_free(ptr);
-    }
-    hv_store(h, "fields", strlen("fields"), newRV_noinc((SV*)av_zfields), 0);
-
-    hv_store(h, "auth", strlen("auth"), 
-	     newSVpv(owl_zephyr_get_authstr(owl_message_get_notice(m)),0),0);
-  }
-
-  j=owl_list_get_size(&(m->attributes));
-  for(i=0; i<j; i++) {
-    pair=owl_list_get_element(&(m->attributes), i);
-    hv_store(h, owl_pair_get_key(pair), strlen(owl_pair_get_key(pair)),
-	     newSVpv(owl_pair_get_value(pair),0),0);
-  }
-  
-  MSG2H(h, type);
-  MSG2H(h, direction);
-  MSG2H(h, class);
-  MSG2H(h, instance);
-  MSG2H(h, sender);
-  MSG2H(h, realm);
-  MSG2H(h, recipient);
-  MSG2H(h, opcode);
-  MSG2H(h, hostname);
-  MSG2H(h, body);
-  MSG2H(h, login);
-  MSG2H(h, zsig);
-  MSG2H(h, zwriteline);
-  if (owl_message_get_header(m)) {
-    MSG2H(h, header); 
-  }
-  hv_store(h, "time", strlen("time"), newSVpv(owl_message_get_timestr(m),0),0);
-  hv_store(h, "id", strlen("id"), newSViv(owl_message_get_id(m)),0);
-  hv_store(h, "deleted", strlen("deleted"), newSViv(owl_message_is_delete(m)),0);
-  hv_store(h, "private", strlen("private"), newSViv(owl_message_is_private(m)),0);
-  hv_store(h, "should_wordwrap",
-	   strlen("should_wordwrap"), newSViv(
-					      owl_filter_message_match(wrap, m)),0);
-
-  type = owl_message_get_type(m);
-  if(!type || !*type) type = "generic";
-  type = owl_strdup(type);
-  type[0] = toupper(type[0]);
-  blessas = owl_sprintf("BarnOwl::Message::%s", type);
-
-  hr = sv_2mortal(newRV_noinc((SV*)h));
-  stash =  gv_stashpv(blessas,0);
-  if(!stash) {
-    owl_function_error("No such class: %s for message type %s", blessas, owl_message_get_type(m));
-    stash = gv_stashpv("BarnOwl::Message", 1);
-  }
-  hr = sv_bless(hr,stash);
-  owl_free(type);
-  owl_free(blessas);
-  return hr;
+  return (SV*)m;
 }
 
 SV *owl_perlconfig_curmessage2hashref(void) /*noproto*/
@@ -125,54 +42,9 @@
   return owl_perlconfig_message2hashref(owl_view_get_element(v, curmsg));
 }
 
-/* XXX TODO: Messages should round-trip properly between
-   message2hashref and hashref2message. Currently we lose
-   zephyr-specific properties stored in the ZNotice_t
- */
 owl_message * owl_perlconfig_hashref2message(SV *msg)
 {
-  owl_message * m;
-  HE * ent;
-  I32 count, len;
-  char *key,*val;
-  HV * hash;
-  struct tm tm;
-
-  hash = (HV*)SvRV(msg);
-
-  m = owl_message_new();
-  owl_message_init(m);
-
-  count = hv_iterinit(hash);
-  while((ent = hv_iternext(hash))) {
-    key = hv_iterkey(ent, &len);
-    val = SvPV_nolen(hv_iterval(hash, ent));
-    if(!strcmp(key, "type")) {
-      owl_message_set_type(m, val);
-    } else if(!strcmp(key, "direction")) {
-      owl_message_set_direction(m, owl_message_parse_direction(val));
-    } else if(!strcmp(key, "private")) {
-      SV * v = hv_iterval(hash, ent);
-      if(SvTRUE(v)) {
-        owl_message_set_isprivate(m);
-      }
-    } else if (!strcmp(key, "hostname")) {
-      owl_message_set_hostname(m, val);
-    } else if (!strcmp(key, "zwriteline")) {
-      owl_message_set_zwriteline(m, val);
-    } else if (!strcmp(key, "time")) {
-      m->timestr = owl_strdup(val);
-      strptime(val, "%a %b %d %T %Y", &tm);
-      m->time = mktime(&tm);
-    } else {
-      owl_message_set_attribute(m, key, val);
-    }
-  }
-  if(owl_message_is_type_admin(m)) {
-    if(!owl_message_get_attribute_value(m, "adminheader"))
-      owl_message_set_attribute(m, "adminheader", "");
-  }
-  return m;
+  return (owl_message*)SvREFCNT_inc(msg);
 }
 
 /* Calls in a scalar context, passing it a hash reference.

Modified: branches/barnowl_sqlite/owl/perlwrap.pm
===================================================================
--- branches/barnowl_sqlite/owl/perlwrap.pm	2008-01-12 07:26:49 UTC (rev 849)
+++ branches/barnowl_sqlite/owl/perlwrap.pm	2008-01-12 08:43:25 UTC (rev 850)
@@ -289,16 +289,40 @@
 #####################################################################
 
 package BarnOwl::Message;
+use POSIX qw(ctime);
 
+my $__next_id;
+$__next_id = 1 unless defined($__next_id);
+
 sub new {
     my $class = shift;
-    my %args = (@_);
+    my $time = time;
+    my $timestr = ctime($time);
+    $timestr =~ s/\n$//;
+    my %args = (
+        id        => $__next_id++,
+        deleted   => 0,
+        time      => $timestr,
+        _time     => $time,
+        direction => 'none',
+        @_);
+    if(exists $args{loginout} && !exists $args{login}) {
+        $args{login} = $args{loginout};
+        delete $args{loginout};
+    }
     if($class eq __PACKAGE__ && $args{type}) {
         $class = "BarnOwl::Message::" . ucfirst $args{type};
     }
     return bless {%args}, $class;
 }
 
+sub __set_attribute {
+    my $self = shift;
+    my $attr = shift;
+    my $val  = shift;
+    $self->{$attr} = $val;
+}
+
 sub type        { return shift->{"type"}; }
 sub direction   { return shift->{"direction"}; }
 sub time        { return shift->{"time"}; }
@@ -306,7 +330,7 @@
 sub body        { return shift->{"body"}; }
 sub sender      { return shift->{"sender"}; }
 sub recipient   { return shift->{"recipient"}; }
-sub login       { return shift->{"login"}; }
+sub login       { return shift->{"login"} || ""; }
 sub is_private  { return shift->{"private"}; }
 
 sub is_login    { return shift->login eq "login"; }


home help back first fref pref prev next nref lref last post