<commit_before>#include "spdy_nv_block.h"
#include "spdy_log.h"
#include "spdy_error.h"

#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <assert.h>

/**
 * Parse a Name/Value block payload.
 * @param nv_block - Target block.
 * @param data - Data to parse.
 * @param data_length - Length of data.
 * @see spdy_nv_block
 * @todo Replace mallocs with a single one. (Speed up!)
 * @todo Freeing in the loop.
 * @todo Multiple value support.
 * @return Errorcode
 */
int spdy_nv_block_parse(
		spdy_nv_block *nv_block,
		char *data,
		size_t data_length) {
	// The bounds of data.
	char *data_max = data + data_length;

	// Data must at least contain the number of NV pairs.
	if(data_length < 2) {
		SPDYDEBUG("Data to small.");
		return SPDY_ERROR_INSUFFICIENT_DATA;
	}

	// Read the 16 bit integer containing the number of name/value pairs.
	nv_block->count = ntohs(*((uint16_t*) data));
	assert(nv_block->count > 0);

	// Allocate memory for Name/Value pairs.
	nv_block->pairs = calloc(nv_block->count, sizeof(spdy_nv_pair));
	// Malloc failed
	if(!nv_block->pairs) {
		SPDYDEBUG("Malloc of pairs failed.");
		return SPDY_ERROR_MALLOC_FAILED;
	}

	// Move forward by two bytes.
	data += 2;

	uint16_t item_length;
	size_t size;
	// Loop through all pairs
	for(int i=0; i < nv_block->count; i++) {
		if(data+2 > data_max) {
			SPDYDEBUG("Data to small.");
			return SPDY_ERROR_INSUFFICIENT_DATA;
		}
		spdy_nv_pair *pair = &nv_block->pairs[i];

		// Read Name
		// Read length of name
		item_length = ntohs(*((uint16_t*) data));
		data += 2;
		// Allocate space for name
		size = (sizeof(char)*item_length)+1;
		if(data+item_length > data_max) {
			SPDYDEBUG("Data to small.");
			return SPDY_ERROR_INSUFFICIENT_DATA;
		}
		pair->name = malloc(size);
		if(!pair->name) {
			SPDYDEBUG("Pair name malloc failed.");
			return SPDY_ERROR_MALLOC_FAILED;
		}
		memcpy(pair->name, data, item_length);
		pair->name[item_length] = '\0';
		data += item_length;

		// Read Values
		// Read length of value
		if(data+2 > data_max) {
			SPDYDEBUG("Data to small.");
			return SPDY_ERROR_INSUFFICIENT_DATA;
		}
		item_length = ntohs(*((uint16_t*) data));
		data += 2;
		// Allocate space for values
		size = (sizeof(char)*item_length)+1;
		if(data+item_length > data_max) {
			SPDYDEBUG("Insufficient data for block parse.");
			return SPDY_ERROR_INSUFFICIENT_DATA;
		}
		pair->values = malloc(size);
		if(!pair->name) {
			SPDYDEBUG("Pair value malloc failed.");
			return SPDY_ERROR_MALLOC_FAILED;
		}
		memcpy(pair->values, data, item_length);
		pair->values[item_length] = '\0';
		data += item_length;
	}

	return 0;
}

