CVS: beepcore-c/base/test all_tests,NONE,1.1 beep_test_msg.h,NONE,1.1 unit_base64.c,NONE,1.1 unit_cbeep_io.c,NONE,1.1 unit_cbeep_io.save,NONE,1.1 unit_cbeep_notify.c,NONE,1.1 unit_cbeep_notify.save,NONE,1.1 unit_cbeep_query.c,NONE,1.1 unit_cbeep_query.save,NONE,1.1 unit_cbeep_shortframe.c,NONE,1.1 unit_cbeep_shortframe.save,NONE,1.1 unit_channel_0.c,NONE,1.1 unit_frame_aggregate.c,NONE,1.1 unit_notify_stubs.c,NONE,1.1 unit_notify_stubs.h,NONE,1.1

Chris Hanson <[email protected]> Fri, 06 Sep 2002 18:15:25 -0700
Newsgroups gmane.network.beep.beepcore.c.cvs
Message-ID <[email protected]>
Update of /cvsroot/beepcore-c/beepcore-c/base/test
In directory usw-pr-cvs1:/tmp/cvs-serv22777/base/test

Added Files:
	all_tests beep_test_msg.h unit_base64.c unit_cbeep_io.c 
	unit_cbeep_io.save unit_cbeep_notify.c unit_cbeep_notify.save 
	unit_cbeep_query.c unit_cbeep_query.save 
	unit_cbeep_shortframe.c unit_cbeep_shortframe.save 
	unit_channel_0.c unit_frame_aggregate.c unit_notify_stubs.c 
	unit_notify_stubs.h 
Log Message:
Rename "core" directories to "base".


--- NEW FILE: all_tests ---
# Run this from the "test" directory.
#
# Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
# 
# The contents of this file are subject to the Blocks Public License (the
# "License"); You may not use this file except in compliance with the License.
# 
# You may obtain a copy of the License at http://www.beepcore.org/
# 
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
# for the specific language governing rights and limitations under the
# License.
#
#


rm -f a.out

echo TESTING IO
gcc -Wall -pedantic -O2 -I . -I ../generic unit_cbeep_io.c ../generic/CBEEP.c ../generic/channel_0.c ../generic/base64.c ../generic/xml_entities.c -o a.out
a.out 2>&1 >unit_cbeep_io.out
diff unit_cbeep_io.save unit_cbeep_io.out

echo TESTING QUERY
gcc -Wall -pedantic -O2 -I . -I ../generic unit_cbeep_query.c ../generic/CBEEP.c ../generic/channel_0.c ../generic/base64.c  ../generic/xml_entities.c -o a.out
a.out 2>&1 >unit_cbeep_query.out
diff unit_cbeep_query.save unit_cbeep_query.out

echo TESTING SHORTFRAME
gcc -Wall -pedantic -I . -I ../generic unit_cbeep_shortframe.c ../generic/CBEEP.c ../generic/channel_0.c ../generic/base64.c ../generic/xml_entities.c -o a.out
a.out 2>&1 >unit_cbeep_shortframe.out
diff unit_cbeep_shortframe.save unit_cbeep_shortframe.out

echo TESTING NOTIFIES
gcc -Wall -pedantic -I . -I ../generic unit_cbeep_notify.c ../generic/CBEEP.c ../generic/channel_0.c ../generic/base64.c ../generic/xml_entities.c -o a.out
a.out 2>&1 >unit_cbeep_notify.out
diff unit_cbeep_notify.save unit_cbeep_notify.out

rm a.out

--- NEW FILE: beep_test_msg.h ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */
/*
 * $Id: beep_test_msg.h,v 1.1 2002/09/07 01:15:23 cphmit Exp $
 *
 * beep_test.msg.h
 *
 * a structure of messages we use in various tests.
 */
#include <stddef.h>

struct beep_test_msg {char frametype, * testname, * testdata;} beep_msgs[] = {
  /* 
   * greeting messages: empty and populated
   */
  {'R', "greeting: empty unary:", "Content-Type: application/beep+xml\r\n\r\n<greeting />"}, 
  {'R', "greeting: no MIME:", "<greeting />"}, 
  {'R', "greeting: no MIME leading w/s:", "\r\n<greeting />"}, 
  {'R', "greeting: trailing whitespace:", "Content-Type: application/beep+xml\r\n\r\n<greeting />\r\n"},
  {'R', "greeting: leading whitespace:", "Content-Type: application/beep+xml\r\n\r\n<greeting />\r\n"},
  {'R', "greeting: empty binary:", "Content-Type: application/beep+xml\r\n\r\n<greeting></greeting>"}, 
  {'R', "greeting: empty w/attrib:", "Content-Type: application/beep+xml\r\n\r\n<greeting localize='eng/us' features = 'test features'/>"}, 
  {'R', "greeting: empty profile:", "Content-Type: application/beep+xml\r\n\r\n<greeting>\r\n   <profile uri='http://iana.org/beep/TLS' />\r\n</greeting>\r\n"},
  {'R', "greeting: multiple empty profiles:", "Content-Type: application/beep+xml\r\n\r\n<greeting>\r\n   <profile uri='http://iana.org/beep/TLS' />\r\n\r\n   <profile uri='http://iana.org/beep/SASL/OTP' />\r\n   <profile uri='http://iana.org/beep/FOO' /></greeting>\r\n"},
  
  /* start message transaction set 
   *
   * starts: 1 and N profiles.  one piggyback example
   * replies success: with and without piggyback
   * replies error:
   */
  {'M', "start: chan=1: 1 empty profile:", "Content-Type: application/beep+xml\r\n\r\n<start number='1'>\r\n   <profile uri='http://iana.org/beep/SASL/OTP' />\r\n</start>\r\n"},
  {'M', "start: chan=1: 2 empty profiles:", "Content-Type: application/beep+xml\r\n\r\n<start number='1'>\r\n   <profile uri='http://iana.org/beep/SASL/OTP' />\r\n   <profile uri='http://iana.org/beep/SASL/ANONYMOUS' />\r\n</start>\r\n"},
  {'M', "start: chan=2: 1 empty profile:", "Content-Type: application/beep+xml\r\n\r\n<start number='2'>\r\n   <profile uri='http://iana.org/beep/FOO' />\r\n</start>\r\n\r\n"},
  {'M', "start: chan=1: non-empty profile w/CDATA:", "Content-Type: application/beep+xml\r\n\r\n<start number='1'>\r\n   <profile uri='http://iana.org/beep/TLS'>\r\n       <![CDATA[<ready />]]>\r\n   </profile>\r\n</start>\r\n"},
  {'M', "start: chan=11: non-empty profile with b64 CDATA:", "<start number='11' ><profile uri='http://iana.org/beep/SASL/OTP' encoding='base64' >AQEBT25jZSB1cG9uIGEgbWlkbmlnaHQgZHJlYXJ5</profile></start>"},

  {'R', "confirm: empty profile:", "Content-Type: application/beep+xml\r\n\r\n<profile uri='http://iana.org/beep/SASL/OTP' />\r\n"},
  {'R', "confirm: profile w/CDATA:", "Content-Type: application/beep+xml\r\n\r\n<profile uri='http://iana.org/beep/TLS'>\r\n    <![CDATA[<proceed />]]>\r\n</profile>\r\n"},

  {'E', "error: with text:", "Content-Type: application/beep+xml\r\n\r\n<error code='550'>all requested profiles are\r\nunsupported</error>\r\n"},
  {'E', "error: with text and entities:", "Content-Type: application/beep+xml\r\n\r\n<error code='501'>number attribute\r\nin &lt;start&gt; element must be odd-valued</error>\r\n"},

  /* close message set (error handled above) */
  {'M', "close: no channel:", "Content-Type: application/beep+xml\r\n\r\n<close code='200' />\r\n"},
  {'M', "close: channel 0:", "Content-Type: application/beep+xml\r\n\r\n<close number='0' code='200' />\r\n"},
  {'M', "close: channel 1:", "Content-Type: application/beep+xml\r\n\r\n<close number='1' code='200' />\r\n"},
  {'M', "close: with text:", "Content-Type: application/beep+xml\r\n\r\n<close number='1' code='200'>Session timout.</close>\r\n"},

  {'R', "ok: unary:", "Content-Type: application/beep+xml\r\n\r\n<ok />\r\n"},
  {'R', "ok: binary:", "Content-Type: application/beep+xml\r\n\r\n<ok></ok>\r\n"},
  /* elephant in karthoum */
  {' ', NULL, NULL}
};


--- NEW FILE: unit_base64.c ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */

#include <beepcore-c/CBEEP.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <strings.h>

#include <beepcore-c/base64.h>


#ifndef ASSERT
#define ASSERT(x) assert(x)
#endif

