diff options
Diffstat (limited to 'v_windows/v/old/vlib/net/http/chunked')
| -rw-r--r-- | v_windows/v/old/vlib/net/http/chunked/dechunk.v | 72 | 
1 files changed, 72 insertions, 0 deletions
| diff --git a/v_windows/v/old/vlib/net/http/chunked/dechunk.v b/v_windows/v/old/vlib/net/http/chunked/dechunk.v new file mode 100644 index 0000000..0e82586 --- /dev/null +++ b/v_windows/v/old/vlib/net/http/chunked/dechunk.v @@ -0,0 +1,72 @@ +module chunked + +import strings +// See: https://en.wikipedia.org/wiki/Chunked_transfer_encoding +// ///////////////////////////////////////////////////////////// +// The chunk size is transferred as a hexadecimal number +// followed by \r\n as a line separator, +// followed by a chunk of data of the given size. +// The end is marked with a chunk with size 0. + +struct ChunkScanner { +mut: +	pos  int +	text string +} + +fn (mut s ChunkScanner) read_chunk_size() int { +	mut n := 0 +	for { +		if s.pos >= s.text.len { +			break +		} +		c := s.text[s.pos] +		if !c.is_hex_digit() { +			break +		} +		n = n << 4 +		n += int(unhex(c)) +		s.pos++ +	} +	return n +} + +fn unhex(c byte) byte { +	if `0` <= c && c <= `9` { +		return c - `0` +	} else if `a` <= c && c <= `f` { +		return c - `a` + 10 +	} else if `A` <= c && c <= `F` { +		return c - `A` + 10 +	} +	return 0 +} + +fn (mut s ChunkScanner) skip_crlf() { +	s.pos += 2 +} + +fn (mut s ChunkScanner) read_chunk(chunksize int) string { +	startpos := s.pos +	s.pos += chunksize +	return s.text[startpos..s.pos] +} + +pub fn decode(text string) string { +	mut sb := strings.new_builder(100) +	mut cscanner := ChunkScanner{ +		pos: 0 +		text: text +	} +	for { +		csize := cscanner.read_chunk_size() +		if 0 == csize { +			break +		} +		cscanner.skip_crlf() +		sb.write_string(cscanner.read_chunk(csize)) +		cscanner.skip_crlf() +	} +	cscanner.skip_crlf() +	return sb.str() +} | 
