You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
2.1 KiB
C
60 lines
2.1 KiB
C
#include "parse.h"
|
|
|
|
static const size_t max_ssize_t = (((size_t)1) << (sizeof(size_t)*8-1))-1;
|
|
|
|
/* Some protocols have a fixed field length for a string,
|
|
* If the string is shorter than the field, the rest is filled with 0
|
|
* bytes. But it is not an error if there are no 0 bytes.
|
|
* This function is for those cases (the filename field in the tar file
|
|
* header is an example of this).
|
|
* For a field of length 8, you need to pass destsize as 9 so we can add
|
|
* a 0 terminator. This function will consume the 8 bytes and add a 0 byte.
|
|
* The return value is strlen(dest). */
|
|
ssize_t prs_asciiz_fixedlen(struct bytestream* bs, char* dest, size_t len) {
|
|
size_t i;
|
|
ssize_t r=0;
|
|
/* The maximum value of ssize_t is half that of size_t.
|
|
* So we arbitrarily decide to limit len to it here. */
|
|
if (len>max_ssize_t) len=max_ssize_t;
|
|
if (len==0) {
|
|
bs->cur = 1; // mark bytestream state as erroneous
|
|
bs->max = 0;
|
|
return -1;
|
|
}
|
|
|
|
for (i=0; i+1<len; ++i)
|
|
if ((dest[i] = bs_get(bs)) == 0 && r==0)
|
|
r=i; // note the position of the first 0 byte
|
|
dest[i] = 0; // add 0 terminator
|
|
if (dest[r]) r=i;
|
|
return bs_err(bs) ? -1 : r;
|
|
}
|
|
|
|
#ifdef UNITTEST
|
|
#include <assert.h>
|
|
|
|
#undef UNITTEST
|
|
#include "buffer/bs_init_membuf.c"
|
|
#include "buffer/bs_get.c"
|
|
#include "buffer/bs_err.c"
|
|
#include "buffer/bs_peek.c"
|
|
|
|
// we use membuf here, mock buffer stuff away
|
|
ssize_t buffer_getc(buffer* b,char* x) { return 0; }
|
|
ssize_t buffer_peekc(buffer* b,char* x) { return 0; }
|
|
|
|
int main() {
|
|
struct bytestream bs = BS_FROM_MEMBUF("fnord\n\0x",8);
|
|
char buf[100];
|
|
assert(prs_asciiz_fixedlen(&bs, buf, 8) == 6); // return value should be strlen("fnord\n")
|
|
assert(!memcmp(buf,"fnord\n\0\0",8)); // returned string should be "fnord\n" and the rest filled with 0 bytes
|
|
assert(!bs_err(&bs));
|
|
|
|
bs_init_membuf(&bs, (const unsigned char*)"fnord\n\0x", 8);
|
|
assert(prs_asciiz_fixedlen(&bs, buf, 5) == 4); // no 0 terminator in first 4 bytes
|
|
assert(!memcmp(buf,"fnor",5)); // expect 4 bytes + 0 terminator in dest buf
|
|
assert(bs_get(&bs) == 'd'); // 0 terminator in buf was artificial, 'd' was not consumed
|
|
assert(!bs_err(&bs)); // bytestream should be ok
|
|
}
|
|
#endif
|