Пример #1
0
static int get_bsd_value( sdb_read_ctx_t *ctx, double *value) {
    bsd_data_t data;
    if( bsd_read(& ctx->bsd_ctx, & data, ctx->bytes, ctx->nbytes) < ctx->nbytes) return 0; // read error, bad type

    if( data.type == BSD_INT) {
        *value = data.content.i;
    } else if( data.type == BSD_DOUBLE) {
        *value = data.content.d;
    } else {
        return 0; // bad type.
    }
    return 1;
}
Пример #2
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;
  }
}