int main () {

  int nbytes;

  char * rawstr = "Once upon a midnight dreary as I pondered weak and weary I heard a rapping tap tap tapping at my parlor door.";
  char * codedstr = "T25jZSB1cG9uIGEgbWlkbmlnaHQgZHJlYXJ5IGFzIEkgcG9uZGVyZWQgd2VhayBhbmQgd2Vhcnkg\r\nSSBoZWFyZCBhIHJhcHBpbmcgdGFwIHRhcCB0YXBwaW5nIGF0IG15IHBhcmxvciBkb29yLg=="; 

  unsigned char * resultstr;
  struct session mysession;


  char source[] = "[email protected]";
  char dest[256];
  unsigned char *foo, *bar;
  int i;
  

  mysession.malloc = malloc;
  mysession.free   = free;

  printf("encode test: ");
  resultstr = base64_encode(&mysession, rawstr, strlen(rawstr));
  if (resultstr && !bcmp(resultstr, codedstr, strlen(codedstr))) {
    free(resultstr);
    printf("passed\n");
  } else {
    printf("FAILED'\n");
  }

  printf("decode test: ");
  nbytes = base64_decode(&mysession, codedstr, &resultstr);
  if (nbytes > 0 && !bcmp(resultstr, rawstr, strlen(rawstr))) {
    free(resultstr);
    printf("passed\n");
  } else {
    printf("FAILED'\n");  }

  printf("detect length error: ");
  nbytes = base64_decode(&mysession, "AA", &resultstr);
  if (-2 == nbytes) {
    printf("passed\n");
  } else {
    printf("FAILED\n");
  }

  printf("detect coding error: ");
  nbytes = base64_decode(&mysession, "A}}A", &resultstr);
  if (-2 == nbytes) {
    printf("passed\n");
  } else {
    printf("FAILED\n");
  }

  printf("detect trailers error: ");
  nbytes = base64_decode(&mysession, "A===", &resultstr);
  if (-2 == nbytes) {
    printf("passed\n");
  } else {
    printf("FAILED\n");
  }

  resultstr = "aa==";
  nbytes = 1;
  printf("base64_dsize: of '%s' should be %d: actually %d\n", 
	 resultstr, nbytes, base64_dsize(resultstr));

  resultstr = "aaa=";
  nbytes = 2;
  printf("base64_dsize: of '%s' should be %d: actually %d\n", 
	 resultstr, nbytes, base64_dsize(resultstr));

  resultstr = "aaaa";
  nbytes = 3;
  printf("base64_dsize: of '%s' should be %d: actually %d\n", 
	 resultstr, nbytes, base64_dsize(resultstr));

  nbytes = 1;
  printf("base64_esize: of %d should be %d: actually %d\n", 
	 nbytes, 4, base64_esize(nbytes));

  nbytes = 2;
  printf("base64_esize: of %d should be %d: actually %d\n", 
	 nbytes, 4, base64_esize(nbytes));

  nbytes = 3;
  printf("base64_esize: of %d should be %d: actually %d\n", 
	 nbytes, 4, base64_esize(nbytes));


  /*
   * incremental test and print.
   */

  memset(dest, 0, 256);

  for (i = 0; i < 10; i++) {
    dest[i] = source[i];

    foo = base64_encode(&mysession, dest, i+1);
    base64_decode(&mysession, foo, &bar);

    printf("\tinput=`%s` encoded=`%s` decoded=`%s`\n", dest, foo, bar);

    free(foo);
    free(bar);
  }

  foo = base64_encode(&mysession, rawstr, strlen(rawstr));
  base64_decode(&mysession, foo, &bar);

  printf("\tinput=`%s` encoded=`%s` decoded=`%s`\n", dest, foo, bar);

  free(foo);
  free(bar);
  

  /*
   * done-zies
   */
  exit(0);
}



--- NEW FILE: unit_cbeep_io.c ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */

#include <beepcore-c/CBEEPint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

char * profiles[3] = {
  "http://first/profile",
  "http://second/profile",
  NULL
  };

void notify_lower(struct session * s, int i) {
  char * cp;
  printf("Notify lower: %d\n", i);
  cp = bll_status_text(s);
  if (cp==NULL) cp = ">>NULL<<";
  printf("  text: %s\n", cp);
  printf("  chan: %ld\n", bll_status_channel(s));
}

void notify_upper(struct session * s, long c, int i) {
  printf("Notify upper: %ld, %d\n", c, i);
}

int main() {
  struct session * sess;
  struct beep_iovec * biv;
  int total_size = 0;
  setbuf(stdout, NULL);
  printf("Starting...\n"); fflush(stdout);
  sess = bll_session_create(
    malloc, free, notify_lower, notify_upper,
    'L', "features", "localize", profiles, NULL, NULL);
  printf("FIRST CALL\n"); fflush(stdout);
  bll_session_debug_print(sess, stdout);

  biv = bll_out_buffer(sess);
  while (biv != NULL && 0 < biv->vec_count && 0 < biv->iovec[0].iov_len) {
    int size; int inx;
    for (inx = size = 0; inx < biv->vec_count; inx++)
      size += biv->iovec[inx].iov_len;
    if (25 < size) size = 25;
    total_size += size;
    bll_out_count(sess, size);
    biv = bll_out_buffer(sess);
    printf("\nAFTER %d OCTETS:\n", total_size);
    bll_session_debug_print(sess,stdout);
  }

  printf("Yes so far!\n");

  /* OK, here test the frame entry stuff. */
  {
    char * s;
    char * p;
    int i; int j;
    struct beep_iovec * x;

    s = "RPY 0 0 . 0 48\r\ncontent-type:application/xml+beep\r\n\r\n<greeting/>END\r\nSEQ 0 100 6000\r\n";
    p = s;
    j = 0;
    while (*p) {
      x = bll_in_buffer(sess);
      if (x == NULL) printf("NULL found\n");
      assert(x != NULL);
      if (1 != x->vec_count) printf("1 not found\n");
      assert(1 == x->vec_count); /* Just because I that's how it's implemented */
      i = 10;
      if (x->iovec[0].iov_len < i) i = x->iovec[0].iov_len;
      if (strlen(p) < i) i = strlen(p);
      memmove(x->iovec[0].iov_base, p, i);
      p += i; j += i;
      bll_in_count(sess, i);
      fprintf(stdout, "\nAFTER %d BYTES:\n", j);
      bll_session_debug_print(sess, stdout);
   }
 }

  biv = bll_out_buffer(sess);
  printf("\nWE SHOULD HAVE MORE NOW!\n");
  bll_session_debug_print(sess,stdout);
  while (biv != NULL && 0 < biv->vec_count && 0 < biv->iovec[0].iov_len) {
    int size; int inx;
    for (inx = size = 0; inx < biv->vec_count; inx++)
      size += biv->iovec[inx].iov_len;
    if (25 < size) size = 25;
    total_size += size;
    bll_out_count(sess, size);
    biv = bll_out_buffer(sess);
    printf("\nAFTER %d OCTETS:\n", total_size);
    bll_session_debug_print(sess,stdout);
  }

  /* Now we're going to queue three messages on channel 0, and make sure
     they go out in the right order. */

  {
    struct frame * f1;
    struct frame * f2;
    struct frame * f3;
    long ll;
    f1 = blu_frame_create(sess, 10);
    f1->channel_number = 0; f1->message_number = 1; f1->more = '*'; f1->msg_type = 'M';
    strcpy(f1->payload, "AAAAAAAAAA");
    f2 = blu_frame_create(sess, 10);
    f2->channel_number = 0; f2->message_number = 1; f2->more = '.'; f2->msg_type = 'M';
    strcpy(f2->payload, "BBBBBBBBBB");
    f3 = blu_frame_create(sess, 10);
    f3->channel_number = 0; f3->message_number = 2; f3->more = '.'; f3->msg_type = 'M';
    strcpy(f3->payload, "CCCCCCCCCC");

    ll = blu_local_window_set(sess, 0, 8000); /* Test creation of SEQ messages */
    printf("PREVIOUS WINDOW WAS %ld\n", ll);
    blu_frame_send(f1);
    blu_frame_send(f3);
    blu_frame_send(f2);

    printf("\n\nHERE WE GO WITH OUT OF ORDER DATA\n");
    bll_session_debug_print(sess,stdout);

    biv = bll_out_buffer(sess);
    while (biv != NULL && 0 < biv->vec_count && 0 < biv->iovec[0].iov_len) {
      int size; int inx;
      for (inx = size = 0; inx < biv->vec_count; inx++)
        size += biv->iovec[inx].iov_len;
      if (5 < size) size = 5;
      total_size += size;
      bll_out_count(sess, size);
      biv = bll_out_buffer(sess);
      printf("\nAFTER %d OCTETS:\n", total_size);
      bll_session_debug_print(sess,stdout);
    }

    printf("Was it good for you?\n");

  }
  return 0;
}


--- NEW FILE: unit_cbeep_io.save ---
Starting...
Notify lower: 3
  text: >>NULL<<
  chan: -1
