Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sven Gestegård Robertz
LabComm
Commits
70b290de
Commit
70b290de
authored
May 16, 2013
by
Anders Blomdell
Browse files
Changed writer interface from a funtion to a [const] vtable struct.
parent
b5a801be
Changes
10
Hide whitespace changes
Inline
Side-by-side
lib/c/Makefile
View file @
70b290de
...
...
@@ -6,13 +6,14 @@ CFLAGS = -g -Wall -Werror -O3 -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH
LDFLAGS
=
-L
.
LDLIBS_TEST
=
-Tlabcomm
.linkscript
-lcunit
-llabcomm
OBJS
=
labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o labcomm_mem_reader.o labcomm_mem_writer.o
OBJS
=
labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o
#FIXME: labcomm_mem_reader.o labcomm_mem_writer.o
LABCOMM_JAR
=
../../compiler/labComm.jar
LABCOMM
=
java
-jar
$(LABCOMM_JAR)
TESTS
=
test_labcomm_basic_type_encoding test_labcomm_generated_encoding
#
test_labcomm
#FIXME: test_labcomm_errors
#
#FIXME:
test_labcomm
test_labcomm_errors
TEST_DIR
=
test
TESTDATA_DIR
=
$(TEST_DIR)
/testdata
TEST_GEN_DIR
=
$(TESTDATA_DIR)
/gen
...
...
lib/c/labcomm.c
View file @
70b290de
...
...
@@ -34,7 +34,7 @@
#include
"labcomm_ioctl.h"
#include
"labcomm_dynamic_buffer_writer.h"
#define LABCOMM_VERSION "LabComm2013"
#define LABCOMM_VERSION "
\x0b
LabComm2013"
typedef
struct
labcomm_sample_entry
{
struct
labcomm_sample_entry
*
next
;
...
...
@@ -227,20 +227,22 @@ static int get_encoder_index(
void
labcomm_encode_signature
(
struct
labcomm_encoder
*
e
,
labcomm_signature_t
*
signature
)
{
int
i
;
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_start_signature
);
int
i
,
index
;
index
=
get_encoder_index
(
e
,
signature
);
e
->
writer
.
action
.
start
(
&
e
->
writer
,
e
,
index
,
signature
,
NULL
);
labcomm_encode_packed32
(
e
,
signature
->
type
);
labcomm_encode_packed32
(
e
,
get_encoder_index
(
e
,
signature
)
);
labcomm_encode_packed32
(
e
,
index
);
labcomm_encode_string
(
e
,
signature
->
name
);
for
(
i
=
0
;
i
<
signature
->
size
;
i
++
)
{
if
(
e
->
writer
.
pos
>=
e
->
writer
.
count
)
{
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_continue
);
e
->
writer
.
action
.
flush
(
&
e
->
writer
);
}
e
->
writer
.
data
[
e
->
writer
.
pos
]
=
signature
->
signature
[
i
];
e
->
writer
.
pos
++
;
}
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_end_signature
);
e
->
writer
.
action
.
end
(
&
e
->
writer
);
}
#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
...
...
@@ -363,25 +365,23 @@ static int do_encode(
void
*
value
)
{
int
result
;
labcomm_writer_start_t
lws
;
lws
.
encoder
=
e
;
lws
.
index
=
get_encoder_index
(
e
,
signature
);
lws
.
signature
=
signature
;
lws
.
value
=
value
;
result
=
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_start
,
&
lws
);
if
(
result
==
-
EALREADY
)
{
result
=
0
;
goto
out
;
}
int
index
;
index
=
get_encoder_index
(
e
,
signature
);
result
=
e
->
writer
.
action
.
start
(
&
e
->
writer
,
e
,
index
,
signature
,
value
);
if
(
result
==
-
EALREADY
)
{
result
=
0
;
goto
no_end
;
}
if
(
result
!=
0
)
{
goto
out
;
}
result
=
labcomm_encode_packed32
(
e
,
lws
.
index
);
result
=
labcomm_encode_packed32
(
e
,
index
);
if
(
result
!=
0
)
{
goto
out
;
}
result
=
encode
(
e
,
value
);
out:
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_end
,
&
lws
);
e
->
writer
.
action
.
end
(
&
e
->
writer
);
no_end:
return
result
;
}
labcomm_encoder_t
*
labcomm_encoder_new
(
int
(
*
writer
)(
labcomm_writer_t
*
,
labcomm_writer_action
_t
,
...)
,
const
struct
labcomm_writer_action
action
,
void
*
writer_context
)
{
labcomm_encoder_t
*
result
=
malloc
(
sizeof
(
labcomm_encoder_t
));
...
...
@@ -402,13 +402,12 @@ labcomm_encoder_t *labcomm_encoder_new(
result
->
writer
.
count
=
0
;
result
->
writer
.
pos
=
0
;
result
->
writer
.
error
=
0
;
result
->
writer
.
write
=
writer
;
result
->
writer
.
ioctl
=
NULL
;
result
->
writer
.
action
=
action
;
result
->
writer
.
on_error
=
on_error_fprintf
;
result
->
do_register
=
do_encoder_register
;
result
->
do_encode
=
do_encode
;
result
->
on_error
=
on_error_fprintf
;
result
->
writer
.
write
(
&
result
->
writer
,
labcomm_writer_alloc
);
result
->
writer
.
action
.
alloc
(
&
result
->
writer
,
LABCOMM_VERSION
);
}
return
result
;
}
...
...
@@ -442,7 +441,7 @@ int labcomm_internal_encode(
void
labcomm_encoder_free
(
labcomm_encoder_t
*
e
)
{
e
->
writer
.
writ
e
(
&
e
->
writer
,
labcomm_writer_free
);
e
->
writer
.
action
.
fre
e
(
&
e
->
writer
);
labcomm_encoder_context_t
*
context
=
(
labcomm_encoder_context_t
*
)
e
->
context
;
#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
...
...
@@ -466,11 +465,11 @@ int labcomm_encoder_ioctl(struct labcomm_encoder *encoder,
{
int
result
=
-
ENOTSUP
;
if
(
encoder
->
writer
.
ioctl
!=
NULL
)
{
if
(
encoder
->
writer
.
action
.
ioctl
!=
NULL
)
{
va_list
va
;
va_start
(
va
,
action
);
result
=
encoder
->
writer
.
ioctl
(
&
encoder
->
writer
,
action
,
NULL
,
va
);
result
=
encoder
->
writer
.
action
.
ioctl
(
&
encoder
->
writer
,
action
,
NULL
,
va
);
va_end
(
va
);
}
return
result
;
...
...
@@ -483,8 +482,9 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
{
int
result
=
-
ENOTSUP
;
if
(
encoder
->
writer
.
ioctl
!=
NULL
)
{
result
=
encoder
->
writer
.
ioctl
(
&
encoder
->
writer
,
action
,
signature
,
va
);
if
(
encoder
->
writer
.
action
.
ioctl
!=
NULL
)
{
result
=
encoder
->
writer
.
action
.
ioctl
(
&
encoder
->
writer
,
action
,
signature
,
va
);
}
return
result
;
}
...
...
@@ -584,7 +584,7 @@ static int do_decode_one(labcomm_decoder_t *d)
/* TODO: should the labcomm_dynamic_buffer_writer be
a permanent part of labcomm_decoder? */
labcomm_encoder_t
*
e
=
labcomm_encoder_new
(
labcomm_dynamic_buffer_writer
,
0
);
labcomm_dynamic_buffer_writer
,
NULL
);
labcomm_signature_t
signature
;
labcomm_sample_entry_t
*
entry
=
NULL
;
int
index
,
err
;
...
...
@@ -592,11 +592,11 @@ static int do_decode_one(labcomm_decoder_t *d)
index
=
labcomm_decode_packed32
(
d
);
//int
signature
.
name
=
labcomm_decode_string
(
d
);
signature
.
type
=
result
;
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_start
);
e
->
writer
.
action
.
start
(
&
e
->
writer
,
NULL
,
0
,
NULL
,
NULL
);
/* printf("do_decode_one: result = %x, index = %x, name=%s\n",
result, index, signature.name); */
collect_flat_signature
(
d
,
e
);
e
->
writer
.
write
(
&
e
->
writer
,
labcomm_writer_end
);
e
->
writer
.
action
.
end
(
&
e
->
writer
);
err
=
labcomm_encoder_ioctl
(
e
,
LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN
,
&
signature
.
size
);
if
(
err
<
0
)
{
...
...
lib/c/labcomm.h
View file @
70b290de
...
...
@@ -81,24 +81,14 @@ void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d,
* Decoder
*/
typedef
enum
{
labcomm_reader_alloc
,
/* (..., char *labcomm_version)
Allocate all neccessary data */
labcomm_reader_free
,
labcomm_reader_start
,
labcomm_reader_continue
,
labcomm_reader_end
,
labcomm_reader_ioctl
}
labcomm_reader_action_t
;
struct
labcomm_reader
;
struct
labcomm_reader_action
{
int
(
*
alloc
)(
struct
labcomm_reader
*
,
char
*
labcomm_version
);
int
(
*
free
)(
struct
labcomm_reader
*
);
int
(
*
start
)(
struct
labcomm_reader
*
);
int
(
*
fill
)(
struct
labcomm_reader
*
);
int
(
*
end
)(
struct
labcomm_reader
*
);
int
(
*
fill
)(
struct
labcomm_reader
*
);
int
(
*
ioctl
)(
struct
labcomm_reader
*
,
int
,
labcomm_signature_t
*
,
va_list
);
};
...
...
@@ -108,6 +98,7 @@ typedef struct labcomm_reader {
int
data_size
;
int
count
;
int
pos
;
int
error
;
struct
labcomm_reader_action
action
;
labcomm_error_handler_callback
on_error
;
}
labcomm_reader_t
;
...
...
@@ -130,26 +121,20 @@ int labcomm_decoder_ioctl(struct labcomm_decoder *decoder,
/*
* Encoder
*/
typedef
struct
{
struct
labcomm_encoder
*
encoder
;
int
index
;
labcomm_signature_t
*
signature
;
void
*
value
;
}
labcomm_writer_start_t
;
typedef
enum
{
labcomm_writer_alloc
,
/* (..., char *labcomm_version)
Allocate all neccessary data */
labcomm_writer_free
,
/* Free all allocated data */
labcomm_writer_start
,
/* (..., labcomm_writer_start_t *s)
-EALREADY skips further encoding
Start writing an ordinary sample */
labcomm_writer_continue
,
/* Buffer full during ordinary sample */
labcomm_writer_end
,
/* End writing ordinary sample */
labcomm_writer_start_signature
,
/* Start writing signature */
labcomm_writer_continue_signature
,
/* Buffer full during signature */
labcomm_writer_end_signature
,
/* End writing signature */
}
labcomm_writer_action_t
;
struct
labcomm_writer
;
struct
labcomm_writer_action
{
int
(
*
alloc
)(
struct
labcomm_writer
*
w
,
char
*
labcomm_version
);
int
(
*
free
)(
struct
labcomm_writer
*
w
);
int
(
*
start
)(
struct
labcomm_writer
*
w
,
struct
labcomm_encoder
*
encoder
,
int
index
,
labcomm_signature_t
*
signature
,
void
*
value
);
int
(
*
end
)(
struct
labcomm_writer
*
w
);
int
(
*
flush
)(
struct
labcomm_writer
*
w
);
int
(
*
ioctl
)(
struct
labcomm_writer
*
w
,
int
,
labcomm_signature_t
*
,
va_list
);
};
typedef
struct
labcomm_writer
{
void
*
context
;
...
...
@@ -158,13 +143,12 @@ typedef struct labcomm_writer {
int
count
;
int
pos
;
int
error
;
int
(
*
write
)(
struct
labcomm_writer
*
,
labcomm_writer_action_t
,
...);
int
(
*
ioctl
)(
struct
labcomm_writer
*
,
int
,
labcomm_signature_t
*
,
va_list
);
struct
labcomm_writer_action
action
;
labcomm_error_handler_callback
on_error
;
}
labcomm_writer_t
;
struct
labcomm_encoder
*
labcomm_encoder_new
(
int
(
*
writer
)(
labcomm_writer_t
*
,
labcomm_writer_action
_t
,
...)
,
const
struct
labcomm_writer_action
action
,
void
*
writer_context
);
void
labcomm_encoder_free
(
struct
labcomm_encoder
*
encoder
);
...
...
lib/c/labcomm_dynamic_buffer_writer.c
View file @
70b290de
...
...
@@ -4,11 +4,78 @@
#include
"labcomm_ioctl.h"
#include
"labcomm_dynamic_buffer_writer.h"
static
int
labcomm_dynamic_buffer_writer_ioctl
(
struct
labcomm_writer
*
w
,
int
action
,
labcomm_signature_t
*
signature
,
va_list
arg
)
static
int
dyn_alloc
(
struct
labcomm_writer
*
w
,
char
*
labcomm_version
)
{
w
->
data_size
=
1000
;
w
->
count
=
w
->
data_size
;
w
->
data
=
malloc
(
w
->
data_size
);
if
(
w
->
data
==
NULL
)
{
w
->
error
=
-
ENOMEM
;
}
w
->
pos
=
0
;
return
w
->
error
;
}
static
int
dyn_free
(
struct
labcomm_writer
*
w
)
{
free
(
w
->
data
);
w
->
data
=
0
;
w
->
data_size
=
0
;
w
->
count
=
0
;
w
->
pos
=
0
;
return
0
;
}
static
int
dyn_start
(
struct
labcomm_writer
*
w
,
struct
labcomm_encoder
*
encoder
,
int
index
,
labcomm_signature_t
*
signature
,
void
*
value
)
{
void
*
tmp
;
w
->
data_size
=
1000
;
w
->
count
=
w
->
data_size
;
tmp
=
realloc
(
w
->
data
,
w
->
data_size
);
if
(
tmp
!=
NULL
)
{
w
->
data
=
tmp
;
w
->
error
=
0
;
}
else
{
w
->
error
=
-
ENOMEM
;
}
w
->
pos
=
0
;
return
w
->
error
;
}
static
int
dyn_end
(
struct
labcomm_writer
*
w
)
{
return
0
;
}
static
int
dyn_flush
(
struct
labcomm_writer
*
w
)
{
void
*
tmp
;
w
->
data_size
+=
1000
;
w
->
count
=
w
->
data_size
;
tmp
=
realloc
(
w
->
data
,
w
->
data_size
);
if
(
tmp
!=
NULL
)
{
w
->
data
=
tmp
;
w
->
error
=
0
;
}
else
{
w
->
error
=
-
ENOMEM
;
}
return
w
->
error
;
}
static
int
dyn_ioctl
(
struct
labcomm_writer
*
w
,
int
action
,
labcomm_signature_t
*
signature
,
va_list
arg
)
{
int
result
=
-
ENOTSUP
;
switch
(
action
)
{
...
...
@@ -26,59 +93,11 @@ static int labcomm_dynamic_buffer_writer_ioctl(
return
result
;
}
int
labcomm_dynamic_buffer_writer
(
labcomm_writer_t
*
w
,
labcomm_writer_action_t
action
,
...)
{
switch
(
action
)
{
case
labcomm_writer_alloc
:
{
w
->
data_size
=
1000
;
w
->
count
=
w
->
data_size
;
w
->
data
=
malloc
(
w
->
data_size
);
if
(
w
->
data
==
NULL
)
{
w
->
error
=
-
ENOMEM
;
}
w
->
pos
=
0
;
w
->
ioctl
=
labcomm_dynamic_buffer_writer_ioctl
;
}
break
;
case
labcomm_writer_start
:
case
labcomm_writer_start_signature
:
{
void
*
tmp
;
w
->
data_size
=
1000
;
w
->
count
=
w
->
data_size
;
tmp
=
realloc
(
w
->
data
,
w
->
data_size
);
if
(
tmp
!=
NULL
)
{
w
->
data
=
tmp
;
w
->
error
=
0
;
}
else
{
w
->
error
=
-
ENOMEM
;
}
w
->
pos
=
0
;
}
break
;
case
labcomm_writer_continue
:
case
labcomm_writer_continue_signature
:
{
void
*
tmp
;
w
->
data_size
+=
1000
;
w
->
count
=
w
->
data_size
;
tmp
=
realloc
(
w
->
data
,
w
->
data_size
);
if
(
tmp
!=
NULL
)
{
w
->
data
=
tmp
;
}
else
{
w
->
error
=
-
ENOMEM
;
}
}
break
;
case
labcomm_writer_end
:
case
labcomm_writer_end_signature
:
{
}
break
;
case
labcomm_writer_free
:
{
free
(
w
->
data
);
w
->
data
=
0
;
w
->
data_size
=
0
;
w
->
count
=
0
;
w
->
pos
=
0
;
}
break
;
}
return
w
->
error
;
}
const
struct
labcomm_writer_action
labcomm_dynamic_buffer_writer
=
{
.
alloc
=
dyn_alloc
,
.
free
=
dyn_free
,
.
start
=
dyn_start
,
.
end
=
dyn_end
,
.
flush
=
dyn_flush
,
.
ioctl
=
dyn_ioctl
};
lib/c/labcomm_dynamic_buffer_writer.h
View file @
70b290de
...
...
@@ -3,9 +3,6 @@
#include
"labcomm.h"
extern
int
labcomm_dynamic_buffer_writer
(
labcomm_writer_t
*
writer
,
labcomm_writer_action_t
action
,
...);
extern
const
struct
labcomm_writer_action
labcomm_dynamic_buffer_writer
;
#endif
lib/c/labcomm_fd_writer.c
View file @
70b290de
...
...
@@ -7,59 +7,70 @@
#define BUFFER_SIZE 2048
int
labcomm_fd_writer
(
labcomm_writer_t
*
w
,
labcomm_writer_action_t
action
,
...)
static
int
fd_alloc
(
struct
labcomm_writer
*
w
,
char
*
version
)
{
int
result
=
0
;
#ifndef LABCOMM_FD_OMIT_VERSION
int
*
fd
=
w
->
context
;
write
(
*
fd
,
version
,
strlen
(
version
));
#endif
w
->
data
=
malloc
(
BUFFER_SIZE
);
if
(
!
w
->
data
)
{
w
->
error
=
-
ENOMEM
;
w
->
data_size
=
0
;
w
->
count
=
0
;
w
->
pos
=
0
;
}
else
{
w
->
data_size
=
BUFFER_SIZE
;
w
->
count
=
BUFFER_SIZE
;
w
->
pos
=
0
;
}
switch
(
action
)
{
case
labcomm_writer_alloc
:
{
#ifndef LABCOMM_FD_OMIT_VERSION
va_list
ap
;
va_start
(
ap
,
action
);
char
*
version
=
va_arg
(
ap
,
char
*
);
return
w
->
error
;
}
write
(
*
fd
,
version
,
strlen
(
version
));
#endif
w
->
data
=
malloc
(
BUFFER_SIZE
);
if
(
!
w
->
data
)
{
result
=
-
ENOMEM
;
w
->
data_size
=
0
;
w
->
count
=
0
;
w
->
pos
=
0
;
}
else
{
w
->
data_size
=
BUFFER_SIZE
;
w
->
count
=
BUFFER_SIZE
;
w
->
pos
=
0
;
}
#ifndef LABCOMM_FD_OMIT_VERSION
va_end
(
ap
);
#endif
}
break
;
case
labcomm_writer_free
:
{
free
(
w
->
data
);
w
->
data
=
0
;
w
->
data_size
=
0
;
w
->
count
=
0
;
w
->
pos
=
0
;
}
break
;
case
labcomm_writer_start
:
case
labcomm_writer_start_signature
:
{
w
->
pos
=
0
;
}
break
;
case
labcomm_writer_continue
:
case
labcomm_writer_continue_signature
:
{
result
=
write
(
*
fd
,
w
->
data
,
w
->
pos
);
w
->
pos
=
0
;
}
break
;
case
labcomm_writer_end
:
case
labcomm_writer_end_signature
:
{
result
=
write
(
*
fd
,
w
->
data
,
w
->
pos
);
w
->
pos
=
0
;
}
break
;
static
int
fd_free
(
struct
labcomm_writer
*
w
)
{
free
(
w
->
data
);
w
->
data
=
0
;
w
->
data_size
=
0
;
w
->
count
=
0
;
w
->
pos
=
0
;
return
0
;
}
static
int
fd_start
(
struct
labcomm_writer
*
w
,
struct
labcomm_encoder
*
encoder
,
int
index
,
labcomm_signature_t
*
signature
,
void
*
value
)
{
w
->
pos
=
0
;
return
w
->
error
;
}
static
int
fd_flush
(
struct
labcomm_writer
*
w
)
{
int
*
fd
=
w
->
context
;
int
err
;
err
=
write
(
*
fd
,
w
->
data
,
w
->
pos
);
if
(
err
<
0
)
{
w
->
error
=
-
errno
;
}
else
if
(
err
==
0
)
{
w
->
error
=
-
EINVAL
;
}
return
result
;
w
->
pos
=
0
;
return
w
->
error
;
}
const
struct
labcomm_writer_action
labcomm_fd_writer
=
{
.
alloc
=
fd_alloc
,
.
free
=
fd_free
,
.
start
=
fd_start
,
.
end
=
fd_flush
,
.
flush
=
fd_flush
,
.
ioctl
=
NULL
};
lib/c/labcomm_fd_writer.h
View file @
70b290de
...
...
@@ -3,10 +3,7 @@
#include
"labcomm.h"
extern
int
labcomm_fd_writer
(
labcomm_writer_t
*
writer
,
labcomm_writer_action_t
action
,
...);
extern
const
struct
labcomm_writer_action
labcomm_fd_writer
;
#endif
lib/c/labcomm_private.h
View file @
70b290de
...
...
@@ -221,7 +221,7 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
for (i = sizeof(type) - 1 ; i >= 0 ; i--) { \
if (w->pos >= w->count) {
/*buffer is full*/
\
int err; \
err = w->
write(w, labcomm_writer_continue);
\
err = w->
action.flush(w);
\
if (err != 0) { return err; } \
} \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \
...
...
@@ -241,7 +241,7 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
for (i = 0 ; i < sizeof(type) ; i++) { \
if (w->pos >= w->count) { \
int err; \
err = w->
write(w, labcomm_writer_continue);
\
err = w->
action.flush(w);
\
if (err != 0) { return err; } \
} \
w->data[w->pos] = ((unsigned char*)(&data))[i]; \
...
...
@@ -263,95 +263,6 @@ LABCOMM_ENCODE(long, long long)
LABCOMM_ENCODE
(
float
,
float
)
LABCOMM_ENCODE
(
double
,
double
)
#if 0
/*
* Pack the 32 bit unsigned number data as a sequence bytes, where the
* first byte is prefixed with a variable length bit pattern that
* indicates the number of bytes used for encoding. The encoding
* is inspired by the UTF-8 encoding.
*
* 0b0 - 1 byte (0x00000000 - 0x0000007f)
* 0b10 - 2 bytes (0x00000080 - 0x00003fff)
* 0b110 - 3 bytes (0x00004000 - 0x001fffff)
* 0b1110 - 4 bytes (0x00200000 - 0x0fffffff)
* 0b11110 - 5 bytes (0x10000000 - 0xffffffff) [4 bits unused]
*/
static inline int labcomm_write_packed32(labcomm_writer_t *w,
unsigned int data)
{
int n;
unsigned char tag;
unsigned char tmp[4] = { (data >> 24) & 0xff,
(data >> 16) & 0xff,
(data >> 8) & 0xff,
(data ) & 0xff };
if (data < 0x80) {
n = 1;
tag = 0x00;
} else if (data < 0x4000) {
n = 2;
tag = 0x80;
} else if (data < 0x200000) {
n = 3;
tag = 0xc0;
} else if (data < 0x10000000) {
n = 4;
tag = 0xe0;
} else {
n = 5;
tag = 0xf0;
}
/* TODO: maybe?
if (w->pos + n - 1 >= w->count) {
w->write(w, labcomm_writer_continue, n);
}
*/
switch (n) {
case 5: {
if (w->pos >= w->count) {
int err;
err = w->write(w, labcomm_writer_continue);
if (err != 0) { return err; }
}