ssize_t nghttp2_nv_array_from_cstr(nghttp2_nv **nva_ptr, const char **nv) { int i; uint8_t *data; size_t buflen = 0, nvlen = 0; nghttp2_nv *p; for(i = 0; nv[i]; ++i) { size_t len = strlen(nv[i]); if(len > NGHTTP2_MAX_HD_VALUE_LENGTH) { return NGHTTP2_ERR_INVALID_ARGUMENT; } buflen += len; } nvlen = i/2; /* If all name/value pair is 0-length, remove them */ if(nvlen == 0 || buflen == 0) { *nva_ptr = NULL; return 0; } buflen += sizeof(nghttp2_nv)*nvlen; *nva_ptr = malloc(buflen); if(*nva_ptr == NULL) { return NGHTTP2_ERR_NOMEM; } p = *nva_ptr; data = (uint8_t*)(*nva_ptr) + sizeof(nghttp2_nv)*nvlen; for(i = 0; nv[i]; i += 2) { size_t len = strlen(nv[i]); memcpy(data, nv[i], len); p->name = data; p->namelen = len; nghttp2_downcase(p->name, p->namelen); data += len; len = strlen(nv[i+1]); memcpy(data, nv[i+1], len); p->value = data; p->valuelen = len; data += len; ++p; } nghttp2_nv_array_sort(*nva_ptr, nvlen); return nvlen; }
ssize_t nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva, size_t nvlen) { size_t i; uint8_t *data; size_t buflen = 0; nghttp2_nv *p; for(i = 0; i < nvlen; ++i) { buflen += nva[i].namelen + nva[i].valuelen; } /* If all name/value pair is 0-length, remove them */ if(nvlen == 0 || buflen == 0) { *nva_ptr = NULL; return 0; } buflen += sizeof(nghttp2_nv)*nvlen; *nva_ptr = malloc(buflen); if(*nva_ptr == NULL) { return NGHTTP2_ERR_NOMEM; } p = *nva_ptr; data = (uint8_t*)(*nva_ptr) + sizeof(nghttp2_nv)*nvlen; for(i = 0; i < nvlen; ++i) { memcpy(data, nva[i].name, nva[i].namelen); p->name = data; p->namelen = nva[i].namelen; nghttp2_downcase(p->name, p->namelen); data += nva[i].namelen; memcpy(data, nva[i].value, nva[i].valuelen); p->value = data; p->valuelen = nva[i].valuelen; data += nva[i].valuelen; ++p; } return nvlen; }