FIRST CALL
Start of dump, session at 2C6F0
  in_buffer.vec_count=1
  in_buffer.iov_len[0] = 78
  in_buffer.iov_base[0] = 2C894 = ''
  out_buffer.vec_count=3
  out_buffer.iov_len[0] = 17
  out_buffer.iov_base[0] = 2C844 = 'RPY 0 0 . 0 186
'
  out_buffer.iov_len[1] = 186
  out_buffer.iov_base[1] = 2D03C = 'content-type: application/xml+beep

<greeting features='features' localize='localize'>
  <profile uri='http://first/profile'/>
  <profile uri='http://second/profile'/>
[...2972 lines suppressed...]

<greeting/><<<
      NULL FRAME POINTER
    out_frame:
      NULL FRAME POINTER
    commit_frame:
      NULL FRAME POINTER
    apparent out window: 4096
    cur_out_msg type=' ', number=-1
    cur_in_seq=48
    max_in_seq=10241
    cur_in_buf=48
    max_in_buf=8000
    cur_out_seq=216
    max_out_seq=6100
    SENT messages: 
      Sent 1 msg_more='.' rpy_more=' '
      Sent 2 msg_more='.' rpy_more=' '
    RCVD messages: NONE
Was it good for you?

--- NEW FILE: unit_cbeep_notify.c ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */

#include <beepcore-c/CBEEPint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

char * profiles[3] = {
  "http://first/profile",
  "http://second/profile",
  NULL
  };

void notify_lower(struct session * s, int i) {
  char * cp;
  printf("Notify lower: %d\n", i);
  cp = bll_status_text(s);
  if (cp==NULL) cp = ">>NULL<<";
  printf("  text: %s\n", cp);
  printf("  chan: %ld\n", bll_status_channel(s));
}

void notify_upper(struct session * s, long c, int i) {
  printf("Notify upper: %ld, %d\n", c, i);
}

int main() {
  struct session * sess;
  struct frame * f;
  struct beep_iovec * biv;
  int total_size = 0;
  setbuf(stdout, NULL);
  printf("Starting...\n"); fflush(stdout);
  sess = bll_session_create(
    malloc, free, notify_lower, notify_upper,
    'L', "features", "localize", profiles, NULL, NULL);
  printf("FIRST CALL\n"); fflush(stdout);
  /* bll_session_debug_print(sess, stdout); */

  biv = bll_out_buffer(sess);
  while (biv != NULL && 0 < biv->vec_count && 0 < biv->iovec[0].iov_len) {
    int size; int inx;
    for (inx = size = 0; inx < biv->vec_count; inx++)
      size += biv->iovec[inx].iov_len;
    total_size += size;
    bll_out_count(sess, size);
    biv = bll_out_buffer(sess);
    printf("\nAFTER %d OCTETS:\n", total_size);
    /* bll_session_debug_print(sess,stdout); */
  }

  printf("GREETING SENT - SHOULD HAVE SEEN notify_upper 0,3\n");
  /* bll_session_debug_print(sess,stdout); */

  /* OK, here test the greeting reception */
  {
    char * s;
    char * p;
    int i; int j;
    struct beep_iovec * x;

    s = "RPY 0 0 . 0 48\r\ncontent-type:application/beep+xml\r\n\r\n<greeting/>END\r\nSEQ 0 0 6000\r\n";
    p = s;
    j = 0;
    while (*p) {
      x = bll_in_buffer(sess);
      if (x == NULL) printf("NULL found\n");
      assert(x != NULL);
      if (1 != x->vec_count) printf("1 not found\n");
      assert(1 == x->vec_count); /* Just because I that's how it's implemented */
      i = strlen(s);
      if (x->iovec[0].iov_len < i) i = x->iovec[0].iov_len;
      if (strlen(p) < i) i = strlen(p);
      memmove(x->iovec[0].iov_base, p, i);
      p += i; j += i;
      bll_in_count(sess, i);
      /* fprintf(stdout, "\nAFTER %d BYTES:\n", j);
         bll_session_debug_print(sess, stdout); */
    }
  }
  printf("GREETING ANSWER QUEUED\n");
  /* bll_session_debug_print(sess, stdout); */
  printf("NEXT, TWO NOTIFIES AS I READ IT\n");
  f = blu_frame_read(sess, 0);

  printf("GREETING ANSWER COMPLETE - SHOULD HAVE SEEN 2 NOTIFY_UPPERS\n");

  /* Now send two frames and check the notifies */
  f = blu_frame_create(sess, 3);
  f->msg_type = 'M';
  f->message_number = 12;
  f->channel_number = 0;
  f->more = '.';
  strcpy(f->payload, "ONE");
  blu_frame_send(f);
  f = blu_frame_create(sess, 3);
  f->msg_type = 'M';
  f->message_number = 14;
  f->channel_number = 0;
  f->more = '.';
  strcpy(f->payload, "TWO");
  blu_frame_send(f);
  /* Now send it out */
  biv = bll_out_buffer(sess);
  while (biv != NULL && 0 < biv->vec_count && 0 < biv->iovec[0].iov_len) {
    int size; int inx;
    for (inx = size = 0; inx < biv->vec_count; inx++)
      size += biv->iovec[inx].iov_len;
    total_size += size;
    bll_out_count(sess, size);
    biv = bll_out_buffer(sess);
    /* printf("\nAFTER %d OCTETS:\n", total_size); */
    /* bll_session_debug_print(sess,stdout); */
  }
  printf("TWO MESSAGES SENT\n");
  /* bll_session_debug_print(sess,stdout); */
  /* Now answer them, but include a message in the middle */
  {
    char * s;
    char * p;
    int i; int j;
    struct beep_iovec * x;

    s = "RPY 0 12 . 48 3\r\nONEEND\r\nMSG 0 29 . 51 5\r\nTHREEEND\r\nRPY 0 14 . 56 3\r\nTWOEND\r\n";
    p = s;
    j = 0;
    while (*p) {
      x = bll_in_buffer(sess);
      if (x == NULL) printf("NULL found\n");
      assert(x != NULL);
      if (1 != x->vec_count) printf("1 not found\n");
      assert(1 == x->vec_count); /* Just because I that's how it's implemented */
      i = strlen(s);
      if (x->iovec[0].iov_len < i) i = x->iovec[0].iov_len;
      if (strlen(p) < i) i = strlen(p);
      memmove(x->iovec[0].iov_base, p, i);
      p += i; j += i;
      bll_in_count(sess, i);
      /* fprintf(stdout, "\nAFTER %d BYTES:\n", j);
         bll_session_debug_print(sess, stdout); */
    }
  }
  printf("THREE MESSSAGES IN\n");
  /* bll_session_debug_print(sess, stdout); */

  printf("NOW READING THREE MESSAGES\n");
  f = blu_frame_read(sess, 0); printf("%s\n", f->payload); blu_frame_destroy(f);
  f = blu_frame_read(sess, 0); printf("%s\n", f->payload); blu_frame_destroy(f);
  f = blu_frame_read(sess, 0); printf("%s\n", f->payload); blu_frame_destroy(f);

  printf("REPLY TO MESSAGE #29...\n");
  f = blu_frame_create(sess, 5);
  f->message_number = 29;
  f->msg_type = 'R';
  f->channel_number = 0;
  f->more = '.';
  blu_frame_send(f);
  printf("REPLY SENT. NOW DRAINING...\n");
  /* Now send it out */
  biv = bll_out_buffer(sess);
  while (biv != NULL && 0 < biv->vec_count && 0 < biv->iovec[0].iov_len) {
    int size; int inx;
    for (inx = size = 0; inx < biv->vec_count; inx++)
      size += biv->iovec[inx].iov_len;
    total_size += size;
    bll_out_count(sess, size);
    biv = bll_out_buffer(sess);
    /* printf("\nAFTER %d OCTETS:\n", total_size); */
    /* bll_session_debug_print(sess,stdout); */
  }


  printf("ALL DONE!\n");

  return 0;
}


--- NEW FILE: unit_cbeep_notify.save ---
Starting...
Notify upper: 0, 3
Notify lower: 3
  text: >>NULL<<
  chan: -1
FIRST CALL
Notify upper: 0, 3
Notify lower: 3
  text: >>NULL<<
  chan: -1

AFTER 208 OCTETS:

AFTER 223 OCTETS:
GREETING SENT - SHOULD HAVE SEEN notify_upper 0,3
Notify upper: 0, 1
Notify upper: 0, 2
GREETING ANSWER QUEUED
NEXT, TWO NOTIFIES AS I READ IT
Notify upper: 0, 4
Notify upper: 0, 5
GREETING ANSWER COMPLETE - SHOULD HAVE SEEN 2 NOTIFY_UPPERS
Notify upper: 0, 3
Notify lower: 3
  text: >>NULL<<
  chan: -1
Notify upper: 0, 3
Notify lower: 3
  text: >>NULL<<
  chan: -1
