Browse Source

varint: new file.

Move varint handling from tx.c and generalize it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
6b956ea22a
  1. 6
      Makefile
  2. 1
      bitcoin/test/run-tx-encode.c
  3. 60
      bitcoin/tx.c
  4. 4
      bitcoin/tx.h
  5. 62
      bitcoin/varint.c
  6. 17
      bitcoin/varint.h

6
Makefile

@ -28,7 +28,8 @@ BITCOIN_SRC := \
bitcoin/script.c \
bitcoin/shadouble.c \
bitcoin/signature.c \
bitcoin/tx.c
bitcoin/tx.c \
bitcoin/varint.c
BITCOIN_OBJS := $(BITCOIN_SRC:.c=.o)
CORE_SRC := \
@ -135,7 +136,8 @@ BITCOIN_HEADERS := bitcoin/address.h \
bitcoin/script.h \
bitcoin/shadouble.h \
bitcoin/signature.h \
bitcoin/tx.h
bitcoin/tx.h \
bitcoin/varint.h
CORE_HEADERS := close_tx.h \
commit_tx.h \

1
bitcoin/test/run-tx-encode.c

@ -1,5 +1,6 @@
#include "bitcoin/tx.c"
#include "bitcoin/shadouble.c"
#include "bitcoin/varint.c"
#include <assert.h>
#include <ccan/str/hex/hex.h>

60
bitcoin/tx.c

@ -13,32 +13,9 @@
static void add_varint(varint_t v,
void (*add)(const void *, size_t, void *), void *addp)
{
u8 buf[9], *p = buf;
if (v < 0xfd) {
*(p++) = v;
} else if (v <= 0xffff) {
(*p++) = 0xfd;
(*p++) = v;
(*p++) = v >> 8;
} else if (v <= 0xffffffff) {
(*p++) = 0xfe;
(*p++) = v;
(*p++) = v >> 8;
(*p++) = v >> 16;
(*p++) = v >> 24;
} else {
(*p++) = 0xff;
(*p++) = v;
(*p++) = v >> 8;
(*p++) = v >> 16;
(*p++) = v >> 24;
(*p++) = v >> 32;
(*p++) = v >> 40;
(*p++) = v >> 48;
(*p++) = v >> 56;
}
add(buf, p - buf, addp);
u8 buf[VARINT_MAX_LEN];
add(buf, varint_put(buf, v), addp);
}
static void add_le32(u32 v,
@ -376,34 +353,15 @@ static const u8 *pull(const u8 **cursor, size_t *max, void *copy, size_t n)
static u64 pull_varint(const u8 **cursor, size_t *max)
{
u64 ret;
const u8 *p;
size_t len;
p = pull(cursor, max, NULL, 1);
if (!p)
len = varint_get(*cursor, *max, &ret);
if (len == 0) {
*cursor = NULL;
*max = 0;
return 0;
if (*p < 0xfd) {
ret = *p;
} else if (*p == 0xfd) {
p = pull(cursor, max, NULL, 2);
if (!p)
return 0;
ret = ((u64)p[1] << 8) + p[0];
} else if (*p == 0xfe) {
p = pull(cursor, max, NULL, 4);
if (!p)
return 0;
ret = ((u64)p[3] << 24) + ((u64)p[2] << 16)
+ ((u64)p[1] << 8) + p[0];
} else {
p = pull(cursor, max, NULL, 8);
if (!p)
return 0;
ret = ((u64)p[7] << 56) + ((u64)p[6] << 48)
+ ((u64)p[5] << 40) + ((u64)p[4] << 32)
+ ((u64)p[3] << 24) + ((u64)p[2] << 16)
+ ((u64)p[1] << 8) + p[0];
}
pull(cursor, max, NULL, len);
return ret;
}

4
bitcoin/tx.h

@ -3,12 +3,10 @@
#include "config.h"
#include "shadouble.h"
#include "signature.h"
#include "varint.h"
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
/* We unpack varints for our in-memory representation */
#define varint_t u64
struct bitcoin_tx {
u32 version;
varint_t input_count;

62
bitcoin/varint.c

@ -0,0 +1,62 @@
#include "varint.h"
size_t varint_put(u8 buf[VARINT_MAX_LEN], varint_t v)
{
u8 *p = buf;
if (v < 0xfd) {
*(p++) = v;
} else if (v <= 0xffff) {
(*p++) = 0xfd;
(*p++) = v;
(*p++) = v >> 8;
} else if (v <= 0xffffffff) {
(*p++) = 0xfe;
(*p++) = v;
(*p++) = v >> 8;
(*p++) = v >> 16;
(*p++) = v >> 24;
} else {
(*p++) = 0xff;
(*p++) = v;
(*p++) = v >> 8;
(*p++) = v >> 16;
(*p++) = v >> 24;
(*p++) = v >> 32;
(*p++) = v >> 40;
(*p++) = v >> 48;
(*p++) = v >> 56;
}
return p - buf;
}
size_t varint_get(const u8 *p, size_t max, varint_t *val)
{
if (max < 1)
return 0;
switch (*p) {
case 0xfd:
if (max < 3)
return 0;
*val = ((u64)p[1] << 8) + p[0];
return 3;
case 0xfe:
if (max < 5)
return 0;
*val = ((u64)p[3] << 24) + ((u64)p[2] << 16)
+ ((u64)p[1] << 8) + p[0];
return 5;
case 0xff:
if (max < 9)
return 0;
*val = ((u64)p[7] << 56) + ((u64)p[6] << 48)
+ ((u64)p[5] << 40) + ((u64)p[4] << 32)
+ ((u64)p[3] << 24) + ((u64)p[2] << 16)
+ ((u64)p[1] << 8) + p[0];
return 9;
default:
*val = *p;
return 1;
}
}

17
bitcoin/varint.h

@ -0,0 +1,17 @@
#ifndef LIGHTNING_BITCOIN_VARINT_H
#define LIGHTNING_BITCOIN_VARINT_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <stdlib.h>
/* We unpack varints for our in-memory representation */
#define varint_t u64
#define VARINT_MAX_LEN 9
/* Returns bytes used (up to 9) */
size_t varint_put(u8 buf[VARINT_MAX_LEN], varint_t v);
/* Returns bytes used: 0 if max_len too small. */
size_t varint_get(const u8 *p, size_t max_len, varint_t *val);
#endif /* LIGHTNING_BITCOIN_VARINT_H */
Loading…
Cancel
Save