int spdy_nv_block_inflate_parse(
		spdy_nv_block *nv_block,
		char *data,
		size_t data_length,
		spdy_zlib_context *zlib_ctx) {
	int ret;

	// Inflate NV block.
	char *inflate = NULL;
	size_t inflate_size = 0;
	
	if((ret = spdy_zlib_inflate(
					zlib_ctx,
					data,
					data_length,
					&inflate,
					&inflate_size)) != SPDY_ERROR_NONE) {
		SPDYDEBUG("Failed to inflate data.");
		return ret;
	}

	// Allocate space for NV block.
	/*nv_block = malloc(sizeof(spdy_nv_block));
	if(!nv_block) {
		// Inflate gets allocated in spdy_zlib_inflate.
		free(inflate);
		SPDYDEBUG("Failed to allocate memory for nv_block.");
		return SPDY_ERROR_MALLOC_FAILED;
	}*/

	// Parse NV block.
	if((ret = spdy_nv_block_parse(
					nv_block,<commit_msg>spdy_nv_block.c: Removed old, commented out & broken code.<commit_after>#include "spdy_nv_block.h"
#include "spdy_log.h"
#include "spdy_error.h"

#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <assert.h>

/**
 * Parse a Name/Value block payload.
 * @param nv_block - Target block.
 * @param data - Data to parse.
 * @param data_length - Length of data.
 * @see spdy_nv_block
 * @todo Replace mallocs with a single one. (Speed up!)
 * @todo Freeing in the loop.
 * @todo Multiple value support.
 * @return Errorcode
 */
int spdy_nv_block_parse(
		spdy_nv_block *nv_block,
		char *data,
		size_t data_length) {
	// The bounds of data.
	char *data_max = data + data_length;

	// Data must at least contain the number of NV pairs.
	if(data_length < 2) {
		SPDYDEBUG("Data to small.");
		return SPDY_ERROR_INSUFFICIENT_DATA;
	}

	// Read the 16 bit integer containing the number of name/value pairs.
	nv_block->count = ntohs(*((uint16_t*) data));
	assert(nv_block->count > 0);

	// Allocate memory for Name/Value pairs.
	nv_block->pairs = calloc(nv_block->count, sizeof(spdy_nv_pair));
	// Malloc failed
	if(!nv_block->pairs) {
		SPDYDEBUG("Malloc of pairs failed.");
		return SPDY_ERROR_MALLOC_FAILED;
	}

	// Move forward by two bytes.
	data += 2;

	uint16_t item_length;
	size_t size;
	// Loop through all pairs
	for(int i=0; i < nv_block->count; i++) {
		if(data+2 > data_max) {
			SPDYDEBUG("Data to small.");
			return SPDY_ERROR_INSUFFICIENT_DATA;
		}
		spdy_nv_pair *pair = &nv_block->pairs[i];

		// Read Name
		// Read length of name
		item_length = ntohs(*((uint16_t*) data));
		data += 2;
		// Allocate space for name
		size = (sizeof(char)*item_length)+1;
		if(data+item_length > data_max) {
			SPDYDEBUG("Data to small.");
			return SPDY_ERROR_INSUFFICIENT_DATA;
		}
		pair->name = malloc(size);
		if(!pair->name) {
			SPDYDEBUG("Pair name malloc failed.");
			return SPDY_ERROR_MALLOC_FAILED;
		}
		memcpy(pair->name, data, item_length);
		pair->name[item_length] = '\0';
		data += item_length;

		// Read Values
		// Read length of value
		if(data+2 > data_max) {
			SPDYDEBUG("Data to small.");
			return SPDY_ERROR_INSUFFICIENT_DATA;
		}
		item_length = ntohs(*((uint16_t*) data));
		data += 2;
		// Allocate space for values
		size = (sizeof(char)*item_length)+1;
		if(data+item_length > data_max) {
			SPDYDEBUG("Insufficient data for block parse.");
			return SPDY_ERROR_INSUFFICIENT_DATA;
		}
		pair->values = malloc(size);
		if(!pair->name) {
			SPDYDEBUG("Pair value malloc failed.");
			return SPDY_ERROR_MALLOC_FAILED;
		}
		memcpy(pair->values, data, item_length);
		pair->values[item_length] = '\0';
		data += item_length;
	}

	return 0;
}

int spdy_nv_block_inflate_parse(
		spdy_nv_block *nv_block,
		char *data,
		size_t data_length,
		spdy_zlib_context *zlib_ctx) {
	int ret;

	// Inflate NV block.
	char *inflate = NULL;
	size_t inflate_size = 0;
	
	if((ret = spdy_zlib_inflate(
					zlib_ctx,
					data,
					data_length,
					&inflate,
					&inflate_size)) != SPDY_ERROR_NONE) {
		SPDYDEBUG("Failed to inflate data.");
		return ret;
	}

	// Parse NV block.
	if((ret = spdy_nv_block_parse(
					nv_block,
{'fraction_non_alphanumeric': 0.13288426209430496, 'fraction_numerical': 0.007348438456827924, 'mean_word_length': 3.7237888647866955, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1027974', 'n_tokens_mistral': 2741, 'n_tokens_neox': 2461, 'n_words': 593}