Notify upper: 0, 3
TWO MESSAGES SENT
Notify upper: 0, 1
Notify upper: 0, 2
Notify upper: 0, 1
Notify upper: 0, 2
Notify upper: 0, 1
Notify upper: 0, 2
THREE MESSSAGES IN
NOW READING THREE MESSAGES
ONE
THREE
Notify upper: 0, 4
TWO
REPLY TO MESSAGE #29...
Notify upper: 0, 3
Notify lower: 3
  text: >>NULL<<
  chan: -1
REPLY SENT. NOW DRAINING...
Notify upper: 0, 3
Notify upper: 0, 5
ALL DONE!

--- NEW FILE: unit_cbeep_query.c ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */

#include <beepcore-c/CBEEP.h>
#include <beepcore-c/CBEEPint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

extern void bll_frame_debug_print(struct frame *, FILE *);

char * profiles[3] = {
  "http://first/profile",
  "http://second/profile",
  NULL
  };

void notify_lower(struct session * s, int i) {
  char * cp;
  printf("Notify lower: %d\n", i);
  cp = bll_status_text(s);
  if (cp==NULL) cp = ">>NULL<<";
  printf("  text: %s\n", cp);
  printf("  chan: %ld\n", bll_status_channel(s));
}

void notify_upper(struct session * s, long c, int i) {
  printf("Notify upper: %ld, %d\n", c, i);
}

int main() {
  struct session * sess;
  setbuf(stdout, NULL);
  printf("Starting...\n"); fflush(stdout);
  sess = bll_session_create(
    malloc, free, notify_lower, notify_upper,
    'L', "features", "localize", profiles, NULL, NULL);
  printf("FIRST CALL\n"); fflush(stdout);
  bll_session_debug_print(sess, stdout);

  {

    /* Now we queue six frames incoming, to test the query routine */
    struct frame * f1 = blu_frame_create(sess,10);
    struct frame * f2 = blu_frame_create(sess,10);
    struct frame * f3 = blu_frame_create(sess,10);
    struct frame * f4 = blu_frame_create(sess,10);
    struct frame * f5 = blu_frame_create(sess,10);
    struct frame * f6 = blu_frame_create(sess,10);

    struct frame * answer;

    printf("Begin now.\n");
    strcpy(f1->payload, "one");
    strcpy(f2->payload, "two");
    strcpy(f3->payload, "three");
    strcpy(f4->payload, "four");
    strcpy(f5->payload, "five");
    strcpy(f6->payload, "six");

    f1->next_on_channel = f2;
    f2->next_on_channel = f3;
    f3->next_on_channel = f4;
    f4->next_on_channel = f5;
    f5->next_on_channel = f6;

    f1->msg_type = 'M'; f1->message_number = 3; f1->more = '*';
    f2->msg_type = 'M'; f2->message_number = 3; f2->more = '.';
    f3->msg_type = 'M'; f3->message_number = 7; f3->more = '*';
    f4->msg_type = 'M'; f4->message_number = 9; f4->more = '.';
    f5->msg_type = 'M'; f5->message_number = 7; f5->more = '.';
    f6->msg_type = 'M'; f6->message_number = 9; f6->more = '.';
    f1->channel_number = 0;
    f2->channel_number = 0;
    f3->channel_number = 0;
    f4->channel_number = 0;
    f5->channel_number = 0;
    f6->channel_number = 0;

    sess->channel->in_frame = f1; /* Zap! */
    printf("\nFIRST QUERY TEST\n");
    bll_session_debug_print(sess,stdout);
    printf("Good so far...\n");
    answer = blu_frame_query(sess, 0, ' ', -1, -1, '*');
    if (answer != f1) printf("Wrong at 1\n");
    bll_session_debug_print(sess,stdout);
    bll_frame_debug_print(answer,stdout);
    if (answer->next_on_channel != NULL) printf("Wrong at 2\n");
    if (sess->channel->in_frame != f2) printf("Wrong at 3\n");
    printf("If you didn't see \"wrong at ...\" then it worked.\n");

    f1->next_on_channel = f2;   f1->next_in_message = NULL;
    f2->next_on_channel = f3;   f2->next_in_message = NULL;
    f3->next_on_channel = f4;   f3->next_in_message = NULL;
    f4->next_on_channel = f5;   f4->next_in_message = NULL;
    f5->next_on_channel = f6;   f5->next_in_message = NULL;
    f6->next_on_channel = NULL; f6->next_in_message = NULL;
    sess->channel->in_frame = f1; /* Zap! */

    printf("\nSECOND QUERY TEST\n");
    answer = blu_frame_query(sess, 0, 'M', -1, -1, '.');
    bll_session_debug_print(sess,stdout);
    printf("Answer:\n");
    bll_frame_debug_print(answer,stdout);
    printf("f2:\n");
    bll_frame_debug_print(f2,stdout);
    if (answer != f1 ||
	f1->next_in_message != f2 ||
	sess->channel->in_frame != f1) printf("Wrong at 4\n");
    if (f1->next_on_channel != NULL || f2->next_on_channel != NULL ||
	f2->next_in_message != NULL) printf("Wrong at 5\n");
    printf("If no \"wrong at\" above, it seems to have worked.\n");

    printf("\nTHIRD QUERY TEST\n");
    f1->next_on_channel = f2;   f1->next_in_message = NULL;
    f2->next_on_channel = f3;   f2->next_in_message = NULL;
    f3->next_on_channel = f4;   f3->next_in_message = NULL;
    f4->next_on_channel = f5;   f4->next_in_message = NULL;
    f5->next_on_channel = f6;   f5->next_in_message = NULL;
    f6->next_on_channel = NULL; f6->next_in_message = NULL;
    sess->channel->in_frame = f1; /* Zap! */

    answer = blu_frame_query(sess, 0, 'M', 7, -1, '.');
    bll_session_debug_print(sess,stdout);
    printf("Answer:\n");
    bll_frame_debug_print(answer,stdout);
    printf("f5:\n");
    bll_frame_debug_print(f5,stdout);
    if (answer != f3 ||
	f3->next_in_message != f5 ||
	sess->channel->in_frame != f1) printf("Wrong at 6\n");
    if (f3->next_on_channel != NULL || f5->next_on_channel != NULL ||
	f5->next_in_message != NULL) printf("Wrong at 7\n");
    if (f1->next_on_channel != f2 || f2->next_on_channel != f4 ||
	f4->next_on_channel != f6 || f6->next_on_channel != NULL)
	  printf("Wrong at 8\n");
    printf("If no \"wrong at\" above, it seems to have worked.\n");

    printf("\nFOURTH QUERY TEST\n");
    f1->next_on_channel = f2;   f1->next_in_message = NULL;
    f2->next_on_channel = f3;   f2->next_in_message = NULL;
    f3->next_on_channel = f4;   f3->next_in_message = NULL;
    f4->next_on_channel = f5;   f4->next_in_message = NULL;
    f5->next_on_channel = f6;   f5->next_in_message = NULL;
    f6->next_on_channel = NULL; f6->next_in_message = NULL;
    sess->channel->in_frame = f1; /* Zap! */

    /* Note there are two complete #9 messages. Test we only get one */
    answer = blu_frame_query(sess, 0, 'M', 9, -1, '.');
    bll_session_debug_print(sess,stdout);
    printf("Answer:\n");
    bll_frame_debug_print(answer,stdout);
    printf("f6:\n");
    bll_frame_debug_print(f6,stdout);
    if (answer != f4 ||
	f4->next_in_message != NULL ||
	sess->channel->in_frame != f1) printf("Wrong at 9\n");
    if (f4->next_on_channel != NULL || f6->next_on_channel != NULL ||
	f6->next_in_message != NULL) printf("Wrong at 10\n");
    if (f1->next_on_channel != f2 || f2->next_on_channel != f3 ||
	f3->next_on_channel != f5 || f5->next_on_channel != f6 ||
	f6->next_on_channel != NULL)
	  printf("Wrong at 11\n");
    printf("If no \"wrong at\" above, it seems to have worked.\n");

    printf("\nFIFTH QUERY TEST\n");

    /* Note there are two complete #9 messages. 
       Test we get the other, and that end-of-list works. */
    answer = blu_frame_query(sess, 0, 'M', 9, -1, '.');
    bll_session_debug_print(sess,stdout);
    printf("Answer:\n");
    bll_frame_debug_print(answer,stdout);
    if (answer != f6 ||
	f4->next_in_message != NULL ||
	sess->channel->in_frame != f1) printf("Wrong at 12\n");
    if (f6->next_on_channel != NULL || f5->next_on_channel != NULL ||
	f6->next_in_message != NULL) printf("Wrong at 13\n");
    if (f1->next_on_channel != f2 || f2->next_on_channel != f3 ||
	f3->next_on_channel != f5 || f5->next_on_channel != NULL)
	  printf("Wrong at 14\n");
    printf("If no \"wrong at\" above, it seems to have worked.\n");


    printf("\nSIXTH QUERY TEST\n");
    f1->next_on_channel = f2;   f1->next_in_message = NULL;
    f2->next_on_channel = NULL; f2->next_in_message = NULL;
    sess->channel->in_frame = f1; /* Zap! */

    /* Check that grabbing *all* of a queue works. */
    answer = blu_frame_query(sess, 0, 'M', -1, -1, '.');
    bll_session_debug_print(sess,stdout);
    printf("Answer:\n");
    bll_frame_debug_print(answer,stdout);
    if (answer != f1 ||
	f1->next_in_message != f2 ||
	sess->channel->in_frame != NULL) printf("Wrong at 14\n");
    if (f1->next_on_channel != NULL || f2->next_on_channel != NULL)
	printf("Wrong at 15\n");
    printf("If no \"wrong at\" above, it seems to have worked.\n");

    printf("\nSEVENTH QUERY TEST\n");
    f1->next_on_channel = NULL;  f1->next_in_message = NULL;
    sess->channel->in_frame = f1; /* Zap! */

    /* Check that grabbing the only one on the queue works. */
    answer = blu_frame_query(sess, 0, 'M', -1, -1, '*');
    bll_session_debug_print(sess,stdout);
    printf("Answer:\n");
    bll_frame_debug_print(answer,stdout);
    if (answer != f1 ||
	f1->next_in_message != NULL ||
	sess->channel->in_frame != NULL) printf("Wrong at 16\n");
    printf("If no \"wrong at\" above, it seems to have worked.\n");


    printf("\nEIGTH QUERY TEST\n");
    f1->next_on_channel = NULL;  f1->next_in_message = NULL;
    sess->channel->in_frame = f1; /* Zap! */

    /* Check that missing works */
    answer = blu_frame_query(sess, 0, 'M', -1, -1, '.');
    bll_session_debug_print(sess,stdout);
    printf("Answer:\n");
    bll_frame_debug_print(answer,stdout);
    if (answer != NULL ||
	f1->next_in_message != NULL ||
	f1->next_on_channel != NULL ||
	sess->channel->in_frame != f1) printf("Wrong at 17\n");
    printf("If no \"wrong at\" above, it seems to have worked.\n");

  }

  return 0;
}


