Iterator-like interface for extracting records from a blob I have a blob whose format is something like:

(id1,key1,value1)(id2,key2,value2)....  

where id is a uint32_t, and key and value are null-terminated strings. I am looking for an iterator-like interface that will extract records from the blob.

This is what I have come up with:

typedef struct blob_ {  
    uint32_t size;  // length of the buffer
    char buf[]; 
}blob;

typedef struct record_ {
    uint32_t id;    // id
    char *key;      // pointer to key in the blob
    char *value;    // pointer to value in the blob
    char *next;    // pointer to where the next record starts
} record;  

static record
get_next_obj(const char* begin, const char* end)
{
    record obj; 
    if (begin == end) {
        obj.id = 0;
        obj.key = NULL;
        obj.value = NULL;
        obj._next = NULL;
    } else {

        memcpy(&amp;obj.id, begin, sizeof(uint32_t));
        begin += sizeof(uint32_t);

        obj.key = begin;
        while(begin &lt; end &amp;&amp; *begin != '\0')
            ++begin;

        ++begin;

        obj.value = begin;
        while(begin &lt; end &amp;&amp; *begin != '\0')
            ++begin;
        ++begin;

        obj.next = begin;
    }
    return obj;
}

record
blob_list_next(const blob *data, const record *prev)
{
    const char *begin, *end;

    begin = prev-&gt;next;
    end = data-&gt;buf + data-&gt;size;

    return get_next_obj(begin, end);
}

record
blob_list_begin(const blob *data)
{
    const char *begin, *end;

    begin = data-&gt;buf;
    end = data-&gt;buf + data-&gt;size;
    return get_next_obj(begin, end);
}

record
blob_list_end(const blob *data)
{
    record obj;
    obj.id = 0;
    obj.key = NULL;
    obj.value = NULL;
    obj.next = NULL;
    return obj;
}


Then the API will be accessed with something like this:

record obj;  
record obj_end;
// comp is a comparison operator of two record objects  
for (obj = blob_list_begin(data), obj_end = blob_list_end(data); 
    comp(obj, obj_end) == false; obj = blob_list_next(data, &amp;obj))  {   
   // access the obj
}  


I used return-by-value semantics because I wanted to avoid calling malloc(). There will be a maximum of 4096 records in a tuple.
Some random comments:


The behaviour of flexible array members are defined in the C99 standard, but undefined in C90. Because of that reason, you might want to add a compiler switch guard against C90 compilers:

#if !defined __STDC_VERSION__ || (__STDC_VERSION__ &lt; 199901L)
  #error Code must be compiled as C99 or later.
#endif

Why is the data binary data char and not uint8_t? char may or may not be signed, depending on the compiler.
Consider inlining get_next_obj(). Since you return the struct by value, even good C compilers will generate a lot of overhead code from that. If you can weed out at least the internal return-by-value, the algorithm will be a bit faster.
Any reason why the record objects can't hold a prev pointer? That is, why can't they be a double-linked list instead of a single linked one? And on the topic of linked lists, you may want to consider changing the type of the next pointer:

typedef struct record_ {
    uint32_t id;     // id
    char *key;       // pointer to key in the blob
    char *value;     // pointer to value in the blob
    record_ *next;   // pointer to the next record 
    record_ *prev;   // pointer to the previous record
} record;  


Or perhaps stuff all the record objects into a real linked list ADT.