示例#1
0
static void decodeNull( bsd_ctx_t *ctx, bsd_data_t *x) {
  struct bsd_stackframe_t * f = topframe( ctx);
  if( BS_FZLIST == f->kind || (BS_FZMAP == f->kind && f->content.map.even)) {
    x->kind = BSD_CLOSE;
    x->content.cont_type = bsd_typeFromFrameKind( f->kind);
    ctx->stacksize--;
  } else {
    x->kind = BSD_NULL;
  }
}
/* stack-debug.c 732a */
void stack_trace_current_value(Value v, Env rho, Stack s) {
    if (trace_countp && *trace_countp != 0) {
        (*trace_countp)--;
        vtick++;
        fprint(stderr, "val  %d = %v\n", vtick, v);
        fprint(stderr, "env  %R\n", rho);
        if (topframe(s)) 
            fprint(stderr, "stack\n%S\n", s);
        else 
            fprint(stderr, " (final answer from stack-based eval)\n");
    }
}
示例#3
0
/* Adds a frame to the decoding stack. */
static bsd_status_t openContainer(
    bsd_ctx_t *ctx,
    bs_stackframekind_t kind,
    bs_ctxid_t ctxid,
    int missing,
    union bsd_stackframecontent_t **c) {

  struct bsd_stackframe_t *f;
  if( (BSD_STACK_SIZE-1) == ctx->stacksize) return BSD_ETOODEEP;
  ctx->stacksize++;
  f = topframe( ctx);
  f->kind = kind;
  f->ctxid = ctxid;
  f->missing = missing;
  // both key and value count for maps
  if( BS_FMAP == kind || BS_FZMAP == kind) {
    f->missing *= 2;
    f->content.map.even = 1; /* will be inverted */
  }
  if( c)
    *c = &f->content;
  return BSD_EOK;
}
示例#4
0
void bsd_dump( bsd_ctx_t *ctx, FILE *output, const uint8_t *buffer, int length) {
  const uint8_t *begin = buffer;
  const uint8_t *end = buffer + length;

  fputs("Byte\tOpcode\tContext\tType\tValue\tAdditional bytes\tAdditional info\n", output);
  while( buffer < end || ctx->stacksize > 0) {
    bsd_data_t x;
    struct bsd_stackframe_t *f = topframe( ctx);
    // we need context in which the value is decoded, so we catch now rather than after the read
    bs_ctxid_t ctxid = getctxid( f);
    int r = bsd_read( ctx, &x, buffer, length);
    if( 0 == r && BSD_ERROR == x.kind) {
      fprintf( output, "Error %d at byte %td.\n", x.content.error, buffer - begin);
      break;
    } else if( r < 0) {
      fprintf( output, "Error: %d bytes missing.\n", r);
      break;
    } else {
      int opcode_len = 0;
      fprintf( output, "%td\t", buffer - begin);
      if( r == 0) fputs( "N/A\tN/A\t", output);
      else {
        switch( ctxid) {
        case BS_CTXID_CHUNKED: opcode_len = 2; break;
        case BS_CTXID_FLOAT:
        case BS_CTXID_INT32:   opcode_len = 4; break;
        case BS_CTXID_DOUBLE:  opcode_len = 8; break;
        default:               opcode_len = 1; break;
        }
        hexdump( output, buffer, opcode_len); fputc('\t', output);

        switch( ctxid) {
#define CASE(x) case BS_CTXID_##x: fputs( #x"\t", output); break
        CASE(GLOBAL);
        CASE(UNSIGNED_OR_STRING);
        CASE(NUMBER);
        CASE(INT32);
        CASE(FLOAT);
        CASE(DOUBLE);
        CASE(LIST_OR_MAP);
        default: printf("%d\t", ctxid); break;
#undef CASE
        }
      }

      switch( x.kind) {
#define CASE(x) case BSD_##x: fputs( #x"\t", output)
      CASE(CLOSE); fputs( "N/A\t", output); break;
      CASE(NULL); fputs( "N/A\t", output); break;
      CASE(INT); fprintf( output, "%" PRId64 "\t", x.content.i); break;
      CASE(BOOL); fputs( x.content.boolean ? "true\t" : "false\t", output); break;
      CASE(DOUBLE); fprintf( output, "%f\t", x.content.d); break;
      CASE(STRING); fprintf( output, "length: %zu\t", x.content.string.length); break;
      CASE(CHUNKED_STRING); fputs( "N/A\t", output); break;
      CASE(CHUNK); fprintf( output, "length: %zu\t", x.content.chunk.length); break;
      CASE(LIST); fprintf( output, "length: %zu, ctx: %d\t", x.content.length, topframe( ctx)->ctxid); break;
      CASE(ZLIST); fprintf( output, "ctx: %d\t", topframe( ctx)->ctxid); break;
      CASE(MAP); fprintf( output, "length: %zu, ctx: %d\t", x.content.length, topframe( ctx)->ctxid); break;
      CASE(ZMAP); fprintf( output, "ctx: %d\t", topframe( ctx)->ctxid); break;
      CASE(OBJECT);
        if( NULL == x.content.classdef->classname) fprintf( output, "class: %d\t", x.content.classdef->classid);
        else fprintf( output, "class: %s\t", x.content.classdef->classname);
        break;
      CASE(CLASSDEF);
        if( NULL == x.content.classdef->classname) fprintf( output, "class: %d\t", x.content.classdef->classid);
        else fprintf( output, "class: %s\t", x.content.classdef->classname);
        break;
      default: fprintf(output, "%d\tN/A\t", x.kind);
#undef CASE
      }

      int additional = r - opcode_len;
      if( 0 < additional && additional <= 10) hexdump( output, buffer+opcode_len, additional);
      else if( additional > 10) {
        hexdump( output, buffer+opcode_len, 3);
        fputs( "...", output);
        hexdump( output, buffer+r-3, 3);
      }
      else fputs( "N/A", output);
      fputs( "\t", output);
      // additional infos
      if( BSD_KOBJFIELD == x._internalContext && x.fieldname != NULL) {
        fprintf( output, "field: %s\t", x.fieldname);
      } else {
        fputs( "N/A\t", output);
      }
      fputs( "\n", output);
    }

    buffer += r;
    length -= r;
  }
}
示例#5
0
int bsd_read( bsd_ctx_t *ctx, bsd_data_t *x, const uint8_t *buffer, int length) {
  int nread = 0;
  struct bsd_stackframe_t *f = topframe( ctx);
  x->kind = BSD_NULL; // if x is already of type error, it will confuse error checking

  // check stack (fixed length terminated containers)
  if( f->missing == 0) {
    x->kind = BSD_CLOSE;
    x->content.cont_type = bsd_typeFromFrameKind( f->kind);
    ctx->stacksize--;
    /* the other properties depends on the frame below the closed one */
    f = topframe( ctx);
    x->_internalContext = bsd_getFrameDataKind( f);
    /* set field name for objects */
    if( BSD_KOBJFIELD == x->_internalContext) {
      const bs_class_t *classdef = f->content.object.classdef;
      x->fieldname = classdef->fields[classdef->nfields - (f->missing + 1)].name;
    }
    return 0;
  }

  switch( getctxid( f)) {
  case BS_CTXID_GLOBAL:             nread = bsd_global( ctx, x, buffer, length);  break;
  case BS_CTXID_UNSIGNED_OR_STRING: nread = bsd_uis( ctx, x, buffer, length);     break;
  case BS_CTXID_NUMBER:             nread = bsd_number( ctx, x, buffer, length);  break;
  case BS_CTXID_INT32:              nread = bsd_int32( ctx, x, buffer, length);   break;
  case BS_CTXID_FLOAT:              nread = bsd_float( ctx, x, buffer, length);   break;
  case BS_CTXID_DOUBLE:             nread = bsd_double( ctx, x, buffer, length);  break;
  case BS_CTXID_LIST_OR_MAP:        nread = bsd_listmap( ctx, x, buffer, length); break;
  case BS_CTXID_CHUNKED:            nread = bsd_chunked( ctx, x, buffer, length); break;
//  case BS_CTXID_OBJECT:
//  case BS_CTXID_CLASSDEF:
//  case BS_CTXID_NAMEDCLASSDEF:
//  case BS_CTXID_INTERNALCLASSDEF:
  default:
    return bsd_error( x, BSD_EBADCONTEXT);
  }

  // stop any further action in case of error
  if( nread < 0 || BSD_ERROR == x->kind) return nread;

  /* class definition does not count as value */
  if( BSD_CLASSDEF != x->kind) {
    // decrement counter (for fixed containers)
    if( f->missing > 0) {
      f->missing--;
    }

    // map key/value decoding
    if( BS_FMAP == f->kind || BS_FZMAP == f->kind) {
      f->content.map.even ^= 1;
    }
  }

  // top frame may have changed
  if( topframe( ctx) > f) {
    x->_internalContext = BSD_KNEWCONTAINER;
  } else {
    f = topframe( ctx);
    x->_internalContext = bsd_getFrameDataKind( f);
    /* set field name for objects */
    if( BSD_KOBJFIELD == x->_internalContext) {
      const bs_class_t *classdef = f->content.object.classdef;
      x->fieldname = classdef->fields[classdef->nfields - (f->missing + 1)].name;
    }
  }

  ctx->read += nread;
  return nread;
}