--- NEW FILE: unit_cbeep_query.save ---
Starting...
Notify lower: 3
  text: >>NULL<<
  chan: -1
FIRST CALL
Start of dump, session at 2CCA0
  in_buffer.vec_count=1
  in_buffer.iov_len[0] = 78
  in_buffer.iov_base[0] = 2CE44 = ''
  out_buffer.vec_count=3
  out_buffer.iov_len[0] = 17
  out_buffer.iov_base[0] = 2CDF4 = 'RPY 0 0 . 0 186
'
  out_buffer.iov_len[1] = 186
  out_buffer.iov_base[1] = 2D5EC = 'content-type: application/xml+beep

<greeting features='features' localize='localize'>
  <profile uri='http://first/profile'/>
  <profile uri='http://second/profile'/>
[...1025 lines suppressed...]
      msg_type='R' more='.'
      channel_number=0
      message_number=0
      answer_number =-1
      size=0, alloc=187
      payload=>>><<<
    apparent out window: 4096
    cur_out_msg type='R', number=0
    cur_in_seq=0
    max_in_seq=4096
    cur_in_buf=0
    max_in_buf=10241
    cur_out_seq=186
    max_out_seq=4096
    SENT messages: 
      Sent 0 msg_more='.' rpy_more=' '
    RCVD messages: NONE
Answer:
      NULL FRAME POINTER
If no "wrong at" above, it seems to have worked.

--- NEW FILE: unit_cbeep_shortframe.c ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */

#include <beepcore-c/CBEEPint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

char * profiles[3] = {
  "http://first/profile",
  "http://second/profile",
  NULL
  };

void notify_lower(struct session * s, int i) {
  char * cp;
  printf("Notify lower: %d\n", i);
  cp = bll_status_text(s);
  if (cp==NULL) cp = ">>NULL<<";
  printf("  text: %s\n", cp);
  printf("  chan: %ld\n", bll_status_channel(s));
}

void notify_upper(struct session * s, long c, int i) {
  printf("Notify upper: %ld, %d\n", c, i);
}

int main() {
  struct session * sess;
  struct beep_iovec * biv;
  int total_size = 0;
  setbuf(stdout, NULL);
  printf("Starting...\n"); fflush(stdout);
  sess = bll_session_create(
    malloc, free, notify_lower, notify_upper,
    'L', "features", "localize", profiles, NULL, NULL);
  printf("FIRST CALL\n"); fflush(stdout);
  bll_session_debug_print(sess, stdout);

  biv = bll_out_buffer(sess);
  while (biv != NULL && 0 < biv->vec_count && 0 < biv->iovec[0].iov_len) {
    int size; int inx;
    for (inx = size = 0; inx < biv->vec_count; inx++)
      size += biv->iovec[inx].iov_len;
    total_size += size;
    bll_out_count(sess, size);
    biv = bll_out_buffer(sess);
    printf("\nAFTER %d OCTETS:\n", total_size);
    bll_session_debug_print(sess,stdout);
  }

  printf("GREETING CLEANED OUT - START SHORTFRAME TEST\n");

  /* OK, here test the frame entry stuff for a really short frame. */
  {
    char * s;
    char * p;
    int i; int j;
    struct beep_iovec * x;

    s = "SEQ 0 100 5000\r\nMSG 0 9 . 0 11\r\n<greeting/>END\r\nSEQ 0 100 6000\r\n";
    p = s;
    j = 0;
    while (*p) {
      x = bll_in_buffer(sess);
      if (x == NULL) printf("NULL found\n");
      assert(x != NULL);
      if (1 != x->vec_count) printf("1 not found\n");
      assert(1 == x->vec_count); /* Just because I that's how it's implemented */
      i = strlen(s);
      if (x->iovec[0].iov_len < i) i = x->iovec[0].iov_len;
      if (strlen(p) < i) i = strlen(p);
      memmove(x->iovec[0].iov_base, p, i);
      p += i; j += i;
      bll_in_count(sess, i);
      fprintf(stdout, "\nAFTER %d BYTES:\n", j);
      bll_session_debug_print(sess, stdout);
    }
  }

  printf("START EMPTY FRAME TEST\n");

  /* OK, here test the frame entry stuff for an empty frame. */
  {
    char * s;
    char * p;
    int i; int j;
    struct beep_iovec * x;

    s = "SEQ 0 100 7000\r\nMSG 0 10 . 11 0\r\nEND\r\nSEQ 0 100 8000\r\n";
    p = s;
    j = 0;
    while (*p) {
      x = bll_in_buffer(sess);
      if (x == NULL) printf("NULL found\n");
      assert(x != NULL);
      if (1 != x->vec_count) printf("1 not found\n");
      assert(1 == x->vec_count); /* Just because I that's how it's implemented */
      i = strlen(s);
      if (x->iovec[0].iov_len < i) i = x->iovec[0].iov_len;
      if (strlen(p) < i) i = strlen(p);
      memmove(x->iovec[0].iov_base, p, i);
      p += i; j += i;
      bll_in_count(sess, i);
      fprintf(stdout, "\nAFTER %d BYTES:\n", j);
      bll_session_debug_print(sess, stdout);
    }
  }

  printf("ALL DONE!\n");

  return 0;
}


--- NEW FILE: unit_cbeep_shortframe.save ---
Starting...
Notify lower: 3
  text: >>NULL<<
  chan: -1
FIRST CALL
Start of dump, session at 330C0
  in_buffer.vec_count=1
  in_buffer.iov_len[0] = 78
  in_buffer.iov_base[0] = 33264 = ''
  out_buffer.vec_count=3
  out_buffer.iov_len[0] = 17
  out_buffer.iov_base[0] = 33214 = 'RPY 0 0 . 0 186
'
  out_buffer.iov_len[1] = 186
  out_buffer.iov_base[1] = 33A0C = 'content-type: application/xml+beep

<greeting features='features' localize='localize'>
  <profile uri='http://first/profile'/>
  <profile uri='http://second/profile'/>
</greeting>
'
  out_buffer.iov_len[2] = 5
  out_buffer.iov_base[2] = 20F90 = 'END
'
  status=0. status_channel=-1. status_text=>>NULL<<
  memory_limit=-1, memory_used=187
  frame_pre=0, frame_post=0
  IL=L
  server_name='>>NULL<<'
  Offered profiles: NULL
  Greeting error: 0
  Features: >>NULL<<
  Localize: >>NULL<<
  Session info: 0
  SEQ buffer: ''
  HEAD buffer: 'RPY 0 0 . 0 186
