diff --git a/lib/spdylay_buffer.c b/lib/spdylay_buffer.c index d41d697..87afa85 100644 --- a/lib/spdylay_buffer.c +++ b/lib/spdylay_buffer.c @@ -201,6 +201,31 @@ void spdylay_buffer_reader_data(spdylay_buffer_reader *reader, } } +int spdylay_buffer_reader_count(spdylay_buffer_reader *reader, + size_t len, uint8_t c) +{ + int res = 0; + while(len) { + size_t remlen, readlen, i; + uint8_t *p; + remlen = reader->buffer->capacity - reader->offset; + readlen = spdylay_min(remlen, len); + p = reader->current->data + reader->offset; + for(i = 0; i < readlen; ++i) { + if(p[i] == c) { + ++res; + } + } + len -= readlen; + reader->offset += readlen; + if(reader->buffer->capacity == reader->offset) { + reader->current = reader->current->next; + reader->offset = 0; + } + } + return res; +} + void spdylay_buffer_reader_advance(spdylay_buffer_reader *reader, size_t amount) { diff --git a/lib/spdylay_buffer.h b/lib/spdylay_buffer.h index 38c0f31..aeeaf9d 100644 --- a/lib/spdylay_buffer.h +++ b/lib/spdylay_buffer.h @@ -154,6 +154,13 @@ uint32_t spdylay_buffer_reader_uint32(spdylay_buffer_reader *reader); void spdylay_buffer_reader_data(spdylay_buffer_reader *reader, uint8_t *out, size_t len); +/** + * Reads |len| bytes and count the occurrence of |c| there and return + * it. This function will advance the current position by |len|. + */ +int spdylay_buffer_reader_count(spdylay_buffer_reader *reader, + size_t len, uint8_t c); + /* * Advances the current position by |amount|. */ diff --git a/lib/spdylay_frame.c b/lib/spdylay_frame.c index 170f264..9b1fc78 100644 --- a/lib/spdylay_frame.c +++ b/lib/spdylay_frame.c @@ -146,12 +146,7 @@ int spdylay_frame_count_unpack_nv_space(size_t *nvlen_ptr, size_t *buflen_ptr, spdylay_buffer_reader_advance(&reader, len); } } - for(j = off, off -= len; off != j; ++off) { - uint8_t b = spdylay_buffer_reader_uint8(&reader); - if(b == '\0') { - ++nvlen; - } - } + nvlen += spdylay_buffer_reader_count(&reader, len, '\0'); ++nvlen; } if(inlen == off) {