'
  READ buffer: ''
  READ SEQ: 0
  READ FRAME:
      NULL FRAME POINTER
  Channels:
    CHANNEL at 332C8:
    next 0
    chan_number=0
    channel_info=0
    priority=100
    in_frame:
      NULL FRAME POINTER
    out_frame:
      NULL FRAME POINTER
    commit_frame:
      FRAME at 339E0 (session=330C0):
      Next on channel: 0
      Next in message: 0
      msg_type='R' more='.'
      channel_number=0
      message_number=0
      answer_number =-1
      size=0, alloc=187
      payload=>>><<<
    apparent out window: 4096
    cur_out_msg type='R', number=0
    cur_in_seq=0
    max_in_seq=4096
    cur_in_buf=0
    max_in_buf=10241
    cur_out_seq=186
    max_out_seq=4096
    SENT messages: 
      Sent 0 msg_more='.' rpy_more=' '
    RCVD messages: NONE
Notify lower: 3
  text: >>NULL<<
  chan: -1

AFTER 208 OCTETS:
Start of dump, session at 330C0
  in_buffer.vec_count=1
  in_buffer.iov_len[0] = 78
  in_buffer.iov_base[0] = 33264 = ''
  out_buffer.vec_count=1
  out_buffer.iov_len[0] = 15
  out_buffer.iov_base[0] = 331C4 = 'SEQ 0 0 10241
'
  status=0. status_channel=-1. status_text=>>NULL<<
  memory_limit=-1, memory_used=0
  frame_pre=0, frame_post=0
  IL=L
  server_name='>>NULL<<'
  Offered profiles: NULL
  Greeting error: 0
  Features: >>NULL<<
  Localize: >>NULL<<
  Session info: 0
  SEQ buffer: 'SEQ 0 0 10241
'
  HEAD buffer: ''
  READ buffer: ''
  READ SEQ: 0
  READ FRAME:
      NULL FRAME POINTER
  Channels:
    CHANNEL at 332C8:
    next 0
    chan_number=0
    channel_info=0
    priority=100
    in_frame:
      NULL FRAME POINTER
    out_frame:
      NULL FRAME POINTER
    commit_frame:
      NULL FRAME POINTER
    apparent out window: 4096
    cur_out_msg type=' ', number=-1
    cur_in_seq=0
    max_in_seq=10241
    cur_in_buf=0
    max_in_buf=10241
    cur_out_seq=186
    max_out_seq=4096
    SENT messages: 
      Sent 0 msg_more='.' rpy_more=' '
    RCVD messages: NONE

AFTER 223 OCTETS:
Start of dump, session at 330C0
  in_buffer.vec_count=1
  in_buffer.iov_len[0] = 78
  in_buffer.iov_base[0] = 33264 = ''
  out_buffer.vec_count=0
  status=0. status_channel=-1. status_text=>>NULL<<
  memory_limit=-1, memory_used=0
  frame_pre=0, frame_post=0
  IL=L
  server_name='>>NULL<<'
  Offered profiles: NULL
  Greeting error: 0
  Features: >>NULL<<
  Localize: >>NULL<<
  Session info: 0
  SEQ buffer: ''
  HEAD buffer: ''
  READ buffer: ''
  READ SEQ: 0
  READ FRAME:
      NULL FRAME POINTER
  Channels:
    CHANNEL at 332C8:
    next 0
    chan_number=0
    channel_info=0
    priority=100
    in_frame:
      NULL FRAME POINTER
    out_frame:
      NULL FRAME POINTER
    commit_frame:
      NULL FRAME POINTER
    apparent out window: 4096
    cur_out_msg type=' ', number=-1
    cur_in_seq=0
    max_in_seq=10241
    cur_in_buf=0
    max_in_buf=10241
    cur_out_seq=186
    max_out_seq=4096
    SENT messages: 
      Sent 0 msg_more='.' rpy_more=' '
    RCVD messages: NONE
GREETING CLEANED OUT - START SHORTFRAME TEST
Notify upper: 0, 1
Notify upper: 0, 2

AFTER 64 BYTES:
Start of dump, session at 330C0
  in_buffer.vec_count=1
  in_buffer.iov_len[0] = 78
  in_buffer.iov_base[0] = 33264 = ''
  out_buffer.vec_count=0
  status=0. status_channel=-1. status_text=>>NULL<<
  memory_limit=-1, memory_used=0
  frame_pre=0, frame_post=0
  IL=L
  server_name='>>NULL<<'
  Offered profiles: NULL
  Greeting error: 0
  Features: >>NULL<<
  Localize: >>NULL<<
  Session info: 0
  SEQ buffer: ''
  HEAD buffer: ''
  READ buffer: ''
  READ SEQ: 0
  READ FRAME:
      NULL FRAME POINTER
  Channels:
    CHANNEL at 332C8:
    next 0
    chan_number=0
    channel_info=0
    priority=100
    in_frame:
      FRAME at 339E0 (session=330C0):
      Next on channel: 0
      Next in message: 0
      msg_type='M' more='.'
      channel_number=0
      message_number=9
      answer_number =-1
      size=11, alloc=-11
      payload=>>><greeting/><<<
      NULL FRAME POINTER
    out_frame:
      NULL FRAME POINTER
    commit_frame:
      NULL FRAME POINTER
    apparent out window: 4096
    cur_out_msg type=' ', number=-1
    cur_in_seq=11
    max_in_seq=10241
    cur_in_buf=11
    max_in_buf=10241
    cur_out_seq=186
    max_out_seq=6100
    SENT messages: 
      Sent 0 msg_more='.' rpy_more=' '
    RCVD messages: 
      Rcvd 9 msg_more='.' rpy_more=' '
START EMPTY FRAME TEST
Notify upper: 0, 1
Notify upper: 0, 2

AFTER 54 BYTES:
Start of dump, session at 330C0
  in_buffer.vec_count=1
  in_buffer.iov_len[0] = 78
  in_buffer.iov_base[0] = 33264 = ''
  out_buffer.vec_count=0
  status=0. status_channel=-1. status_text=>>NULL<<
  memory_limit=-1, memory_used=0
  frame_pre=0, frame_post=0
  IL=L
  server_name='>>NULL<<'
  Offered profiles: NULL
  Greeting error: 0
  Features: >>NULL<<
  Localize: >>NULL<<
  Session info: 0
  SEQ buffer: ''
  HEAD buffer: ''
  READ buffer: ''
  READ SEQ: 11
  READ FRAME:
      NULL FRAME POINTER
  Channels:
    CHANNEL at 332C8:
    next 0
    chan_number=0
    channel_info=0
    priority=100
    in_frame:
      FRAME at 339E0 (session=330C0):
      Next on channel: 33330
      Next in message: 0
      msg_type='M' more='.'
      channel_number=0
      message_number=9
      answer_number =-1
      size=11, alloc=-11
      payload=>>><greeting/><<<
      FRAME at 33330 (session=330C0):
      Next on channel: 0
      Next in message: 0
      msg_type='M' more='.'
      channel_number=0
      message_number=10
      answer_number =-1
      size=0, alloc=0
      payload=>>><<<
      NULL FRAME POINTER
    out_frame:
      NULL FRAME POINTER
    commit_frame:
      NULL FRAME POINTER
    apparent out window: 4096
    cur_out_msg type=' ', number=-1
    cur_in_seq=11
    max_in_seq=10241
    cur_in_buf=11
    max_in_buf=10241
    cur_out_seq=186
    max_out_seq=8100
    SENT messages: 
      Sent 0 msg_more='.' rpy_more=' '
    RCVD messages: 
      Rcvd 9 msg_more='.' rpy_more=' '
      Rcvd 10 msg_more='.' rpy_more=' '
ALL DONE!

--- NEW FILE: unit_channel_0.c ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */
/*
 * unit_channel_0.c
 *
 * Unit testing code for channel_0.c 
 *
 */
const char * __unit_channel_0_c__ = "$Id: unit_channel_0.c,v 1.1 2002/09/07 01:15:23 cphmit Exp $";

#include <beepcore-c/CBEEPint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <strings.h>

#include <beepcore-c/channel_0.h>
#include <beepcore-c/base64.h>

#ifndef ASSERT
#define ASSERT(x) assert(x)
#endif

#include "beep_test_msg.h"

char * b64_rawstr = "Once upon a midnight dreary";
char * b64_codedstr = "AQEBT25jZSB1cG9uIGEgbWlkbmlnaHQgZHJlYXJ5"; 

int chan0_base64_isneeded(struct profile *);

/*
 * Test functions
 */
int test_parse (struct session * session) {
  
  int i = 0;
  int verbose = 0;
  char readbuf[256];
  struct chan0_msg * resultchan0;
  struct profile * resultprofile;

  struct frame myframe1 = {NULL, NULL, NULL,
			   beep_msgs[0].frametype, 0, 0,
                           0, '+', 0, 
			   40, beep_msgs[0].testdata};

  struct frame myframe2 = {NULL, NULL, NULL, 
 			   beep_msgs[0].frametype, 0, 0, 
			   0, '.', 0,
			   strlen(beep_msgs[0].testdata) - 40, &(beep_msgs[0].testdata[40])}; 

  struct frame myframe3 = {NULL, NULL, NULL, 
 			   beep_msgs[0].frametype, 0, 0, 
			   0, '.', 0,
			   strlen(beep_msgs[0].testdata), beep_msgs[0].testdata}; 

  
  myframe1.session = myframe2.session = myframe3.session = session;
  myframe1.next_in_message = myframe1.next_on_channel = &myframe2;
  

  printf("Skip N tests (enter 0 for verbose output): ");
  fgets(readbuf, 255, stdin);
  i = atoi(readbuf);

  verbose = (int)(readbuf[0] == '0');

  for (; beep_msgs[i].testdata; i++) {
    myframe3.size = strlen(beep_msgs[i].testdata);
    myframe3.payload = beep_msgs[i].testdata;
    myframe3.msg_type = beep_msgs[i].frametype;
    printf("%4d) %-40s ", i, beep_msgs[i].testname);
  
    resultchan0=chan0_msg_parse(session, &myframe3);
    if (resultchan0) {
      printf("passed\n");
      /* session->free(resultchan0); */
      if (verbose) {
	printf("\n\nInput-->  %s\n\n", beep_msgs[i].testdata);
	printf("chan0->channel_number:\t%ld\n", resultchan0->channel_number);
	printf("chan0->message_number:\t%ld\n", resultchan0->message_number);
	printf("chan0->op_ic:\t\t%c\n", resultchan0->op_ic);
	printf("chan0->op_sc:\t\t%c\n", resultchan0->op_sc);
	printf("chan0->profileC:\t%ld\n", resultchan0->profileC);
	printf("chan0->features:\t%s\n", resultchan0->features);
	printf("chan0->localize:\t%s\n", resultchan0->localize);
	printf("chan0->server_name:\t%s\n", resultchan0->server_name);

	resultprofile = resultchan0->profile;
	while (resultprofile) {
	  printf("\n");
	  printf("\tprofile->uri:\t\t\t%s\n", resultprofile->uri);
	  printf("\tprofile->piggyback_length:\t%d\n", resultprofile->piggyback_length);
	  if (resultprofile->piggyback)
	    printf("\tstrlen(profile->piggyback):\t%d\n", strlen(resultprofile->piggyback));
	  printf("\tprofile->piggyback:\t\t%s\n", resultprofile->piggyback);
	  if (resultprofile->encoding) {
	    printf("\tprofile->encoding:\t\t%c\n", resultprofile->encoding);
	  } else {
	    printf("\tprofile->encoding:\t\t\\0\n");
	  }
	  resultprofile = resultprofile->next;
	}
	printf("\n");
      }
    } else {
      printf("FAILED'\n");
      return(1);
    }
  }

  return(0);
}


/*
 * test_aggregate
 *
 * run tests on the frame_aggregate function
 */
int test_aggregate(struct session * session) {

  struct frame * resultptr;

  struct frame myframe1 = {NULL, NULL, NULL,
			   beep_msgs[0].frametype, 0, 0,
                           0, '+', 0,
			   40, beep_msgs[0].testdata};

  /*
  struct frame myframe2 = {NULL, NULL, NULL, 
 			   beep_msgs[0].frametype, 0, 0, 
			   0, '.', 0,
			   strlen(beep_msgs[0].testdata) - 40, &(beep_msgs[0].testdata[40])}; 

  struct frame myframe3 = {NULL, NULL, NULL, 
 			   beep_msgs[0].frametype, 0, 0, 
			   0, '.', 0,
			   strlen(beep_msgs[0].testdata), beep_msgs[0].testdata}; 
  */

  printf("aggregate test: ");
  resultptr=blu_frame_aggregate(session, &myframe1); 

  if (resultptr && 
      resultptr->session == myframe1.session &&
      NULL == resultptr->next_in_message &&
      NULL == resultptr->next_on_channel &&
      resultptr->msg_type == myframe1.msg_type &&
      '.' == resultptr->more &&
      resultptr->channel_number == myframe1.channel_number &&
      resultptr->message_number == myframe1.message_number &&
      resultptr->answer_number == myframe1.answer_number &&
      0 == bcmp(resultptr->payload, myframe1.payload, strlen(myframe1.payload))) {
    printf("passed\n");
  } else {
    printf("FAILED'\n");
    return(1);
  }

  printf("negative test: ");
  myframe1.payload = beep_msgs[0].testdata;
  resultptr=blu_frame_aggregate(session, &myframe1);
  if (resultptr && 
      resultptr->session == myframe1.session &&
      NULL == resultptr->next_in_message &&
      NULL == resultptr->next_on_channel &&
      resultptr->msg_type == myframe1.msg_type &&
      '.' == resultptr->more &&
      resultptr->channel_number == myframe1.channel_number &&
      resultptr->message_number == myframe1.message_number &&
      resultptr->answer_number == myframe1.answer_number &&
      0 == bcmp(resultptr->payload, myframe1.payload, strlen(myframe1.payload))) {
    printf("FAILED'\n");
    return(1);
  } else {
    printf("passed\n");
  }

  return(0);
}

/*
 * test_fmt
 *
 * routine for testing the chan0_fmt routines.
 */
int test_fmt(struct session * session) {

  int retcode = 0;
  struct frame * retframe;
  struct chan0_msg msg;
  struct diagnostic err;
  struct profile profile1, profile2;

  msg.channel_number = 0;
  msg.message_number = 10;
  msg.op_ic          = 'c';
  msg.op_sc          = 'c';
  msg.profile        = NULL;
  msg.error          = NULL;
  msg.features       = NULL;
  msg.localize       = NULL;
  msg.server_name     = NULL;

  profile1.next      = NULL;
  profile1.uri       = "http://iana.org/beep/SASL/OTP";
  profile1.piggyback = NULL;
  profile1.piggyback_length = 0;

  profile2.next      = &profile1;
  profile2.uri       = "http://iana.org/beep/NULL/ECHO";
  profile2.piggyback = NULL;
  profile2.piggyback_length = 0;


  err.code           = 451;
  err.message        = "Egregious error message.";
  err.lang           = "eng/us";

  /* greet confirm -- empty */
  msg.op_ic          = 'c';
  msg.op_sc          = 'g';
  msg.channel_number = 11;
  msg.profile        = NULL;
  printf("chan0_msg_fmt: greeting confirm (empty): ");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("PASSED: %s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }
  msg.profile        = NULL;
  msg.channel_number = 0;

  /* greet confirm */
  msg.op_ic          = 'c';
  msg.op_sc          = 'g';
  msg.channel_number = 11;
  msg.profile        = &profile1;
  printf("chan0_msg_fmt: greeting confirm: ");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("PASSED: %s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }
  msg.profile        = NULL;
  msg.channel_number = 0;

  /* start request*/
  msg.op_ic          = 'i';
  msg.op_sc          = 's';
  msg.channel_number = 11;
  msg.profile        = &profile1;
  printf("chan0_msg_fmt: start: ");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("PASSED: %s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }
  msg.profile        = NULL;
  msg.channel_number = 0;

  /* start request with entities needing normalization*/
  msg.op_ic          = 'i';
  msg.op_sc          = 's';
  msg.channel_number = 11;
  msg.profile        = &profile1;

  profile1.uri       = "http://iana.org/beep/SASL/OTP?><@##%#%'";
  msg.server_name     = "<jan&dean>";

  profile1.piggyback = b64_rawstr;
  profile1.piggyback_length = strlen(b64_rawstr);

  printf("chan0_msg_fmt: start : entities to do:");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("PASSED: %s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }

  profile1.uri       = "http://iana.org/beep/SASL/OTP";

  profile1.piggyback = NULL;
  profile1.piggyback_length = 0;
  msg.profile        = NULL;
  msg.channel_number = 0;

  /* start request with piggyback needing base64*/
  msg.op_ic          = 'i';
  msg.op_sc          = 's';
  msg.channel_number = 11;
  msg.profile        = &profile1;

  profile1.piggyback = b64_rawstr;
  profile1.piggyback_length = strlen(b64_rawstr);

  printf("chan0_msg_fmt: start b64 piggyback: ");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("PASSED: %s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }

  profile1.piggyback = NULL;
  profile1.piggyback_length = 0;
  msg.profile        = NULL;
  msg.channel_number = 0;

  /* start request -- 2 profiles*/
  msg.op_ic          = 'i';
  msg.op_sc          = 's';
  msg.channel_number = 11;
  msg.profile        = &profile2;
  printf("chan0_msg_fmt: start (2 profiles): ");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("PASSED: %s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }
  msg.profile        = NULL;
  msg.channel_number = 0;

  /* start confirm */
  msg.op_ic          = 'c';
  msg.op_sc          = 's';
  msg.channel_number = 11;
  msg.profile        = &profile1;
  printf("chan0_msg_fmt: start confirm: ");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("PASSED: %s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }
  msg.profile        = NULL;
  msg.channel_number = 0;

 /* start confirm negative test */
  msg.op_ic          = 'c';
  msg.op_sc          = 's';
  msg.channel_number = 11;
  msg.profile        = &profile2;
  printf("chan0_msg_fmt: start confirm negative test (too many profiles): ");
  if ((!(retframe = chan0_msg_fmt(session, &msg)))) {
    printf("PASSED: \n");
  } else {
    blu_frame_destroy(retframe);
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }
  msg.profile        = NULL;
  msg.channel_number = 0;

  /* close request*/
  msg.op_ic          = 'i';
  msg.op_sc          = 'c';
  msg.error          = &err;
  printf("chan0_msg_fmt: close: ");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("%s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }
  msg.error          = NULL;

  /* ok message for close */
  msg.op_ic          = 'c';
  msg.op_sc          = 'c';
  printf("chan0_msg_fmt: close ok: ");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("%s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }

  /* error frame return for start or close */
  msg.op_ic          = 'c';
  msg.op_sc          = 'e';
  msg.error          = &err;
  printf("chan0_msg_fmt: error: ");
  if ((retframe = chan0_msg_fmt(session, &msg))) {
    printf("%s\n", retframe->payload);
    blu_frame_destroy(retframe);
  } else {
    printf("FAIL\n");
    retcode = 1;
    goto cleanup;
  }
  msg.error          = NULL;

 cleanup:
  return(retcode);
}


/*
 * test_base64_isneeded
 */
int test_base64_isneeded() {
  struct profile myprofile2 = {NULL, "", 
			       "Now is the time for all good men.", 32, ' '};

  struct profile myprofile1 = {&myprofile2, "", 
			       "Now is the time for all good men.", 32, ' '};

  myprofile1.piggyback_length = strlen(myprofile1.piggyback);
  myprofile2.piggyback_length = strlen(myprofile2.piggyback);

  printf("chan0_base64_isneeded: single OK: ");
  if (!chan0_base64_isneeded(&myprofile2)) {
    printf("PASSED: \n");
  } else {
    printf("FAIL\n");
    return(1);
  }

  printf("chan0_base64_isneeded: multi OK: ");
  if (!chan0_base64_isneeded(&myprofile1)) {
    printf("PASSED: \n");
  } else {
    printf("FAIL\n");
    return(1);
  }

  myprofile2.piggyback_length = strlen(myprofile2.piggyback) + 1;
  
  printf("chan0_base64_isneeded: single reqd: ");
  if (chan0_base64_isneeded(&myprofile2)) {
    printf("PASSED: \n");
  } else {
    printf("FAIL\n");
    return(1);
  }

  printf("chan0_base64_isneeded: multi reqd: ");
  if (chan0_base64_isneeded(&myprofile1)) {
    printf("PASSED: \n");
  } else {
    printf("FAIL\n");
    return(1);
  }
  

  return(0);
}
/*
 *
 */
void my_notify_lower(struct session * session, int code) {
  printf("notified lower: code=%d\n", code);
  return;
}

void my_notify_upper(struct session * session, long code1, int code2) {
  printf("notified upper: code1=%d code2=%d\n", (int)code1, (int)code2);
  return;
}

/*
 * main
 *
 * every self respecting test program has one.
 */
/*  typedef int (*intfp)(struct session *); */
typedef int (*intfp)();

int main () {
  int retcode;
  struct session mysession;
  intfp * fcurrent;

/*    intfp flist[] = { test_parse, NULL }; */
  intfp flist[] = { test_fmt, test_parse, test_base64_isneeded, NULL };

  memset(&mysession, 0, sizeof(struct session));

  mysession.malloc = malloc;
  mysession.free   = free;
  mysession.notify_lower   = my_notify_lower;
  mysession.notify_upper   = my_notify_upper;

  for (fcurrent = flist; NULL != *fcurrent; fcurrent++) {
    if ((retcode = (*fcurrent)(&mysession))) 
      exit(retcode);
  }

  exit(0);
}



--- NEW FILE: unit_frame_aggregate.c ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */
#include <beepcore-c/CBEEPint.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <strings.h>

#include <beepcore-c/channel_0.h>
#include <beepcore-c/base64.h>

#ifndef ASSERT
#define ASSERT(x) assert(x)
#endif


char * rawstr = "Once upon a midnight dreary as I pondered weak and weary I heard a rapping tap tap tapping at my parlor door.";
char * codedstr = "T25jZSB1cG9uIGEgbWlkbmlnaHQgZHJlYXJ5IGFzIEkgcG9uZGVyZWQgd2VhayBhbmQgd2Vhcnkg\r\nSSBoZWFyZCBhIHJhcHBpbmcgdGFwIHRhcCB0YXBwaW5nIGF0IG15IHBhcmxvciBkb29yLg=="; 

int main () {

  struct frame * resultptr;

  struct frame myframe1 = {NULL, NULL, NULL,
			   'M', 0, 0,
                           0, '+', 0, 
			   40, rawstr};

  struct frame myframe2 = {NULL, NULL, NULL,
			   'M', 0, 0,
                           0, '.', 0,
			   strlen(rawstr) - 40, &(rawstr[40])};

  struct frame myframe3 = {NULL, NULL, NULL,
			   'M', 0, 0,
                           0, '.', 0,
			   strlen(rawstr), rawstr};

  struct session mysession;

  memset(&mysession, 0, sizeof(struct session));
  
  myframe1.session = myframe2.session = myframe3.session = &mysession;
  myframe1.next_in_message = myframe1.next_on_channel = &myframe2;
  

  mysession.malloc = malloc;
  mysession.free   = free;

  printf("identity test (single frame copy): ");
  resultptr=blu_frame_aggregate(&mysession, &myframe3);
  if (resultptr) {
    printf("got a frame: ");
    if (0 == bcmp(resultptr, &myframe3, sizeof(myframe3) - sizeof(char *)))
      printf("failed compare 1\n");
    else if (0 == bcmp(resultptr->payload, myframe3.payload, strlen(myframe3.payload)))
      printf("failed compare 2\n");
    else 
      printf("passed compare\n");      
  } else {
    printf("FAILED\n");
  }

  if (resultptr) {
    free(resultptr);
    resultptr = NULL;
  }

  printf("aggregate test: ");
  resultptr=blu_frame_aggregate(&mysession, &myframe1);
  if (resultptr && 
      resultptr->session == myframe1.session &&
      NULL == resultptr->next_in_message &&
      NULL == resultptr->next_on_channel &&
      resultptr->msg_type == myframe1.msg_type &&
      '.' == resultptr->more &&
      resultptr->channel_number == myframe1.channel_number &&
      resultptr->message_number == myframe1.message_number &&
      resultptr->answer_number == myframe1.answer_number &&
      0 == bcmp(resultptr->payload, myframe1.payload, strlen(myframe1.payload))) {
    printf("passed\n");
  } else {
    printf("FAILED'\n");
  }

  if (resultptr) {
    free(resultptr);
    resultptr = NULL;
  }

  printf("negative test: ");
  myframe1.payload = codedstr;
  resultptr=blu_frame_aggregate(&mysession, &myframe1);
  if (resultptr && 
      resultptr->session == myframe1.session &&
      NULL == resultptr->next_in_message &&
      NULL == resultptr->next_on_channel &&
      resultptr->msg_type == myframe1.msg_type &&
      '.' == resultptr->more &&
      resultptr->channel_number == myframe1.channel_number &&
      resultptr->message_number == myframe1.message_number &&
      resultptr->answer_number == myframe1.answer_number &&
      0 == strcmp(resultptr->payload, myframe1.payload)) {
    printf("FAILED'\n");
  } else {
    printf("passed\n");
  }

  if (resultptr) {
    free(resultptr);
    resultptr = NULL;
  }

  exit(0);
}


--- NEW FILE: unit_notify_stubs.c ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */
/*
 * $Id: unit_notify_stubs.c,v 1.1 2002/09/07 01:15:23 cphmit Exp $
 *
 * Stubs for the unit tests.
 *
 */
#include <beepcore-c/CBEEPint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void notify_lower(struct session * s, int i) {
  char * cp;
  printf("Notify lower: %d\n", i);
  cp = bll_status_text(s);
  if (cp==NULL) cp = ">>NULL<<";
  printf("  text: %s\n", cp);
  printf("  chan: %ld\n", bll_status_channel(s));
}

void notify_upper(struct session * s, long c, int i) {
  printf("Notify upper: %ld, %d\n", c, i);
}

--- NEW FILE: unit_notify_stubs.h ---
/*
 * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
 *
 * The contents of this file are subject to the Blocks Public License (the
 * "License"); You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at http://www.beepcore.org/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 */
/*
 * $Id: unit_notify_stubs.h,v 1.1 2002/09/07 01:15:23 cphmit Exp $
 *
 * Stubs for the unit tests.
 *
 */
#include <beepcore-c/CBEEPint.h>

void notify_lower(struct session * s, int i);
void notify_upper(struct session * s, long c, int i);




-------------------------------------------------------
This sf.net email is sponsored by: OSDN - Tired of that same old
cell phone?  Get a new here for FREE!
https://www.inphonic.com/r.asp?r=sourceforge1&refcode1=vs3390