[5.2] 14578e5 VMOD blob: remove the decode_n() and transcode_n() functions.

PÃ¥l Hermunn Johansen hermunn at varnish-software.com
Fri Sep 15 11:17:19 UTC 2017


commit 14578e5a9298712e339b14502cef30dd7646466a
Author: Geoff Simmons <geoff at uplex.de>
Date:   Tue Sep 12 00:40:15 2017 +0200

    VMOD blob: remove the decode_n() and transcode_n() functions.
    
    decode() and transcode() now have an optional parameter length;
    if length > 0, decode that many characters from the encoded string.
    
    References #2421

diff --git a/bin/varnishtest/tests/m00033.vtc b/bin/varnishtest/tests/m00033.vtc
index 2340eda..81b654d 100644
--- a/bin/varnishtest/tests/m00033.vtc
+++ b/bin/varnishtest/tests/m00033.vtc
@@ -11,29 +11,29 @@ varnish v1 -vcl {
 	sub vcl_synth {
 	    set resp.http.id =
 	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY,
-			      "The quick brown fox jumps over the lazy dog"));
+			encoded="The quick brown fox jumps over the lazy dog"));
 
 	    set resp.http.hobbes =
-	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY,
+	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY, encoded=
 {"Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."}));
 
 	    set resp.http.list =
-	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY,
+	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY, encoded=
 			      "" + req.http.unset + req.url +
 			      "The quick brown fox jumps over " +
 			      req.http.unset + "" + req.http.unset + "" +
 			      "the lazy dog" + req.url + req.http.unset + ""));
 
 	    set resp.http.empty =
-	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY, ""));
+	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY, encoded=""));
 
 	    set resp.http.undef =
 	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY,
-						      req.http.unset));
+						     encoded=req.http.unset));
 
 	    set resp.http.emptylist =
 	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY,
-			      req.http.unset + "" + req.http.unset + ""));
+			  encoded=req.http.unset + "" + req.http.unset + ""));
 
 	    set resp.http.param =
 	      blob.encode(blob=
@@ -51,13 +51,16 @@ varnish v1 -vcl {
 			      decoding=IDENTITY));
 
 	    set resp.http.truncated =
-	      blob.encode(IDENTITY, blob=blob.decode(HEX, "666f6f00626172"));
+	      blob.encode(IDENTITY,
+	                  blob=blob.decode(HEX, encoded="666f6f00626172"));
 
 	    set resp.http.lc =
-	      blob.encode(IDENTITY, LOWER, blob.decode(IDENTITY, "Don't care"));
+	      blob.encode(IDENTITY, LOWER, blob.decode(IDENTITY,
+	                                               encoded="Don't care"));
 
 	    set resp.http.uc =
-	      blob.encode(IDENTITY, UPPER, blob.decode(IDENTITY, "Don't care"));
+	      blob.encode(IDENTITY, UPPER, blob.decode(IDENTITY,
+	                                               encoded="Don't care"));
 	}
 } -start
 
diff --git a/bin/varnishtest/tests/m00034.vtc b/bin/varnishtest/tests/m00034.vtc
index 949df45..95ea934 100644
--- a/bin/varnishtest/tests/m00034.vtc
+++ b/bin/varnishtest/tests/m00034.vtc
@@ -1,4 +1,4 @@
-varnishtest "VMOD blob IDENTITY decode_n()"
+varnishtest "VMOD blob IDENTITY decode() n chars"
 
 varnish v1 -vcl {
 	import blob;
@@ -10,45 +10,47 @@ varnish v1 -vcl {
 
 	sub vcl_synth {
 	    set resp.http.id =
-	      blob.encode(IDENTITY, blob=blob.decode_n(5, IDENTITY,
-			      "The quick brown fox jumps over the lazy dog"));
+	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY, length=5,
+			encoded="The quick brown fox jumps over the lazy dog"));
 
 	    set resp.http.hobbes =
-	      blob.encode(IDENTITY, blob=blob.decode_n(5, IDENTITY,
+	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY, length=5,
+	                  encoded=
 {"Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure."}));
 
 	    set resp.http.list =
-	      blob.encode(IDENTITY, blob=blob.decode_n(6, IDENTITY,
-			      "" + req.http.unset + req.url +
+	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY, length=6,
+			      encoded="" + req.http.unset + req.url +
 			      "The quick brown fox jumps over " +
 			      req.http.unset + "" + req.http.unset + "" +
 			      "the lazy dog" + req.url + req.http.unset + ""));
 
 	    set resp.http.empty =
-	      blob.encode(IDENTITY, blob=blob.decode_n(5, IDENTITY, ""));
+	      blob.encode(IDENTITY,
+	                  blob=blob.decode(IDENTITY, length=5, encoded=""));
 
 	    set resp.http.undef =
-	      blob.encode(IDENTITY, blob=blob.decode_n(5, IDENTITY,
-						      req.http.unset));
+	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY, length=5,
+						     encoded=req.http.unset));
 
 	    set resp.http.emptylist =
-	      blob.encode(IDENTITY, blob=blob.decode_n(5, IDENTITY,
-			      req.http.unset + "" + req.http.unset + ""));
+	      blob.encode(IDENTITY, blob=blob.decode(IDENTITY, length=5,
+			  encoded=req.http.unset + "" + req.http.unset + ""));
 
 	    set resp.http.param =
 	      blob.encode(blob=
-			      blob.decode_n(encoded=
+			      blob.decode(encoded=
 				 "The quick brown fox jumps over the lazy dog",
-					    n=7, decoding=IDENTITY),
+					    length=7, decoding=IDENTITY),
 			      encoding=IDENTITY);
 
 	    set resp.http.paramlist =
-	      blob.encode(IDENTITY, blob=blob.decode_n(encoded=
+	      blob.encode(IDENTITY, blob=blob.decode(encoded=
 			      "" + req.http.unset + req.url +
 			      "The quick brown fox jumps over " +
 			      req.http.unset + "" + req.http.unset + "" +
 			      "the lazy dog" + req.url + req.http.unset + "",
-			      decoding=IDENTITY, n=37));
+			      decoding=IDENTITY, length=37));
 	}
 } -start
 
diff --git a/bin/varnishtest/tests/m00035.vtc b/bin/varnishtest/tests/m00035.vtc
index e1aa0ff..6190914 100644
--- a/bin/varnishtest/tests/m00035.vtc
+++ b/bin/varnishtest/tests/m00035.vtc
@@ -19,49 +19,56 @@ varnish v1 -arg "-p workspace_client=256k" -vcl {
 {"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="};
 
 	    set resp.http.hex =
-	      blob.encode(HEX, blob=blob.decode(IDENTITY, req.http.pangram));
+	      blob.encode(HEX, blob=blob.decode(IDENTITY,
+	                                        encoded=req.http.pangram));
 
 	    set resp.http.hexlc =
 	      blob.encode(HEX, LOWER,
-	                  blob.decode(IDENTITY, req.http.pangram));
+	                  blob.decode(IDENTITY, encoded=req.http.pangram));
 
 	    set resp.http.hexuc =
 	      blob.encode(HEX, UPPER,
-			  blob.decode(IDENTITY, req.http.pangram));
+			  blob.decode(IDENTITY, encoded=req.http.pangram));
 
 	    set resp.http.hobbes =
-	      blob.encode(HEX, blob=blob.decode(IDENTITY, req.http.hobbes));
+	      blob.encode(HEX, blob=blob.decode(IDENTITY,
+	                                        encoded=req.http.hobbes));
 
 	    set resp.http.hobbeslc =
-	      blob.encode(HEX, LOWER, blob.decode(IDENTITY, req.http.hobbes));
+	      blob.encode(HEX, LOWER, blob.decode(IDENTITY,
+	                                          encoded=req.http.hobbes));
 
 	    set resp.http.hobbesuc =
-	      blob.encode(HEX, UPPER, blob.decode(IDENTITY, req.http.hobbes));
+	      blob.encode(HEX, UPPER, blob.decode(IDENTITY,
+	                                          encoded=req.http.hobbes));
 
 	    set resp.http.all =
-	      blob.encode(HEX, blob=blob.decode(BASE64, req.http.b64all));
+	      blob.encode(HEX, blob=blob.decode(BASE64,
+	                                        encoded=req.http.b64all));
 
 	    set resp.http.all-lc =
-	      blob.encode(HEX, LOWER, blob.decode(BASE64, req.http.b64all));
+	      blob.encode(HEX, LOWER, blob.decode(BASE64,
+	                                          encoded=req.http.b64all));
 
 	    set resp.http.all-uc =
-	      blob.encode(HEX, UPPER, blob.decode(BASE64, req.http.b64all));
+	      blob.encode(HEX, UPPER, blob.decode(BASE64,
+	                                          encoded=req.http.b64all));
 
 	    set resp.http.empty =
-	      blob.encode(HEX, blob=blob.decode(IDENTITY, ""));
+	      blob.encode(HEX, blob=blob.decode(IDENTITY, encoded=""));
 
 	    set resp.http.empty-lc =
-	      blob.encode(HEX, LOWER, blob.decode(IDENTITY, ""));
+	      blob.encode(HEX, LOWER, blob.decode(IDENTITY, encoded=""));
 
 	    set resp.http.empty-uc =
-	      blob.encode(HEX, UPPER, blob.decode(IDENTITY, ""));
+	      blob.encode(HEX, UPPER, blob.decode(IDENTITY, encoded=""));
 
 	    set resp.http.hexlcparam =
-	      blob.encode(blob=blob.decode(IDENTITY, req.http.pangram),
+	      blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
 			  case=LOWER, encoding=HEX);
 
 	    set resp.http.hexucparam =
-	      blob.encode(blob=blob.decode(IDENTITY, req.http.pangram),
+	      blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
 			  case=UPPER, encoding=HEX);
 
 	    set req.http.hexucfoobar = "666F6F206261722062617A2071757578";
@@ -76,52 +83,55 @@ varnish v1 -arg "-p workspace_client=256k" -vcl {
 
 	    set resp.http.decuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(HEX, req.http.hexucfoobar));
+			  blob=blob.decode(HEX, encoded=req.http.hexucfoobar));
 
 	    set resp.http.declc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(HEX, req.http.hexlcfoobar));
+			  blob=blob.decode(HEX, encoded=req.http.hexlcfoobar));
 
 	    set resp.http.dechobbesuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(HEX, req.http.hexhobbesuc));
+			  blob=blob.decode(HEX, encoded=req.http.hexhobbesuc));
 
 	    set resp.http.dechobbeslc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(HEX, req.http.hexhobbeslc));
+			  blob=blob.decode(HEX, encoded=req.http.hexhobbeslc));
 
 	    set resp.http.decalluc =
-	      blob.encode(BASE64, blob=blob.decode(HEX, req.http.hexalluc));
+	      blob.encode(BASE64, blob=blob.decode(HEX,
+	                                           encoded=req.http.hexalluc));
 
 	    set resp.http.decalllc =
-	      blob.encode(BASE64, blob=blob.decode(HEX, req.http.hexalllc));
+	      blob.encode(BASE64, blob=blob.decode(HEX,
+	                                           encoded=req.http.hexalllc));
 
 	    set resp.http.decallucodd =
-	      blob.encode(BASE64, blob=blob.decode(HEX,
-						   req.http.hexallucodd));
+	      blob.encode(BASE64,
+	                  blob=blob.decode(HEX, encoded=req.http.hexallucodd));
 
 	    set resp.http.decalllcodd =
-	      blob.encode(BASE64, blob=blob.decode(HEX,
-						   req.http.hexalllcodd));
+	      blob.encode(BASE64,
+	                  blob=blob.decode(HEX, encoded=req.http.hexalllcodd));
 
 	    set resp.http.decempty =
-	      blob.encode(IDENTITY, blob=blob.decode(HEX, ""));
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, encoded=""));
 
 	    set resp.http.decemptybyte =
-	      blob.encode(IDENTITY, blob=blob.decode(HEX, "00"));
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, encoded="00"));
 
 	    set resp.http.decemptynibble =
-	      blob.encode(IDENTITY, blob=blob.decode(HEX, "0"));
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, encoded="0"));
 
 	    set resp.http.decemptypieces =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(HEX, req.http.unset + ""
-					        + req.http.unset + ""));
+			  blob=blob.decode(HEX, encoded=req.http.unset + ""
+					                + req.http.unset + ""));
 
 	    set req.http.part1 = "666";
 	    set resp.http.dec2pieces =
-	      blob.encode(IDENTITY, blob=blob.decode(HEX, req.http.part1 +
-			     "F6F206261722062617A2071757578"));
+	      blob.encode(IDENTITY, blob=blob.decode(HEX,
+	                  encoded=req.http.part1 +
+			          "F6F206261722062617A2071757578"));
 
 	    set req.http.part2 = "57578";
 	    set resp.http.dec3param =
@@ -131,11 +141,13 @@ varnish v1 -arg "-p workspace_client=256k" -vcl {
 			     encoding=IDENTITY);
 
 	    set resp.http.dec3pieces =
-	      blob.encode(IDENTITY, blob=blob.decode(HEX, req.http.part1 +
+	      blob.encode(IDENTITY, blob=blob.decode(HEX,
+	                  encoded=req.http.part1 +
 			     "F6F206261722062617A20717" + req.http.part2));
 
 	    set resp.http.decmanypieces =
-	      blob.encode(IDENTITY, blob=blob.decode(HEX, "" + req.http.unset
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, encoded=
+	                     "" + req.http.unset
 			     + req.http.part1 + req.http.unset + ""
 			     + req.http.unset + "" + "F6F206261722062617A20717"
 			     + "" + req.http.unset + req.http.part2
@@ -191,7 +203,7 @@ varnish v1 -vcl+backend {
 	sub vcl_deliver {
 	  set req.http.foo = "123";
 	  set resp.http.badhex = blob.encode(HEX, UPPER,
-				 blob.decode(HEX, "g" + req.http.foo));
+				 blob.decode(HEX, encoded="g" + req.http.foo));
 	}
 }
 
diff --git a/bin/varnishtest/tests/m00036.vtc b/bin/varnishtest/tests/m00036.vtc
index cf6335b..635d726 100644
--- a/bin/varnishtest/tests/m00036.vtc
+++ b/bin/varnishtest/tests/m00036.vtc
@@ -1,4 +1,4 @@
-varnishtest "VMOD blob hex decode_n()"
+varnishtest "VMOD blob hex decode() n chars"
 
 varnish v1 -vcl {
 	import blob;
@@ -19,40 +19,45 @@ varnish v1 -vcl {
 
 	    set resp.http.hexlc =
 	      blob.encode(HEX,
-			  blob=blob.decode_n(5, IDENTITY, req.http.pangram));
+			  blob=blob.decode(IDENTITY, 5,
+			                   encoded=req.http.pangram));
 
 	    set resp.http.hexuc =
 	      blob.encode(HEX, UPPER,
-			  blob.decode_n(5, IDENTITY, req.http.pangram));
+			  blob.decode(IDENTITY, 5, encoded=req.http.pangram));
 
 	    set resp.http.hobbeslc =
 	      blob.encode(HEX,
-	                  blob=blob.decode_n(5, IDENTITY, req.http.hobbes));
+	                  blob=blob.decode(IDENTITY, 5,
+			                   encoded=req.http.hobbes));
 
 	    set resp.http.hobbesuc =
 	      blob.encode(HEX, UPPER,
-	                  blob.decode_n(5, IDENTITY, req.http.hobbes));
+	                  blob.decode(IDENTITY, 5, encoded=req.http.hobbes));
 
 	    set resp.http.all-lc =
-	      blob.encode(HEX, blob=blob.decode_n(8, BASE64, req.http.b64all));
+	      blob.encode(HEX, blob=blob.decode(BASE64, 8,
+	                                        encoded=req.http.b64all));
 
 	    set resp.http.all-uc =
 	      blob.encode(HEX, UPPER,
-	                  blob.decode_n(8, BASE64, req.http.b64all));
+	                  blob.decode(BASE64, 8, encoded=req.http.b64all));
 
 	    set resp.http.empty-lc =
-	      blob.encode(HEX, blob=blob.decode_n(5, IDENTITY, ""));
+	      blob.encode(HEX, blob=blob.decode(IDENTITY, 5, encoded=""));
 
 	    set resp.http.empty-uc =
-	      blob.encode(HEX, UPPER, blob.decode_n(5, IDENTITY, ""));
+	      blob.encode(HEX, UPPER, blob.decode(IDENTITY, 5, encoded=""));
 
 	    set resp.http.hexlcparam =
-	      blob.encode(blob=blob.decode_n(5, IDENTITY, req.http.pangram),
-			     encoding=HEX, case=LOWER);
+	      blob.encode(blob=blob.decode(IDENTITY, 5,
+	                                   encoded=req.http.pangram),
+			                   encoding=HEX, case=LOWER);
 
 	    set resp.http.hexucparam =
-	      blob.encode(blob=blob.decode_n(5, IDENTITY, req.http.pangram),
-			     encoding=HEX, case=UPPER);
+	      blob.encode(blob=blob.decode(IDENTITY, 5,
+	                                   encoded=req.http.pangram),
+			                   encoding=HEX, case=UPPER);
 
 	    set req.http.hexucfoobar = "666F6F206261722062617A2071757578";
 	    set req.http.hexlcfoobar = std.tolower(req.http.hexucfoobar);
@@ -66,68 +71,74 @@ varnish v1 -vcl {
 
 	    set resp.http.decuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(10, HEX, req.http.hexucfoobar));
+			  blob=blob.decode(HEX, 10,
+			                   encoded=req.http.hexucfoobar));
 
 	    set resp.http.declc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(10, HEX, req.http.hexlcfoobar));
+			  blob=blob.decode(HEX, 10,
+			                   encoded=req.http.hexlcfoobar));
 
 	    set resp.http.dechobbesuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(12, HEX, req.http.hexhobbesuc));
+			  blob=blob.decode(HEX, 12,
+			                   encoded=req.http.hexhobbesuc));
 
 	    set resp.http.dechobbeslc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(12, HEX, req.http.hexhobbeslc));
+			  blob=blob.decode(HEX, 12,
+			                   encoded=req.http.hexhobbeslc));
 
 	    set resp.http.decalluc =
 	      blob.encode(BASE64,
-	                  blob=blob.decode_n(12, HEX, req.http.hexalluc));
+	                  blob=blob.decode(HEX, 12, encoded=req.http.hexalluc));
 
 	    set resp.http.decalllc =
 	      blob.encode(BASE64,
-	                  blob=blob.decode_n(12, HEX, req.http.hexalllc));
+	                  blob=blob.decode(HEX, 12, encoded=req.http.hexalllc));
 
 	    set resp.http.decallucodd =
-	      blob.encode(BASE64, blob=blob.decode_n(11, HEX,
-						     req.http.hexallucodd));
+	      blob.encode(BASE64, blob=blob.decode(HEX, 11,
+						 encoded=req.http.hexallucodd));
 
 	    set resp.http.decalllcodd =
-	      blob.encode(BASE64, blob=blob.decode_n(11, HEX,
-						     req.http.hexalllcodd));
+	      blob.encode(BASE64, blob=blob.decode(HEX, 11,
+						 encoded=req.http.hexalllcodd));
 
 	    set resp.http.decempty =
-	      blob.encode(IDENTITY, blob=blob.decode_n(5, HEX, ""));
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, 5, encoded=""));
 
 	    set resp.http.decemptybyte =
-	      blob.encode(IDENTITY, blob=blob.decode_n(1, HEX, "00"));
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, 1, encoded="00"));
 
 	    set resp.http.decemptynibble =
-	      blob.encode(IDENTITY, blob=blob.decode_n(2, HEX, "0"));
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, 2, encoded="0"));
 
 	    set resp.http.decemptypieces =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(5, HEX, req.http.unset + ""
+			  blob=blob.decode(HEX, 5, encoded=req.http.unset + ""
 					     + req.http.unset + ""));
 
 	    set req.http.part1 = "666";
 	    set resp.http.dec2pieces =
-	      blob.encode(IDENTITY, blob=blob.decode_n(6, HEX, req.http.part1 +
-			     "F6F206261722062617A2071757578"));
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, 6,
+	                                             encoded=req.http.part1 +
+			                      "F6F206261722062617A2071757578"));
 
 	    set req.http.part2 = "57578";
 	    set resp.http.dec3param =
-	      blob.encode(blob=blob.decode_n(encoded=req.http.part1 +
+	      blob.encode(blob=blob.decode(encoded=req.http.part1 +
 			     "F6F206261722062617A20717" + req.http.part2,
-			     decoding=HEX,n=8),
+			     decoding=HEX, length=8),
 			     encoding=IDENTITY);
 
 	    set resp.http.dec3pieces =
-	      blob.encode(IDENTITY, blob=blob.decode_n(30, HEX, req.http.part1 +
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, 30,
+	                     encoded=req.http.part1 +
 			     "F6F206261722062617A20717" + req.http.part2));
 
 	    set resp.http.decmanypieces =
-	      blob.encode(IDENTITY, blob=blob.decode_n(20, HEX, ""
+	      blob.encode(IDENTITY, blob=blob.decode(HEX, 20, encoded=""
 	                     + req.http.unset
 			     + req.http.part1 + req.http.unset + ""
 			     + req.http.unset + "" + "F6F206261722062617A20717"
@@ -180,7 +191,8 @@ varnish v1 -vcl+backend {
 	sub vcl_deliver {
 	  set req.http.foo = "123";
 	  set resp.http.badhex = blob.encode(HEX, UPPER,
-				 blob.decode_n(2, HEX, "g" + req.http.foo));
+				 blob.decode(HEX, 2,
+				             encoded="g" + req.http.foo));
 	}
 }
 
diff --git a/bin/varnishtest/tests/m00037.vtc b/bin/varnishtest/tests/m00037.vtc
index 25a7dee..e8ee70a 100644
--- a/bin/varnishtest/tests/m00037.vtc
+++ b/bin/varnishtest/tests/m00037.vtc
@@ -18,80 +18,83 @@ varnish v1 -vcl {
 {"fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0dfdedddcdbdad9d8d7d6d5d4d3d2d1d0cfcecdcccbcac9c8c7c6c5c4c3c2c1c0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0afaeadacabaaa9a8a7a6a5a4a3a2a1a09f9e9d9c9b9a999897969594939291908f8e8d8c8b8a898887868584838281807f7e7d7c7b7a797877767574737271706f6e6d6c6b6a696867666564636261605f5e5d5c5b5a595857565554535251504f4e4d4c4b4a494847464544434241403f3e3d3c3b3a393837363534333231302f2e2d2c2b2a292827262524232221201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100"};
 
 	    set resp.http.b64 =
-	      blob.encode(BASE64, blob=blob.decode(IDENTITY,
+	      blob.encode(BASE64, blob=blob.decode(IDENTITY, encoded=
 						      req.http.pangram));
 
 	    set resp.http.b64lc =
-	      blob.encode(BASE64, LOWER, blob.decode(IDENTITY,
+	      blob.encode(BASE64, LOWER, blob.decode(IDENTITY, encoded=
 						      req.http.pangram));
 
 	    set resp.http.b64uc =
-	      blob.encode(BASE64, UPPER, blob.decode(IDENTITY,
+	      blob.encode(BASE64, UPPER, blob.decode(IDENTITY, encoded=
 						      req.http.pangram));
 
 	    set resp.http.b64hobbes =
-	      blob.encode(BASE64, blob=blob.decode(IDENTITY,
+	      blob.encode(BASE64, blob=blob.decode(IDENTITY, encoded=
 						      req.http.hobbes));
 
 	    set resp.http.b64all =
-	      blob.encode(BASE64, blob=blob.decode(HEX, req.http.hexall));
+	      blob.encode(BASE64, blob=blob.decode(HEX,
+	                                           encoded=req.http.hexall));
 
 	    set resp.http.b64url =
 	      blob.encode(BASE64URL,
-			  blob=blob.decode(IDENTITY, req.http.pangram));
+			  blob=blob.decode(IDENTITY, encoded=req.http.pangram));
 
 	    set resp.http.b64urllc =
 	      blob.encode(BASE64URL, LOWER,
-			  blob.decode(IDENTITY, req.http.pangram));
+			  blob.decode(IDENTITY, encoded=req.http.pangram));
 
 	    set resp.http.b64urluc =
 	      blob.encode(BASE64URL, UPPER,
-			  blob.decode(IDENTITY, req.http.pangram));
+			  blob.decode(IDENTITY, encoded=req.http.pangram));
 
 	    set resp.http.b64urlhobbes =
 	      blob.encode(BASE64URL,
-			  blob=blob.decode(IDENTITY, req.http.hobbes));
+			  blob=blob.decode(IDENTITY, encoded=req.http.hobbes));
 
 	    set resp.http.b64urlall =
-	      blob.encode(BASE64URL, blob=blob.decode(HEX, req.http.hexall));
+	      blob.encode(BASE64URL, blob=blob.decode(HEX,
+	                                              encoded=req.http.hexall));
 
 	    set resp.http.b64urlnopad =
 	      blob.encode(BASE64URLNOPAD,
-			  blob=blob.decode(IDENTITY, req.http.pangram));
+			  blob=blob.decode(IDENTITY, encoded=req.http.pangram));
 
 	    set resp.http.b64urlnopadlc =
 	      blob.encode(BASE64URLNOPAD, LOWER,
-			  blob.decode(IDENTITY, req.http.pangram));
+			  blob.decode(IDENTITY, encoded=req.http.pangram));
 
 	    set resp.http.b64urlnopaduc =
 	      blob.encode(BASE64URLNOPAD, UPPER,
-			  blob.decode(IDENTITY, req.http.pangram));
+			  blob.decode(IDENTITY, encoded=req.http.pangram));
 
 	    set resp.http.b64nopadhobbes =
 	      blob.encode(BASE64URLNOPAD,
-			  blob=blob.decode(IDENTITY, req.http.hobbes));
+			  blob=blob.decode(IDENTITY, encoded=req.http.hobbes));
 
 	    set resp.http.b64nopadall =
 	      blob.encode(BASE64URLNOPAD,
-			  blob=blob.decode(HEX, req.http.hexall));
+			  blob=blob.decode(HEX, encoded=req.http.hexall));
 
 	    set resp.http.b64empty =
-	      blob.encode(BASE64, blob=blob.decode(IDENTITY, ""));
+	      blob.encode(BASE64, blob=blob.decode(IDENTITY, encoded=""));
 	    set resp.http.urlempty =
-	      blob.encode(BASE64URL, blob=blob.decode(IDENTITY, ""));
+	      blob.encode(BASE64URL, blob=blob.decode(IDENTITY, encoded=""));
 	    set resp.http.nopadempty =
-	      blob.encode(BASE64URLNOPAD, blob=blob.decode(IDENTITY, ""));
+	      blob.encode(BASE64URLNOPAD,
+	                  blob=blob.decode(IDENTITY, encoded=""));
 
 	    set resp.http.b64param =
-	      blob.encode(blob=blob.decode(IDENTITY, req.http.pangram),
+	      blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
 			  encoding=BASE64, case=LOWER);
 
 	    set resp.http.b64urlparam =
-	      blob.encode(blob=blob.decode(IDENTITY, req.http.pangram),
+	      blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
 			  encoding=BASE64URL, case=UPPER);
 
 	    set resp.http.b64urlnopadparam =
-	      blob.encode(blob=blob.decode(IDENTITY, req.http.pangram),
+	      blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
 			  encoding=BASE64URLNOPAD, case=LOWER);
 
 	    set resp.http.b64xcode =
@@ -157,66 +160,71 @@ varnish v1 -vcl {
 {"AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZaaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzz0000111122223333444455556666777788889999----____"};
 
 	    set resp.http.dec = blob.encode(IDENTITY, blob=
-				blob.decode(BASE64, req.http.foobarbazquux));
+				blob.decode(BASE64,
+				            encoded=req.http.foobarbazquux));
 
 	    set resp.http.dec2
 	      = blob.encode(IDENTITY,
-			    blob=blob.decode(BASE64, req.http.pangram));
+			    blob=blob.decode(BASE64, encoded=req.http.pangram));
 
 	    set resp.http.b64dechobbes =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(BASE64, req.http.hobbes));
+			  blob=blob.decode(BASE64, encoded=req.http.hobbes));
 
 	    set resp.http.b64decall =
-	      blob.encode(HEX, blob=blob.decode(BASE64, req.http.all));
+	      blob.encode(HEX, blob=blob.decode(BASE64, encoded=req.http.all));
 
 	    set resp.http.urldechobbes =
 	      blob.encode(IDENTITY, blob=blob.decode(BASE64URL,
-						      req.http.hobbes));
+						     encoded=req.http.hobbes));
 
 	    set resp.http.urldecall =
 	      blob.encode(HEX,
-			  blob=blob.decode(BASE64URL, req.http.allurl));
+			  blob=blob.decode(BASE64URL, encoded=req.http.allurl));
 
 	    set resp.http.nopaddechobbes =
-	      blob.encode(IDENTITY, blob=blob.decode(BASE64URLNOPAD,
-						      req.http.hobbesnopad));
+	      blob.encode(IDENTITY,
+	                  blob=blob.decode(BASE64URLNOPAD,
+					   encoded=req.http.hobbesnopad));
 
 	    set resp.http.nopaddecall =
 	      blob.encode(HEX,
-			  blob=blob.decode(BASE64URLNOPAD, req.http.allurl));
+			  blob=blob.decode(BASE64URLNOPAD,
+			                   encoded=req.http.allurl));
 
 	    set resp.http.b64empty =
-	      blob.encode(IDENTITY, blob=blob.decode(BASE64, ""));
+	      blob.encode(IDENTITY, blob=blob.decode(BASE64, encoded=""));
 	    set resp.http.urlempty =
-	      blob.encode(IDENTITY, blob=blob.decode(BASE64URL, ""));
+	      blob.encode(IDENTITY, blob=blob.decode(BASE64URL, encoded=""));
 	    set resp.http.nopadempty =
-	      blob.encode(IDENTITY, blob=blob.decode(BASE64URLNOPAD, ""));
+	      blob.encode(IDENTITY,
+	                  blob=blob.decode(BASE64URLNOPAD, encoded=""));
 	    set resp.http.emptypieces =
 	      blob.encode(IDENTITY, blob=
-	      blob.decode(BASE64, req.http.unset + "" + req.http.unset
+	      blob.decode(BASE64, encoded=req.http.unset + "" + req.http.unset
 				      + "" + req.http.unset + ""));
 
 	    set resp.http.decenc
 	      = blob.encode(BASE64,
-			    blob=blob.decode(BASE64, req.http.foobarbazquux));
+			    blob=blob.decode(BASE64,
+			                     encoded=req.http.foobarbazquux));
 
 	    set resp.http.l = "L";
 	    set resp.http.dec2pieces
 	      = blob.encode(IDENTITY, blob=blob.decode(BASE64,
-				resp.http.l + "0hlbGxvIHdvcmxkLw=="));
+				encoded=resp.http.l + "0hlbGxvIHdvcmxkLw=="));
 
 	    set resp.http.pad = "==";
 	    set resp.http.dec3pieces
 	      = blob.encode(IDENTITY, blob=blob.decode(BASE64,
-				resp.http.l + "0hlbGxvIHdvcmxkLw"
+				encoded=resp.http.l + "0hlbGxvIHdvcmxkLw"
 				+ resp.http.pad));
 
 	    set resp.http.mid1 = "GxvI";
 	    set resp.http.mid2 = "dvcmx";
 	    set resp.http.dec7pieces
 	      = blob.encode(IDENTITY, blob=blob.decode(BASE64,
-				resp.http.l + "0hlb" + resp.http.mid1
+				encoded=resp.http.l + "0hlb" + resp.http.mid1
 				+ "H" + resp.http.mid2 + "kLw"
 				+ resp.http.pad));
 
@@ -226,22 +234,22 @@ varnish v1 -vcl {
 				+ resp.http.pad, decoding=BASE64),
 				encoding=IDENTITY);
 
-	    set resp.http.decnopad = blob.encode(IDENTITY,
-				     blob=blob.decode(BASE64URLNOPAD,
-						     "L0hlbGxvIHdvcmxkLw"));
+	    set resp.http.decnopad
+	      = blob.encode(IDENTITY, blob=blob.decode(BASE64URLNOPAD,
+						 encoded="L0hlbGxvIHdvcmxkLw"));
 
 	    set resp.http.decnopad2pieces
 	      = blob.encode(IDENTITY, blob=blob.decode(BASE64URLNOPAD,
-				resp.http.l + "0hlbGxvIHdvcmxkLw"));
+			    encoded=resp.http.l + "0hlbGxvIHdvcmxkLw"));
 
 	    set resp.http.decnopad6pieces
 	      = blob.encode(IDENTITY, blob=blob.decode(BASE64URLNOPAD,
-				resp.http.l + "0hlb" + resp.http.mid1
-				+ "H" + resp.http.mid2 + "kLw"));
+			    encoded=resp.http.l + "0hlb" + resp.http.mid1
+				    + "H" + resp.http.mid2 + "kLw"));
 
 	    set resp.http.decnopadlong
 	      = blob.encode(IDENTITY,
-		blob=blob.decode(BASE64URLNOPAD,
+		blob=blob.decode(BASE64URLNOPAD, encoded=
 		"VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw"
 			       ));
 
@@ -288,15 +296,16 @@ varnish v1 -vcl+backend {
 	  set req.http.foo = "AAA=";
 	  if (req.url == "/base64") {
 		set resp.http.bad64 = blob.encode(IDENTITY,
-		    blob=blob.decode(BASE64, "-_-_" + req.http.foo));
+		    blob=blob.decode(BASE64, encoded="-_-_" + req.http.foo));
 	  }
 	  elsif (req.url == "/base64url") {
 		set resp.http.badurl = blob.encode(IDENTITY,
-		    blob=blob.decode(BASE64URL, "+/+/" + req.http.foo));
+		    blob=blob.decode(BASE64URL, encoded="+/+/" + req.http.foo));
 	  }
 	  elsif (req.url == "/base64urlnopad") {
 		set resp.http.badpad = blob.encode(IDENTITY,
-		    blob=blob.decode(BASE64URLNOPAD, "TWFu" + req.http.foo));
+		    blob=blob.decode(BASE64URLNOPAD,
+		                     encoded="TWFu" + req.http.foo));
 	  }
 	}
 }
diff --git a/bin/varnishtest/tests/m00038.vtc b/bin/varnishtest/tests/m00038.vtc
index 4e7e334..a585981 100644
--- a/bin/varnishtest/tests/m00038.vtc
+++ b/bin/varnishtest/tests/m00038.vtc
@@ -1,4 +1,4 @@
-varnishtest "VMOD blob base64 decode_n()"
+varnishtest "VMOD blob base64 decode() n chars"
 
 varnish v1 -vcl {
 	import blob;
@@ -22,106 +22,105 @@ varnish v1 -vcl {
 
 	    set resp.http.dec
 	      = blob.encode(IDENTITY,
-			    blob=blob.decode_n(8, BASE64,
-						  req.http.foobarbazquux));
+			    blob=blob.decode(BASE64, 8,
+					     req.http.foobarbazquux));
 
 	    set resp.http.deceq
 	      = blob.encode(IDENTITY,
-			    blob=blob.decode_n(20, BASE64,
-						  req.http.foobarbazquux));
+			    blob=blob.decode(BASE64, 20,
+					     req.http.foobarbazquux));
 
 	    set resp.http.declong
 	      = blob.encode(IDENTITY,
-			    blob=blob.decode_n(30, BASE64,
-						  req.http.foobarbazquux));
+			    blob=blob.decode(BASE64, 30,
+					     req.http.foobarbazquux));
 
 	    set resp.http.dec2
 	      = blob.encode(IDENTITY,
-			    blob=blob.decode_n(12, BASE64, req.http.pangram));
+			    blob=blob.decode(BASE64, 12, req.http.pangram));
 
 	    set resp.http.b64dechobbes =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(24, BASE64, req.http.hobbes));
+			  blob=blob.decode(BASE64, 24, req.http.hobbes));
 
 	    set resp.http.b64decall =
-	       blob.encode(HEX, blob=blob.decode_n(128, BASE64, req.http.all));
+	       blob.encode(HEX, blob=blob.decode(BASE64, 128, req.http.all));
 
 	    set resp.http.urldechobbes =
-	      blob.encode(IDENTITY, blob=blob.decode_n(180, BASE64URL,
-							  req.http.hobbes));
+	      blob.encode(IDENTITY, blob=blob.decode(BASE64URL, 180,
+						     req.http.hobbes));
 
 	    set resp.http.urldecall =
-	      blob.encode(HEX,
-			      blob=blob.decode_n(256, BASE64URL,
+	      blob.encode(HEX, blob=blob.decode(BASE64URL, 256,
 						req.http.allurl));
 
 	    set resp.http.nopaddechobbes =
 	      blob.encode(IDENTITY,
-			      blob=blob.decode_n(500, BASE64URLNOPAD,
-						req.http.hobbesnopad));
+			      blob=blob.decode(BASE64URLNOPAD, 500,
+					       req.http.hobbesnopad));
 
 	    set resp.http.nopaddecall =
-	      blob.encode(HEX, blob=blob.decode_n(256, BASE64URLNOPAD,
+	      blob.encode(HEX, blob=blob.decode(BASE64URLNOPAD, 256,
 						  req.http.allurl));
 
 	    set resp.http.b64empty =
-	      blob.encode(IDENTITY, blob=blob.decode_n(0, BASE64, ""));
+	      blob.encode(IDENTITY, blob=blob.decode(BASE64, 0, ""));
 	    set resp.http.urlempty =
-	      blob.encode(IDENTITY, blob=blob.decode_n(1, BASE64URL, ""));
+	      blob.encode(IDENTITY, blob=blob.decode(BASE64URL, 1, ""));
 	    set resp.http.nopadempty =
 		blob.encode(IDENTITY,
-			    blob=blob.decode_n(0, BASE64URLNOPAD, ""));
+			    blob=blob.decode(BASE64URLNOPAD, 0, ""));
 	    set resp.http.emptypieces =
 	      blob.encode(IDENTITY,
-	      blob=blob.decode_n(0, BASE64, req.http.unset + "" + req.http.unset
+	      blob=blob.decode(BASE64, 0, req.http.unset + "" + req.http.unset
 					   + "" + req.http.unset + ""));
 
 	    set resp.http.decenc
 	      = blob.encode(BASE64,
-			    blob=blob.decode_n(20, BASE64,
-						  req.http.foobarbazquux));
+			    blob=blob.decode(BASE64, 20,
+					     req.http.foobarbazquux));
 
 	    set resp.http.l = "L";
 	    set resp.http.dec2pieces
-	      = blob.encode(IDENTITY, blob=blob.decode_n(8, BASE64,
+	      = blob.encode(IDENTITY, blob=blob.decode(BASE64, 8,
 				resp.http.l + "0hlbGxvIHdvcmxkLw=="));
 
 	    set resp.http.pad = "==";
 	    set resp.http.dec3pieces
-	      = blob.encode(IDENTITY, blob=blob.decode_n(12, BASE64,
+	      = blob.encode(IDENTITY, blob=blob.decode(BASE64, 12,
 				resp.http.l + "0hlbGxvIHdvcmxkLw"
 				+ resp.http.pad));
 
 	    set resp.http.mid1 = "GxvI";
 	    set resp.http.mid2 = "dvcmx";
 	    set resp.http.dec7pieces
-	      = blob.encode(IDENTITY, blob=blob.decode_n(16, BASE64,
+	      = blob.encode(IDENTITY, blob=blob.decode(BASE64, 16,
 				resp.http.l + "0hlb" + resp.http.mid1
 				+ "H" + resp.http.mid2 + "kLw"
 				+ resp.http.pad));
 
 	    set resp.http.dec7param
-	      = blob.encode(blob=blob.decode_n(encoded=resp.http.l
+	      = blob.encode(blob=blob.decode(encoded=resp.http.l
 				+ "0hlb" + resp.http.mid1 + "H" + resp.http.mid2
-				+ "kLw" + resp.http.pad, decoding=BASE64, n=20),
-				encoding=IDENTITY);
+				+ "kLw" + resp.http.pad, decoding=BASE64,
+				length=20), encoding=IDENTITY);
 
 	    set resp.http.decnopad = blob.encode(IDENTITY,
-				     blob=blob.decode_n(18, BASE64URLNOPAD,
-						        "L0hlbGxvIHdvcmxkLw"));
+				     blob=blob.decode(BASE64URLNOPAD, 18,
+						      "L0hlbGxvIHdvcmxkLw"));
 
 	    set resp.http.decnopad2pieces
-	      = blob.encode(IDENTITY, blob=blob.decode_n(19, BASE64URLNOPAD,
+	      = blob.encode(IDENTITY, blob=blob.decode(BASE64URLNOPAD, 19,
 				resp.http.l + "0hlbGxvIHdvcmxkLw"));
 
 	    set resp.http.decnopad6pieces
-	      = blob.encode(IDENTITY, blob=blob.decode_n(18, BASE64URLNOPAD,
+	      = blob.encode(IDENTITY, blob=blob.decode(BASE64URLNOPAD, 18,
 				resp.http.l + "0hlb" + resp.http.mid1
 				+ "H" + resp.http.mid2 + "kLw"));
 
 	    set resp.http.decnopadlong
 	      = blob.encode(IDENTITY,
-		blob=blob.decode_n(60, BASE64URLNOPAD,
+		blob=blob.decode(BASE64URLNOPAD, 60,
 		"VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw"
 			       ));
 
@@ -170,16 +169,16 @@ varnish v1 -vcl+backend {
 	  set req.http.foo = "AAA=";
 	  if (req.url == "/base64") {
 		set resp.http.bad64 = blob.encode(IDENTITY,
-		    blob=blob.decode_n(8, BASE64, "-_-_" + req.http.foo));
+		    blob=blob.decode(BASE64, 8, "-_-_" + req.http.foo));
 	  }
 	  elsif (req.url == "/base64url") {
 		set resp.http.badurl = blob.encode(IDENTITY,
-		    blob=blob.decode_n(8, BASE64URL, "+/+/" + req.http.foo));
+		    blob=blob.decode(BASE64URL, 8, "+/+/" + req.http.foo));
 	  }
 	  elsif (req.url == "/base64urlnopad") {
 		set resp.http.badpad = blob.encode(IDENTITY,
-		    blob=blob.decode_n(8, BASE64URLNOPAD,
-				       "TWFu" + req.http.foo));
+		    blob=blob.decode(BASE64URLNOPAD, 8,
+				     "TWFu" + req.http.foo));
 	  }
 	}
 }
diff --git a/bin/varnishtest/tests/m00039.vtc b/bin/varnishtest/tests/m00039.vtc
index 440c7ed..2149585 100644
--- a/bin/varnishtest/tests/m00039.vtc
+++ b/bin/varnishtest/tests/m00039.vtc
@@ -22,74 +22,92 @@ varnish v1 -vcl {
 {"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="};
 
 	    set resp.http.url =
-	      blob.encode(URL, blob=blob.decode(IDENTITY, req.http.pangram));
+	      blob.encode(URL, blob=blob.decode(IDENTITY,
+	                                        encoded=req.http.pangram));
 
 	    set resp.http.urllc =
-	      blob.encode(URL, LOWER, blob.decode(IDENTITY, req.http.pangram));
+	      blob.encode(URL, LOWER, blob.decode(IDENTITY,
+	                                          encoded=req.http.pangram));
 
 	    set resp.http.urluc =
-	      blob.encode(URL, UPPER, blob.decode(IDENTITY, req.http.pangram));
+	      blob.encode(URL, UPPER, blob.decode(IDENTITY,
+	                                          encoded=req.http.pangram));
 
 	    set resp.http.hobbes =
-	      blob.encode(URL, blob=blob.decode(IDENTITY, req.http.hobbes));
+	      blob.encode(URL, blob=blob.decode(IDENTITY,
+	                                        encoded=req.http.hobbes));
 
 	    set resp.http.hobbeslc =
-	      blob.encode(URL, LOWER, blob.decode(IDENTITY, req.http.hobbes));
+	      blob.encode(URL, LOWER, blob.decode(IDENTITY,
+	                                          encoded=req.http.hobbes));
 
 	    set resp.http.hobbesuc =
-	      blob.encode(URL, UPPER, blob.decode(IDENTITY, req.http.hobbes));
+	      blob.encode(URL, UPPER, blob.decode(IDENTITY,
+	                                          encoded=req.http.hobbes));
 
 	    set resp.http.umlauts =
-	      blob.encode(URL, blob=blob.decode(IDENTITY, req.http.umlauts));
+	      blob.encode(URL, blob=blob.decode(IDENTITY,
+	                                        encoded=req.http.umlauts));
 
 	    set resp.http.umlautslc =
-	      blob.encode(URL, LOWER, blob.decode(IDENTITY, req.http.umlauts));
+	      blob.encode(URL, LOWER, blob.decode(IDENTITY,
+	                                          encoded=req.http.umlauts));
 
 	    set resp.http.umlautsuc =
-	      blob.encode(URL, UPPER, blob.decode(IDENTITY, req.http.umlauts));
+	      blob.encode(URL, UPPER, blob.decode(IDENTITY,
+	                                          encoded=req.http.umlauts));
 
 	    set resp.http.phk =
-	      blob.encode(URL, blob=blob.decode(IDENTITY, req.http.phkspeak));
+	      blob.encode(URL, blob=blob.decode(IDENTITY,
+	                                        encoded=req.http.phkspeak));
 
 	    set resp.http.phklc =
-	      blob.encode(URL, LOWER, blob.decode(IDENTITY, req.http.phkspeak));
+	      blob.encode(URL, LOWER, blob.decode(IDENTITY,
+	                                          encoded=req.http.phkspeak));
 
 	    set resp.http.phkuc =
-	      blob.encode(URL, UPPER, blob.decode(IDENTITY, req.http.phkspeak));
+	      blob.encode(URL, UPPER, blob.decode(IDENTITY,
+	                                          encoded=req.http.phkspeak));
 
 	    set resp.http.utf8 =
-	      blob.encode(URL, blob=blob.decode(IDENTITY, req.http.utf8));
+	      blob.encode(URL, blob=blob.decode(IDENTITY,
+	                                        encoded=req.http.utf8));
 
 	    set resp.http.utf8lc =
-	      blob.encode(URL, LOWER, blob.decode(IDENTITY, req.http.utf8));
+	      blob.encode(URL, LOWER, blob.decode(IDENTITY,
+	                                          encoded=req.http.utf8));
 
 	    set resp.http.utf8uc =
-	      blob.encode(URL, UPPER, blob.decode(IDENTITY, req.http.utf8));
+	      blob.encode(URL, UPPER, blob.decode(IDENTITY,
+	                                          encoded=req.http.utf8));
 
 	    set resp.http.all =
-	      blob.encode(URL, blob=blob.decode(BASE64, req.http.b64all));
+	      blob.encode(URL, blob=blob.decode(BASE64,
+	                                        encoded=req.http.b64all));
 
 	    set resp.http.all-lc =
-	      blob.encode(URL, LOWER, blob.decode(BASE64, req.http.b64all));
+	      blob.encode(URL, LOWER, blob.decode(BASE64,
+	                                          encoded=req.http.b64all));
 
 	    set resp.http.all-uc =
-	      blob.encode(URL, UPPER, blob.decode(BASE64, req.http.b64all));
+	      blob.encode(URL, UPPER, blob.decode(BASE64,
+	                                          encoded=req.http.b64all));
 
 	    set resp.http.empty =
-	      blob.encode(URL, blob=blob.decode(IDENTITY, ""));
+	      blob.encode(URL, blob=blob.decode(IDENTITY, encoded=""));
 
 	    set resp.http.empty-lc =
-	      blob.encode(URL, LOWER, blob.decode(IDENTITY, ""));
+	      blob.encode(URL, LOWER, blob.decode(IDENTITY, encoded=""));
 
 	    set resp.http.empty-uc =
-	      blob.encode(URL, UPPER, blob.decode(IDENTITY, ""));
+	      blob.encode(URL, UPPER, blob.decode(IDENTITY, encoded=""));
 
 	    set resp.http.urllcparam =
-	      blob.encode(blob=blob.decode(IDENTITY, req.http.pangram),
+	      blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
 			  encoding=URL, case=LOWER);
 
 	    set resp.http.urlucparam =
-	      blob.encode(blob=blob.decode(IDENTITY, req.http.pangram),
+	      blob.encode(blob=blob.decode(IDENTITY, encoded=req.http.pangram),
 			  encoding=URL, case=UPPER);
 	}
 } -start
@@ -148,69 +166,73 @@ varnish v1 -vcl {
 
 	    set resp.http.decuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urlucfoobar));
+			  blob=blob.decode(URL, encoded=req.http.urlucfoobar));
 
 	    set resp.http.declc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urllcfoobar));
+			  blob=blob.decode(URL, encoded=req.http.urllcfoobar));
 
 	    set resp.http.decmixed =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urlmixedfoobar));
+			  blob=blob.decode(URL,
+			                   encoded=req.http.urlmixedfoobar));
 
 	    set resp.http.dechobbesuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urlhobbesuc));
+			  blob=blob.decode(URL, encoded=req.http.urlhobbesuc));
 
 	    set resp.http.dechobbeslc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urlhobbeslc));
+			  blob=blob.decode(URL, encoded=req.http.urlhobbeslc));
 
 	    set resp.http.decumlautsuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urlucumlauts));
+			  blob=blob.decode(URL, encoded=req.http.urlucumlauts));
 
 	    set resp.http.decumlautslc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urllcumlauts));
+			  blob=blob.decode(URL, encoded=req.http.urllcumlauts));
 
 	    set resp.http.decphkuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urlucphk));
+			  blob=blob.decode(URL, encoded=req.http.urlucphk));
 
 	    set resp.http.decphklc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urllcphk));
+			  blob=blob.decode(URL, encoded=req.http.urllcphk));
 
 	    set resp.http.decutf8uc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urlucutf8));
+			  blob=blob.decode(URL, encoded=req.http.urlucutf8));
 
 	    set resp.http.decutf8lc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.urllcutf8));
+			  blob=blob.decode(URL, encoded=req.http.urllcutf8));
 
 	    set resp.http.decalluc =
-	      blob.encode(BASE64, blob=blob.decode(URL, req.http.urlalluc));
+	      blob.encode(BASE64, blob=blob.decode(URL,
+	                                           encoded=req.http.urlalluc));
 
 	    set resp.http.decalllc =
-	      blob.encode(BASE64, blob=blob.decode(URL, req.http.urlalllc));
+	      blob.encode(BASE64, blob=blob.decode(URL,
+	                                           encoded=req.http.urlalllc));
 
 	    set resp.http.decempty =
-	      blob.encode(IDENTITY, blob=blob.decode(URL, ""));
+	      blob.encode(IDENTITY, blob=blob.decode(URL, encoded=""));
 
 	    set resp.http.decemptybyte =
-	      blob.encode(IDENTITY, blob=blob.decode(URL, "%00"));
+	      blob.encode(IDENTITY, blob=blob.decode(URL, encoded="%00"));
 
 	    set resp.http.decemptypieces =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode(URL, req.http.unset + ""
+			  blob=blob.decode(URL, encoded=req.http.unset + ""
 						   + req.http.unset + ""));
 
 	    set req.http.part1 = "foo%";
 	    set resp.http.dec2pieces =
-	      blob.encode(IDENTITY, blob=blob.decode(URL, req.http.part1 +
-			     "20bar%20baz%20quux"));
+	      blob.encode(IDENTITY, blob=blob.decode(URL,
+	                                             encoded=req.http.part1 +
+			                                 "20bar%20baz%20quux"));
 
 	    set req.http.part2 = "0quux";
 	    set resp.http.dec3param =
@@ -220,11 +242,12 @@ varnish v1 -vcl {
 			      encoding=IDENTITY);
 
 	    set resp.http.dec3pieces =
-	      blob.encode(IDENTITY, blob=blob.decode(URL, req.http.part1 +
-			      "20bar%20baz%2" + req.http.part2));
+	      blob.encode(IDENTITY, blob=blob.decode(URL, encoded=
+	                  req.http.part1 + "20bar%20baz%2" + req.http.part2));
 
 	    set resp.http.decmanypieces =
-	      blob.encode(IDENTITY, blob=blob.decode(URL, "" + req.http.unset
+	      blob.encode(IDENTITY, blob=blob.decode(URL, encoded=
+	                     "" + req.http.unset
 			     + req.http.part1 + req.http.unset + ""
 			     + req.http.unset + "" + "20bar%20baz%2"
 			     + "" + req.http.unset + req.http.part2
@@ -270,19 +293,20 @@ varnish v1 -vcl+backend {
 	sub vcl_deliver {
 		if (req.url == "/percent") {
 			set resp.http.bad
-			    = blob.encode(URL, UPPER, blob.decode(URL, "%"));
+			    = blob.encode(URL, UPPER, blob.decode(URL,
+			                                          encoded="%"));
 		}
 		elsif (req.url == "/percent-two") {
 			set resp.http.bad = blob.encode(URL, UPPER,
-					    blob.decode(URL, "%2"));
+					    blob.decode(URL, encoded="%2"));
 		}
 		elsif (req.url == "/percent-q") {
 			set resp.http.bad = blob.encode(URL, UPPER,
-					    blob.decode(URL, "%q"));
+					    blob.decode(URL, encoded="%q"));
 		}
 		elsif (req.url == "/percent-two-q") {
 			set resp.http.bad = blob.encode(URL, UPPER,
-					    blob.decode(URL, "%2q"));
+					    blob.decode(URL, encoded="%2q"));
 		}
 	}
 }
diff --git a/bin/varnishtest/tests/m00040.vtc b/bin/varnishtest/tests/m00040.vtc
index 2355ca9..2177f8a 100644
--- a/bin/varnishtest/tests/m00040.vtc
+++ b/bin/varnishtest/tests/m00040.vtc
@@ -1,4 +1,4 @@
-varnishtest "VMOD blob decode_n() with URL"
+varnishtest "VMOD blob decode() n chars with URL"
 
 varnish v1 -vcl {
 	import blob;
@@ -25,85 +25,85 @@ varnish v1 -vcl {
 
 	    set resp.http.decuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(9, URL, req.http.urlucfoobar));
+			  blob=blob.decode(URL, 9, req.http.urlucfoobar));
 
 	    set resp.http.declc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(12, URL, req.http.urllcfoobar));
+			  blob=blob.decode(URL, 12, req.http.urllcfoobar));
 
 	    set resp.http.dechobbesuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(27, URL, req.http.urlhobbesuc));
+			  blob=blob.decode(URL, 27, req.http.urlhobbesuc));
 
 	    set resp.http.dechobbeslc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(27, URL, req.http.urlhobbeslc));
+			  blob=blob.decode(URL, 27, req.http.urlhobbeslc));
 
 	    set resp.http.decumlautsuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(17, URL, req.http.urlucumlauts));
+			  blob=blob.decode(URL, 17, req.http.urlucumlauts));
 
 	    set resp.http.decumlautslc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(25, URL, req.http.urllcumlauts));
+			  blob=blob.decode(URL, 25, req.http.urllcumlauts));
 
 	    set resp.http.decphkuc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(18, URL, req.http.urlucphk));
+			  blob=blob.decode(URL, 18, req.http.urlucphk));
 
 	    set resp.http.decphklc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(30, URL, req.http.urllcphk));
+			  blob=blob.decode(URL, 30, req.http.urllcphk));
 
 	    set resp.http.decutf8uc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(9, URL, req.http.urlucutf8));
+			  blob=blob.decode(URL, 9, req.http.urlucutf8));
 
 	    set resp.http.decutf8lc =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(18, URL, req.http.urllcutf8));
+			  blob=blob.decode(URL, 18, req.http.urllcutf8));
 
 	    set resp.http.decalluc =
 	      blob.encode(HEX,
-			  blob=blob.decode_n(252, URL, req.http.urlalluc));
+			  blob=blob.decode(URL, 252, req.http.urlalluc));
 
 	    set resp.http.decalllc =
 	      blob.encode(HEX, UPPER,
-			  blob.decode_n(252, URL, req.http.urlalllc));
+			  blob.decode(URL, 252, req.http.urlalllc));
 
 	    set resp.http.decempty =
-	      blob.encode(IDENTITY, blob=blob.decode_n(10, URL, ""));
+	      blob.encode(IDENTITY, blob=blob.decode(URL, 10, ""));
 
 	    set resp.http.decemptybyte =
-	      blob.encode(IDENTITY, blob=blob.decode_n(3, URL, "%00"));
+	      blob.encode(IDENTITY, blob=blob.decode(URL, 3, "%00"));
 
 	    set resp.http.decemptypieces =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(1, URL, req.http.unset + ""
-							+ req.http.unset + ""));
+			  blob=blob.decode(URL, 1, req.http.unset + ""
+						   + req.http.unset + ""));
 
 	    set req.http.part1 = "foo%";
 	    set resp.http.dec2pieces =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(6, URL, req.http.part1 +
-							"20bar%20baz%20quux"));
+			  blob=blob.decode(URL, 6, req.http.part1 +
+						   "20bar%20baz%20quux"));
 
 	    set req.http.part2 = "0quux";
 	    set resp.http.dec3param =
-	      blob.encode(blob=blob.decode_n(encoded=req.http.part1 +
+	      blob.encode(blob=blob.decode(encoded=req.http.part1 +
 			      "20bar%20baz%2" + req.http.part2,
-			      decoding=URL, n=12),
+			      decoding=URL, length=12),
 			      encoding=IDENTITY);
 
 	    set resp.http.dec3pieces =
 	      blob.encode(IDENTITY,
-			  blob=blob.decode_n(18, URL, req.http.part1
-						+ "20bar%20baz%2"
-						+ req.http.part2));
+			  blob=blob.decode(URL, 18, req.http.part1
+						    + "20bar%20baz%2"
+						    + req.http.part2));
 
 	    set resp.http.decmanypieces =
 	      blob.encode(IDENTITY,
-			      blob=blob.decode_n(24, URL, "" + req.http.unset
+			      blob=blob.decode(URL, 24, "" + req.http.unset
 			      + req.http.part1 + req.http.unset + ""
 			      + req.http.unset + "" + "20bar%20baz%2"
 			      + "" + req.http.unset + req.http.part2
@@ -148,19 +148,19 @@ varnish v1 -vcl+backend {
 	sub vcl_deliver {
 		if (req.url == "/percent") {
 			set resp.http.bad = blob.encode(URL, UPPER,
-					    blob.decode_n(1, URL, "%20"));
+					    blob.decode(URL, 1, "%20"));
 		}
 		elsif (req.url == "/percent-two") {
 			set resp.http.bad = blob.encode(URL, UPPER,
-					    blob.decode_n(2, URL, "%20"));
+					    blob.decode(URL, 2, "%20"));
 		}
 		elsif (req.url == "/comma") {
 			set resp.http.good = blob.encode(IDENTITY, blob=
-					     blob.decode_n(3, URL, "%2c%q"));
+					     blob.decode(URL, 3, "%2c%q"));
 		}
 		elsif (req.url == "/colon") {
 			set resp.http.good = blob.encode(IDENTITY, blob=
-					     blob.decode_n(3, URL, "%3a%2q"));
+					     blob.decode(URL, 3, "%3a%2q"));
 		}
 	}
 }
diff --git a/bin/varnishtest/tests/m00041.vtc b/bin/varnishtest/tests/m00041.vtc
index cfed6ae..4056d9c 100644
--- a/bin/varnishtest/tests/m00041.vtc
+++ b/bin/varnishtest/tests/m00041.vtc
@@ -39,19 +39,19 @@ varnish v1 -arg "-p workspace_client=256k" -vcl {
 	    = blob.transcode(IDENTITY, HEX, encoded=req.http.hobbes);
 
 	  set resp.http.id2hexuc
-	    = blob.transcode(IDENTITY, HEX, UPPER, req.http.hobbes);
+	    = blob.transcode(IDENTITY, HEX, UPPER, encoded=req.http.hobbes);
 
 	  set resp.http.id2hexlc
-	    = blob.transcode(IDENTITY, HEX, LOWER, req.http.hobbes);
+	    = blob.transcode(IDENTITY, HEX, LOWER, encoded=req.http.hobbes);
 
 	  set resp.http.id2url
 	    = blob.transcode(IDENTITY, URL, encoded=req.http.foobar);
 
 	  set resp.http.id2urluc
-	    = blob.transcode(IDENTITY, URL, UPPER, req.http.foobar);
+	    = blob.transcode(IDENTITY, URL, UPPER, encoded=req.http.foobar);
 
 	  set resp.http.id2urllc
-	    = blob.transcode(IDENTITY, URL, LOWER, req.http.foobar);
+	    = blob.transcode(IDENTITY, URL, LOWER, encoded=req.http.foobar);
 
 	  set resp.http.b642id
 	    = blob.transcode(BASE64, IDENTITY, encoded=req.http.hobbesb64);
@@ -81,19 +81,19 @@ varnish v1 -arg "-p workspace_client=256k" -vcl {
 	    = blob.transcode(HEX, URL, encoded=req.http.hexalldown);
 
 	  set resp.http.hexalldown2urluc
-	    = blob.transcode(HEX, URL, UPPER, req.http.hexalldown);
+	    = blob.transcode(HEX, URL, UPPER, encoded=req.http.hexalldown);
 
 	  set resp.http.hexalldown2urllc
-	    = blob.transcode(HEX, URL, LOWER, req.http.hexalldown);
+	    = blob.transcode(HEX, URL, LOWER, encoded=req.http.hexalldown);
 
 	  set resp.http.hexallup2url
 	    = blob.transcode(HEX, URL, encoded=req.http.hexallup);
 
 	  set resp.http.hexallup2urluc
-	    = blob.transcode(HEX, URL, UPPER, req.http.hexallup);
+	    = blob.transcode(HEX, URL, UPPER, encoded=req.http.hexallup);
 
 	  set resp.http.hexallup2urllc
-	    = blob.transcode(HEX, URL, LOWER, req.http.hexallup);
+	    = blob.transcode(HEX, URL, LOWER, encoded=req.http.hexallup);
 
 	}
 } -start
@@ -155,64 +155,64 @@ varnish v1 -vcl {
 	    = blob.transcode(BASE64, HEX, encoded=req.http.b64all);
 
 	  set resp.http.b64all2hexuc
-	    = blob.transcode(BASE64, HEX, UPPER, req.http.b64all);
+	    = blob.transcode(BASE64, HEX, UPPER, encoded=req.http.b64all);
 
 	  set resp.http.b64all2hexlc
-	    = blob.transcode(BASE64, HEX, LOWER, req.http.b64all);
+	    = blob.transcode(BASE64, HEX, LOWER, encoded=req.http.b64all);
 
 	  set resp.http.b64allurl2hex
 	    = blob.transcode(BASE64URL, HEX, encoded=req.http.b64allurl);
 
 	  set resp.http.b64allurl2hexuc
-	    = blob.transcode(BASE64URL, HEX, UPPER, req.http.b64allurl);
+	    = blob.transcode(BASE64URL, HEX, UPPER, encoded=req.http.b64allurl);
 
 	  set resp.http.b64allurl2hexlc
-	    = blob.transcode(BASE64URL, HEX, LOWER, req.http.b64allurl);
+	    = blob.transcode(BASE64URL, HEX, LOWER, encoded=req.http.b64allurl);
 
 	  set resp.http.b64all2url
 	    = blob.transcode(BASE64, URL, encoded=req.http.b64all);
 
 	  set resp.http.b64all2urluc
-	    = blob.transcode(BASE64, URL, UPPER, req.http.b64all);
+	    = blob.transcode(BASE64, URL, UPPER, encoded=req.http.b64all);
 
 	  set resp.http.b64all2urllc
-	    = blob.transcode(BASE64, URL, LOWER, req.http.b64all);
+	    = blob.transcode(BASE64, URL, LOWER, encoded=req.http.b64all);
 
 	  set resp.http.b64allurl2url
 	    = blob.transcode(BASE64URL, URL, encoded=req.http.b64allurl);
 
 	  set resp.http.b64allurl2urluc
-	    = blob.transcode(BASE64URL, URL, UPPER, req.http.b64allurl);
+	    = blob.transcode(BASE64URL, URL, UPPER, encoded=req.http.b64allurl);
 
 	  set resp.http.b64allurl2urllc
-	    = blob.transcode(BASE64URL, URL, LOWER, req.http.b64allurl);
+	    = blob.transcode(BASE64URL, URL, LOWER, encoded=req.http.b64allurl);
 
 	  set resp.http.hexuc2hex
 	    = blob.transcode(HEX, HEX, encoded="0123456789ABCDEF");
 
 	  set resp.http.hexuc2hexuc
-	    = blob.transcode(HEX, HEX, UPPER, "0123456789ABCDEF");
+	    = blob.transcode(HEX, HEX, UPPER, encoded="0123456789ABCDEF");
 
 	  set resp.http.hexlc2hexlc
-	    = blob.transcode(HEX, HEX, LOWER, "0123456789abcdef");
+	    = blob.transcode(HEX, HEX, LOWER, encoded="0123456789abcdef");
 
 	  set resp.http.hexlc2hex
 	    = blob.transcode(HEX, HEX, encoded="0123456789abcdef");
 
 	  set resp.http.hexuc2hexlc
-	    = blob.transcode(HEX, HEX, LOWER, "0123456789ABCDEF");
+	    = blob.transcode(HEX, HEX, LOWER, encoded="0123456789ABCDEF");
 
 	  set resp.http.hexlc2hexuc
-	    = blob.transcode(HEX, HEX, UPPER, "0123456789abcdef");
+	    = blob.transcode(HEX, HEX, UPPER, encoded="0123456789abcdef");
 
 	  set resp.http.hexmix2hex
 	    = blob.transcode(HEX, HEX, encoded="0123456789ABCdef");
 
 	  set resp.http.hexmix2hexuc
-	    = blob.transcode(HEX, HEX, UPPER, "0123456789ABCdef");
+	    = blob.transcode(HEX, HEX, UPPER, encoded="0123456789ABCdef");
 
 	  set resp.http.hexmix2hexlc
-	    = blob.transcode(HEX, HEX, LOWER, "0123456789abcDEF");
+	    = blob.transcode(HEX, HEX, LOWER, encoded="0123456789abcDEF");
 
 	  set req.http.hexpart1 = "01234567";
 	  set req.http.hexpart2 = "89abcdef";
@@ -336,37 +336,37 @@ varnish v1 -vcl {
 	    = blob.transcode(URL, URL, encoded=req.http.urlalldownuc);
 
 	  set resp.http.urlalldownuc2urllc
-	    = blob.transcode(URL, URL, LOWER, req.http.urlalldownuc);
+	    = blob.transcode(URL, URL, LOWER, encoded=req.http.urlalldownuc);
 
 	  set resp.http.urlalldownuc2urluc
-	    = blob.transcode(URL, URL, UPPER, req.http.urlalldownuc);
+	    = blob.transcode(URL, URL, UPPER, encoded=req.http.urlalldownuc);
 
 	  set resp.http.urlalldownlc2url
 	    = blob.transcode(URL, URL, encoded=req.http.urlalldownlc);
 
 	  set resp.http.urlalldownlc2urllc
-	    = blob.transcode(URL, URL, LOWER, req.http.urlalldownlc);
+	    = blob.transcode(URL, URL, LOWER, encoded=req.http.urlalldownlc);
 
 	  set resp.http.urlalldownlc2urluc
-	    = blob.transcode(URL, URL, UPPER, req.http.urlalldownlc);
+	    = blob.transcode(URL, URL, UPPER, encoded=req.http.urlalldownlc);
 
 	  set resp.http.urlallupuc2url
 	    = blob.transcode(URL, URL, encoded=req.http.urlallupuc);
 
 	  set resp.http.urlallupuc2urluc
-	    = blob.transcode(URL, URL, UPPER, req.http.urlallupuc);
+	    = blob.transcode(URL, URL, UPPER, encoded=req.http.urlallupuc);
 
 	  set resp.http.urlallupuc2urllc
-	    = blob.transcode(URL, URL, LOWER, req.http.urlallupuc);
+	    = blob.transcode(URL, URL, LOWER, encoded=req.http.urlallupuc);
 
 	  set resp.http.urlalluplc2url
 	    = blob.transcode(URL, URL, encoded=req.http.urlalluplc);
 
 	  set resp.http.urlalluplc2urluc
-	    = blob.transcode(URL, URL, UPPER, req.http.urlalluplc);
+	    = blob.transcode(URL, URL, UPPER, encoded=req.http.urlalluplc);
 
 	  set resp.http.urlalluplc2urllc
-	    = blob.transcode(URL, URL, LOWER, req.http.urlalluplc);
+	    = blob.transcode(URL, URL, LOWER, encoded=req.http.urlalluplc);
 
 	  }
 }
diff --git a/bin/varnishtest/tests/m00042.vtc b/bin/varnishtest/tests/m00042.vtc
index 4a96c0f..ecd8b44 100644
--- a/bin/varnishtest/tests/m00042.vtc
+++ b/bin/varnishtest/tests/m00042.vtc
@@ -1,4 +1,4 @@
-varnishtest "VMOD blob test transcode_n()"
+varnishtest "VMOD blob test transcode() n chars"
 
 varnish v1 -vcl {
 	import blob;
@@ -22,76 +22,83 @@ varnish v1 -vcl {
 {"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"};
 
 	  set resp.http.id2id
-	    = blob.transcode_n(5, IDENTITY, IDENTITY, encoded="Hello world");
+	    = blob.transcode(IDENTITY, IDENTITY, length=5,
+	                     encoded="Hello world");
 
 	  set resp.http.id2b64
-	    = blob.transcode_n(5, IDENTITY, BASE64, encoded=req.http.hobbes);
+	    = blob.transcode(IDENTITY, BASE64, length=5,
+	                     encoded=req.http.hobbes);
 
 	  set resp.http.id2b64nopad
-	    = blob.transcode_n(5, IDENTITY, BASE64URLNOPAD,
-	                       encoded=req.http.hobbes);
+	    = blob.transcode(IDENTITY, BASE64URLNOPAD, length=5,
+	                     encoded=req.http.hobbes);
 
 	  set resp.http.id2hex
-	    = blob.transcode_n(5, IDENTITY, HEX, encoded=req.http.hobbes);
+	    = blob.transcode(IDENTITY, HEX, length=5, encoded=req.http.hobbes);
 
 	  set resp.http.id2hexuc
-	    = blob.transcode_n(5, IDENTITY, HEX, UPPER, req.http.hobbes);
+	    = blob.transcode(IDENTITY, HEX, UPPER, 5, req.http.hobbes);
 
 	  set resp.http.id2hexlc
-	    = blob.transcode_n(5, IDENTITY, HEX, LOWER, req.http.hobbes);
+	    = blob.transcode(IDENTITY, HEX, LOWER, 5, req.http.hobbes);
 
 	  set resp.http.id2url
-	    = blob.transcode_n(5, IDENTITY, URL, encoded=req.http.foobar);
+	    = blob.transcode(IDENTITY, URL, length=5, encoded=req.http.foobar);
 
 	  set resp.http.id2urluc
-	    = blob.transcode_n(5, IDENTITY, URL, UPPER, req.http.foobar);
+	    = blob.transcode(IDENTITY, URL, UPPER, 5, req.http.foobar);
 
 	  set resp.http.id2urllc
-	    = blob.transcode_n(5, IDENTITY, URL, LOWER, req.http.foobar);
+	    = blob.transcode(IDENTITY, URL, LOWER, 5, req.http.foobar);
 
 	  set resp.http.b642id
-	    = blob.transcode_n(8, BASE64, IDENTITY, encoded=req.http.hobbesb64);
+	    = blob.transcode(BASE64, IDENTITY, length=8,
+	                     encoded=req.http.hobbesb64);
 
 	  set resp.http.hex2id
-	    = blob.transcode_n(12, HEX, IDENTITY, encoded=req.http.hexhobbes);
+	    = blob.transcode(HEX, IDENTITY, length=12,
+	                     encoded=req.http.hexhobbes);
 
 	  set resp.http.hexalldown2b64
-	    = blob.transcode_n(12, HEX, BASE64, encoded=req.http.hexalldown);
+	    = blob.transcode(HEX, BASE64, length=12,
+	                     encoded=req.http.hexalldown);
 
 	  set resp.http.hexalldown2b64url
-	    = blob.transcode_n(12, HEX, BASE64URL, encoded=req.http.hexalldown);
+	    = blob.transcode(HEX, BASE64URL, length=12,
+	                     encoded=req.http.hexalldown);
 
 	  set resp.http.hexalldown2b64nopad
-	    = blob.transcode_n(10, HEX, BASE64URLNOPAD,
-	                       encoded=req.http.hexalldown);
+	    = blob.transcode(HEX, BASE64URLNOPAD, length=10,
+	                     encoded=req.http.hexalldown);
 
 	  set resp.http.hexallup2b64
-	    = blob.transcode_n(12, HEX, BASE64, encoded=req.http.hexallup);
+	    = blob.transcode(HEX, BASE64, length=12, encoded=req.http.hexallup);
 
 	  set resp.http.hexallup2b64url
-	    = blob.transcode_n(10, HEX, BASE64URL, encoded=req.http.hexallup);
+	    = blob.transcode(HEX, BASE64URL, length=10,
+	                     encoded=req.http.hexallup);
 
 	  set resp.http.hexallup2b64nopad
-	    = blob.transcode_n(10, HEX, BASE64URLNOPAD,
-	                       encoded=req.http.hexallup);
+	    = blob.transcode(HEX, BASE64URLNOPAD, length=10,
+	                     encoded=req.http.hexallup);
 
 	  set resp.http.hexalldown2url
-	    = blob.transcode_n(12, HEX, URL, encoded=req.http.hexalldown);
+	    = blob.transcode(HEX, URL, length=12, encoded=req.http.hexalldown);
 
 	  set resp.http.hexalldown2urluc
-	    = blob.transcode_n(12, HEX, URL, UPPER, req.http.hexalldown);
+	    = blob.transcode(HEX, URL, UPPER, 12, req.http.hexalldown);
 
 	  set resp.http.hexalldown2urllc
-	    = blob.transcode_n(12, HEX, URL, LOWER, req.http.hexalldown);
+	    = blob.transcode(HEX, URL, LOWER, 12, req.http.hexalldown);
 
 	  set resp.http.hexallup2url
-	    = blob.transcode_n(12, HEX, URL, encoded=req.http.hexallup);
+	    = blob.transcode(HEX, URL, length=12, encoded=req.http.hexallup);
 
 	  set resp.http.hexallup2urluc
-	    = blob.transcode_n(12, HEX, URL, UPPER, req.http.hexallup);
+	    = blob.transcode(HEX, URL, UPPER, 12, req.http.hexallup);
 
 	  set resp.http.hexallup2urllc
-	    = blob.transcode_n(12, HEX, URL, LOWER, req.http.hexallup);
+	    = blob.transcode(HEX, URL, LOWER, 12, req.http.hexallup);
 
 	}
 } -start
@@ -140,89 +147,91 @@ varnish v1 -vcl {
 {"AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLLMMMMNNNNOOOOPPPPQQQQRRRRSSSSTTTTUUUUVVVVWWWWXXXXYYYYZZZZaaaabbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllllmmmmnnnnooooppppqqqqrrrrssssttttuuuuvvvvwwwwxxxxyyyyzzzz0000111122223333444455556666777788889999----____"};
 
 	  set resp.http.b64all2hex
-	    = blob.transcode_n(8, BASE64, HEX, encoded=req.http.b64all);
+	    = blob.transcode(BASE64, HEX, length=8, encoded=req.http.b64all);
 
 	  set resp.http.b64all2hexuc
-	    = blob.transcode_n(8, BASE64, HEX, UPPER, req.http.b64all);
+	    = blob.transcode(BASE64, HEX, UPPER, 8, req.http.b64all);
 
 	  set resp.http.b64all2hexlc
-	    = blob.transcode_n(8, BASE64, HEX, LOWER, req.http.b64all);
+	    = blob.transcode(BASE64, HEX, LOWER, 8, req.http.b64all);
 
 	  set resp.http.b64allurl2hex
-	    = blob.transcode_n(8, BASE64URL, HEX, encoded=req.http.b64allurl);
+	    = blob.transcode(BASE64URL, HEX, length=8,
+	                     encoded=req.http.b64allurl);
 
 	  set resp.http.b64allurl2hexuc
-	    = blob.transcode_n(8, BASE64URL, HEX, UPPER, req.http.b64allurl);
+	    = blob.transcode(BASE64URL, HEX, UPPER, 8, req.http.b64allurl);
 
 	  set resp.http.b64allurl2hexlc
-	    = blob.transcode_n(8, BASE64URL, HEX, LOWER, req.http.b64allurl);
+	    = blob.transcode(BASE64URL, HEX, LOWER, 8, req.http.b64allurl);
 
 	  set resp.http.b64all2url
-	    = blob.transcode_n(8, BASE64, URL, encoded=req.http.b64all);
+	    = blob.transcode(BASE64, URL, length=8, encoded=req.http.b64all);
 
 	  set resp.http.b64all2urluc
-	    = blob.transcode_n(8, BASE64, URL, UPPER, req.http.b64all);
+	    = blob.transcode(BASE64, URL, UPPER, 8, req.http.b64all);
 
 	  set resp.http.b64all2urllc
-	    = blob.transcode_n(8, BASE64, URL, LOWER, req.http.b64all);
+	    = blob.transcode(BASE64, URL, LOWER, 8, req.http.b64all);
 
 	  set resp.http.b64allurl2url
-	    = blob.transcode_n(8, BASE64URL, URL, encoded=req.http.b64allurl);
+	    = blob.transcode(BASE64URL, URL, length=8,
+	                     encoded=req.http.b64allurl);
 
 	  set resp.http.b64allurl2urluc
-	    = blob.transcode_n(8, BASE64URL, URL, UPPER, req.http.b64allurl);
+	    = blob.transcode(BASE64URL, URL, UPPER, 8, req.http.b64allurl);
 
 	  set resp.http.b64allurl2urllc
-	    = blob.transcode_n(8, BASE64URL, URL, LOWER, req.http.b64allurl);
+	    = blob.transcode(BASE64URL, URL, LOWER, 8, req.http.b64allurl);
 
 	  set resp.http.hexuc2hex
-	    = blob.transcode_n(10, HEX, HEX, encoded="0123456789ABCDEF");
+	    = blob.transcode(HEX, HEX, length=10, encoded="0123456789ABCDEF");
 
 	  set resp.http.hexuc2hexuc
-	    = blob.transcode_n(10, HEX, HEX, UPPER, "0123456789ABCDEF");
+	    = blob.transcode(HEX, HEX, UPPER, 10, "0123456789ABCDEF");
 
 	  set resp.http.hexlc2hex
-	    = blob.transcode_n(10, HEX, HEX, encoded="0123456789abcdef");
+	    = blob.transcode(HEX, HEX, length=10, encoded="0123456789abcdef");
 
 	  set resp.http.hexlc2hexlc
-	    = blob.transcode_n(10, HEX, HEX, LOWER, "0123456789abcdef");
+	    = blob.transcode(HEX, HEX, LOWER, 10, "0123456789abcdef");
 
 	  set resp.http.hexuc2hexlc
-	    = blob.transcode_n(9, HEX, HEX, LOWER, "0123456789ABCDEF");
+	    = blob.transcode(HEX, HEX, LOWER, 9, "0123456789ABCDEF");
 
 	  set resp.http.hexlc2hexuc
-	    = blob.transcode_n(9, HEX, HEX, UPPER, "0123456789abcdef");
+	    = blob.transcode(HEX, HEX, UPPER, 9, "0123456789abcdef");
 
 	  set resp.http.hexmix2hex
-	    = blob.transcode_n(13, HEX, HEX, encoded="0123456789abcDEF");
+	    = blob.transcode(HEX, HEX, length=13, encoded="0123456789abcDEF");
 
 	  set resp.http.hexmix2hexuc
-	    = blob.transcode_n(15, HEX, HEX, UPPER, "0123456789ABCdef");
+	    = blob.transcode(HEX, HEX, UPPER, 15, "0123456789ABCdef");
 
 	  set resp.http.hexmix2hexlc
-	    = blob.transcode_n(13, HEX, HEX, LOWER, "0123456789abcDEF");
+	    = blob.transcode(HEX, HEX, LOWER, 13, "0123456789abcDEF");
 
 	  set req.http.hexpart1 = "01234567";
 	  set req.http.hexpart2 = "89abcdef";
 	  set resp.http.hexparam
-	    = blob.transcode_n(encoded="" + req.http.unset + ""
+	    = blob.transcode(encoded="" + req.http.unset + ""
 				   + req.http.unset + "" + req.http.hexpart1
 				   + "" + req.http.unset + "" + req.http.unset
 				   + req.http.hexpart2, decoding=HEX,
-				   encoding=HEX, n=10, case=UPPER);
+				   encoding=HEX, length=10, case=UPPER);
 
 	  set resp.http.b642b64
-	    = blob.transcode_n(36, BASE64, BASE64, encoded=
+	    = blob.transcode(BASE64, BASE64, length=36, encoded=
 				   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
 				   + "ghijklmnopqrstuvwxyz0123456789+/");
 
 	  set resp.http.b64url2b64url =
-	    blob.transcode_n(34, BASE64URL, BASE64URL, encoded=
+	    blob.transcode(BASE64URL, BASE64URL, length=34, encoded=
 				 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
 				 + "ghijklmnopqrstuvwxyz0123456789-_");
 
 	  set resp.http.b64urlnopad2b64urlnopad =
-	    blob.transcode_n(34, BASE64URLNOPAD, BASE64URLNOPAD, encoded=
+	    blob.transcode(BASE64URLNOPAD, BASE64URLNOPAD, length=34, encoded=
 				 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
 				 + "ghijklmnopqrstuvwxyz0123456789-_");
 
@@ -276,88 +285,98 @@ varnish v1 -vcl {
 	    set req.http.urlalldownlc = "%ff%fe%fd%fc%fb%fa%f9%f8%f7%f6%f5%f4%f3%f2%f1%f0%ef%ee%ed%ec%eb%ea%e9%e8%e7%e6%e5%e4%e3%e2%e1%e0%df%de%dd%dc%db%da%d9%d8%d7%d6%d5%d4%d3%d2%d1%d0%cf%ce%cd%cc%cb%ca%c9%c8%c7%c6%c5%c4%c3%c2%c1%c0%bf%be%bd%bc%bb%ba%b9%b8%b7%b6%b5%b4%b3%b2%b1%b0%af%ae%ad%ac%ab%aa%a9%a8%a7%a6%a5%a4%a3%a2%a1%a0%9f%9e%9d%9c%9b%9a%99%98%97%96%95%94%93%92%91%90%8f%8e%8d%8c%8b%8a%89%88%87%86%85%84%83%82%81%80%7f~%7d%7c%7bzyxwvutsrqponmlkjihgfedcba%60_%5e%5d%5c%5bZYXWVUTSRQPONMLKJIHGFEDCBA%40%3f%3e%3d%3c%3b%3a9876543210%2f.-%2c%2b%2a%29%28%27%26%25%24%23%22%21%20%1f%1e%1d%1c%1b%1a%19%18%17%16%15%14%13%12%11%10%0f%0e%0d%0c%0b%0a%09%08%07%06%05%04%03%02%01%00";
 
 	  set resp.http.urluc2id
-	    = blob.transcode_n(27, URL, IDENTITY, encoded=req.http.urlhobbesuc);
+	    = blob.transcode(URL, IDENTITY, length=27,
+	                     encoded=req.http.urlhobbesuc);
 
 	  set resp.http.urllc2id
-	    = blob.transcode_n(63, URL, IDENTITY, encoded=req.http.urlhobbeslc);
+	    = blob.transcode(URL, IDENTITY, length=63,
+	                     encoded=req.http.urlhobbeslc);
 
 	  set resp.http.urlalldownuc2b64
-	    = blob.transcode_n(18, URL, BASE64, encoded=req.http.urlalldownuc);
+	    = blob.transcode(URL, BASE64, length=18,
+	                     encoded=req.http.urlalldownuc);
 
 	  set resp.http.urlalldownuc2b64url
-	    = blob.transcode_n(15, URL, BASE64URL,
-	                       encoded=req.http.urlalldownuc);
+	    = blob.transcode(URL, BASE64URL, length=15,
+	                     encoded=req.http.urlalldownuc);
 
 	  set resp.http.urlalldownuc2b64nopad
-	    = blob.transcode_n(15, URL, BASE64URLNOPAD,
-			       encoded=req.http.urlalldownuc);
+	    = blob.transcode(URL, BASE64URLNOPAD, length=15,
+			     encoded=req.http.urlalldownuc);
 
 	  set resp.http.urlalldownlc2b64
-	    = blob.transcode_n(18, URL, BASE64, encoded=req.http.urlalldownlc);
+	    = blob.transcode(URL, BASE64, length=18,
+	                     encoded=req.http.urlalldownlc);
 
 	  set resp.http.urlalldownlc2b64url
-	    = blob.transcode_n(15, URL, BASE64URL,
-	                       encoded=req.http.urlalldownlc);
+	    = blob.transcode(URL, BASE64URL, length=15,
+	                     encoded=req.http.urlalldownlc);
 
 	  set resp.http.urlalldownlc2b64nopad
-	    = blob.transcode_n(15, URL, BASE64URLNOPAD,
-			       encoded=req.http.urlalldownlc);
+	    = blob.transcode(URL, BASE64URLNOPAD, length=15,
+			     encoded=req.http.urlalldownlc);
 
 	  set resp.http.urlallupuc2b64
-	    = blob.transcode_n(36, URL, BASE64, encoded=req.http.urlallupuc);
+	    = blob.transcode(URL, BASE64, length=36,
+	                     encoded=req.http.urlallupuc);
 
 	  set resp.http.urlallupuc2b64url
-	    = blob.transcode_n(33, URL, BASE64URL, encoded=req.http.urlallupuc);
+	    = blob.transcode(URL, BASE64URL, length=33,
+	                     encoded=req.http.urlallupuc);
 
 	  set resp.http.urlallupuc2b64nopad
-	    = blob.transcode_n(33, URL, BASE64URLNOPAD,
-			       encoded=req.http.urlallupuc);
+	    = blob.transcode(URL, BASE64URLNOPAD, length=33,
+			     encoded=req.http.urlallupuc);
 
 	  set resp.http.urlalluplc2b64
-	    = blob.transcode_n(36, URL, BASE64, encoded=req.http.urlalluplc);
+	    = blob.transcode(URL, BASE64, length=36,
+	                     encoded=req.http.urlalluplc);
 
 	  set resp.http.urlalluplc2b64url
-	    = blob.transcode_n(33, URL, BASE64URL, encoded=req.http.urlalluplc);
+	    = blob.transcode(URL, BASE64URL, length=33,
+	                     encoded=req.http.urlalluplc);
 
 	  set resp.http.urlalluplc2b64nopad
-	    = blob.transcode_n(33, URL, BASE64URLNOPAD,
-			       encoded=req.http.urlalluplc);
+	    = blob.transcode(URL, BASE64URLNOPAD, length=33,
+			     encoded=req.http.urlalluplc);
 
 	  set resp.http.urlalldownuc2url
-	    = blob.transcode_n(423, URL, URL, encoded=req.http.urlalldownuc);
+	    = blob.transcode(URL, URL, length=423,
+	                     encoded=req.http.urlalldownuc);
 
 	  set resp.http.urlalldownuc2urluc
-	    = blob.transcode_n(423, URL, URL, UPPER, req.http.urlalldownuc);
+	    = blob.transcode(URL, URL, UPPER, 423, req.http.urlalldownuc);
 
 	  set resp.http.urlalldownuc2urllc
-	    = blob.transcode_n(423, URL, URL, LOWER, req.http.urlalldownuc);
+	    = blob.transcode(URL, URL, LOWER, 423, req.http.urlalldownuc);
 
 	  set resp.http.urlalldownlc2url
-	    = blob.transcode_n(423, URL, URL, encoded=req.http.urlalldownlc);
+	    = blob.transcode(URL, URL, length=423,
+	                     encoded=req.http.urlalldownlc);
 
 	  set resp.http.urlalldownlc2urluc
-	    = blob.transcode_n(423, URL, URL, UPPER, req.http.urlalldownlc);
+	    = blob.transcode(URL, URL, UPPER, 423, req.http.urlalldownlc);
 
 	  set resp.http.urlalldownlc2urllc
-	    = blob.transcode_n(423, URL, URL, LOWER, req.http.urlalldownlc);
+	    = blob.transcode(URL, URL, LOWER, 423, req.http.urlalldownlc);
 
 	  set resp.http.urlallupuc2url
-	    = blob.transcode_n(197, URL, URL, encoded=req.http.urlallupuc);
+	    = blob.transcode(URL, URL, length=197, encoded=req.http.urlallupuc);
 
 	  set resp.http.urlallupuc2urluc
-	    = blob.transcode_n(197, URL, URL, UPPER, req.http.urlallupuc);
+	    = blob.transcode(URL, URL, UPPER, 197, req.http.urlallupuc);
 
 	  set resp.http.urlallupuc2urllc
-	    = blob.transcode_n(197, URL, URL, LOWER, req.http.urlallupuc);
+	    = blob.transcode(URL, URL, LOWER, 197, req.http.urlallupuc);
 
 	  set resp.http.urlalluplc2url
-	    = blob.transcode_n(197, URL, URL, encoded=req.http.urlalluplc);
+	    = blob.transcode(URL, URL, length=197, encoded=req.http.urlalluplc);
 
 	  set resp.http.urlalluplc2urluc
-	    = blob.transcode_n(197, URL, URL, UPPER, req.http.urlalluplc);
+	    = blob.transcode(URL, URL, UPPER, 197, req.http.urlalluplc);
 
 	  set resp.http.urlalluplc2urllc
-	    = blob.transcode_n(197, URL, URL, LOWER, req.http.urlalluplc);
+	    = blob.transcode(URL, URL, LOWER, 197, req.http.urlalluplc);
 
 	  }
 }
@@ -407,57 +426,59 @@ varnish v1 -vcl+backend {
 		set req.http.foo = "AAA=";
 		if (req.url == "/1") {
 			set resp.http.good
-			    = blob.transcode_n(3, URL, IDENTITY,
-			                       encoded="%2c%q");
+			    = blob.transcode(URL, IDENTITY, length=3,
+			                     encoded="%2c%q");
 		}
 		elsif (req.url == "/2") {
 			set resp.http.good
-			    = blob.transcode_n(3, URL, IDENTITY,
-			                       encoded="%3a%2q");
+			    = blob.transcode(URL, IDENTITY, length=3,
+			                     encoded="%3a%2q");
 		}
 		elsif (req.url == "/3") {
 			set resp.http.bad
-			    = blob.transcode_n(8, HEX, IDENTITY,
-					       encoded="0x123456");
+			    = blob.transcode(HEX, IDENTITY, length=8,
+					     encoded="0x123456");
 		}
 		elsif (req.url == "/4") {
 			set resp.http.bad
-			    = blob.transcode_n(4, BASE64, IDENTITY,
-					       encoded="-_-_" + req.http.foo);
+			    = blob.transcode(BASE64, IDENTITY, length=4,
+					     encoded="-_-_" + req.http.foo);
 		}
 		elsif (req.url == "/5") {
 			set resp.http.bad
-			    = blob.transcode_n(4, BASE64URL, IDENTITY,
-					       encoded="+/+/" + req.http.foo);
+			    = blob.transcode(BASE64URL, IDENTITY, length=4,
+					     encoded="+/+/" + req.http.foo);
 		}
 		elsif (req.url == "/6") {
 			set resp.http.bad
-			    = blob.transcode_n(8, BASE64URLNOPAD, IDENTITY,
-					       encoded="TWFu" + req.http.foo);
+			    = blob.transcode(BASE64URLNOPAD, IDENTITY, length=8,
+					     encoded="TWFu" + req.http.foo);
 		}
 		elsif (req.url == "/7") {
 			set resp.http.bad
-			    = blob.transcode_n(4, BASE64, BASE64,
-					       encoded="_-_-" + req.http.foo);
+			    = blob.transcode(BASE64, BASE64, length=4,
+					     encoded="_-_-" + req.http.foo);
 		}
 		elsif (req.url == "/8") {
 			set resp.http.bad
-			    = blob.transcode_n(4, BASE64URL, BASE64URL,
-					       encoded="/+/+" + req.http.foo);
+			    = blob.transcode(BASE64URL, BASE64URL, length=4,
+					     encoded="/+/+" + req.http.foo);
 		}
 		elsif (req.url == "/9") {
 			set resp.http.bad
-			    = blob.transcode_n(8, BASE64URLNOPAD,
-					       BASE64URLNOPAD,
-					       encoded="Zm9v" + req.http.foo);
+			    = blob.transcode(BASE64URLNOPAD,
+					     BASE64URLNOPAD, length=8,
+					     encoded="Zm9v" + req.http.foo);
 		}
 		elsif (req.url == "/10") {
 			set resp.http.bad
-			    = blob.transcode_n(1, URL, IDENTITY, encoded="%20");
+			    = blob.transcode(URL, IDENTITY, length=1,
+			                     encoded="%20");
 		}
 		elsif (req.url == "/11") {
 			set resp.http.bad
-			    = blob.transcode_n(2, URL, IDENTITY, encoded="%20");
+			    = blob.transcode(URL, IDENTITY, length=2,
+			                     encoded="%20");
 		}
 	}
 }
diff --git a/bin/varnishtest/tests/m00044.vtc b/bin/varnishtest/tests/m00044.vtc
index ba4b757..e68374a 100644
--- a/bin/varnishtest/tests/m00044.vtc
+++ b/bin/varnishtest/tests/m00044.vtc
@@ -29,7 +29,7 @@ varnish v1 -arg "-p http_max_hdr=128" -vcl+backend {
 	# vice versa at runtime.
 	set resp.http.Base64-Encoded
 	    = blob.encode(BASE64,
-			  blob=blob.decode(HEX, req.http.Hex-Encoded));
+			  blob=blob.decode(HEX, encoded=req.http.Hex-Encoded));
     }
 
     sub vcl_recv {
@@ -53,9 +53,10 @@ varnish v1 -arg "-p http_max_hdr=128" -vcl+backend {
     # IDENTITY
     sub vcl_deliver {
 	set resp.http.Trunced-Foo1
-	    = blob.encode(IDENTITY, blob=blob.decode(HEX, "666f6f00626172"));
+	    = blob.encode(IDENTITY, blob=blob.decode(HEX,
+	                                             encoded="666f6f00626172"));
 	set resp.http.Trunced-Foo2
-	    = blob.encode(blob=blob.decode(HEX, "666f6f00626172"));
+	    = blob.encode(blob=blob.decode(HEX, encoded="666f6f00626172"));
     }
 
     ############################################################
@@ -65,14 +66,15 @@ varnish v1 -arg "-p http_max_hdr=128" -vcl+backend {
 	set resp.http.Second = "def0";
 	set resp.http.Hex-Decoded = blob.encode(
 	    HEX,
-	    blob=blob.decode(HEX, resp.http.First + resp.http.Second));
+	    blob=blob.decode(HEX, encoded=resp.http.First + resp.http.Second));
     }
 
     ############################################################
     # encode - also contains decode examples
     sub vcl_deliver {
 	set resp.http.encode1
-	    = blob.encode(HEX, blob=blob.decode(BASE64, "Zm9vYmFyYmF6"));
+	    = blob.encode(HEX, blob=blob.decode(BASE64,
+	                                        encoded="Zm9vYmFyYmF6"));
 
 	# same with named parameters
 	set resp.http.encode2
@@ -108,7 +110,7 @@ varnish v1 -arg "-p http_max_hdr=128" -vcl+backend {
     ############################################################
     # blob init + .get + .encode
     sub vcl_init {
-	new theblob1 = blob.blob(BASE64, "YmxvYg==");
+	new theblob1 = blob.blob(BASE64, encoded="YmxvYg==");
 
 	# same with named arguments
 	new theblob2 = blob.blob(encoded="YmxvYg==", decoding=BASE64);
diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc
index 6c8ea69..3688987 100644
--- a/bin/varnishtest/tests/v00020.vtc
+++ b/bin/varnishtest/tests/v00020.vtc
@@ -257,7 +257,7 @@ varnish v1 -errvcl {Expected 'from path ...'} {
 varnish v1 -errvcl {INT * BLOB not possible.} {
 	import blob;
 	sub vcl_deliver {
-		set resp.status = 100 * blob.decode(HEX, "a");
+		set resp.status = 100 * blob.decode(HEX, encoded="a");
 	}
 }
 
diff --git a/lib/libvmod_blob/vmod.vcc b/lib/libvmod_blob/vmod.vcc
index a5553c6..290e716 100644
--- a/lib/libvmod_blob/vmod.vcc
+++ b/lib/libvmod_blob/vmod.vcc
@@ -12,12 +12,9 @@ $Module blob 3 utilities for the VCL blob type
 
   # binary-to-text encodings
   STRING blob.encode([ENUM encoding,] [ENUM case,] BLOB blob)
-  BLOB blob.decode([ENUM decoding,] STRING_LIST encoded)
-  BLOB blob.decode_n(INT n, [ENUM decoding,] STRING_LIST encoded)
+  BLOB blob.decode([ENUM decoding,] [INT length,] STRING_LIST encoded)
   STRING blob.transcode([ENUM decoding,] [ENUM encoding,] [ENUM case,]
-			STRING_LIST encoded)
-  STRING blob.transcode_n(INT n, [ENUM decoding,] [ENUM encoding,]
-			  [ENUM case,] STRING_LIST encoded)
+			[INT length,] STRING_LIST encoded)
 
   # other utilities
   BOOL blob.same(BLOB, BLOB)
@@ -55,8 +52,9 @@ Examples::
       # decode() and encode() functions convert blobs to text and
       # vice versa at runtime.
       set resp.http.Base64-Encoded
-	  = blob.encode(BASE64,
-			blob=blob.decode(HEX, req.http.Hex-Encoded));
+          = blob.encode(BASE64,
+                        blob=blob.decode(HEX,
+                                         encoded=req.http.Hex-Encoded));
   }
 
   sub vcl_recv {
@@ -123,7 +121,8 @@ blob. For example::
   # Decode from the hex encoding for "foo\0bar".
   # The header will be seen as "foo".
   set resp.http.Trunced-Foo1
-    = blob.encode(IDENTITY, blob=blob.decode(HEX, "666f6f00626172"));
+      = blob.encode(IDENTITY, blob=blob.decode(HEX,
+                                               encoded="666f6f00626172"));
 
 IDENTITY is the default encoding and decoding. So the above can also
 be written as::
@@ -131,7 +130,7 @@ be written as::
   # Decode from the hex encoding for "foo\0bar".
   # The header will be seen as "foo".
   set resp.http.Trunced-Foo2
-    = blob.encode(blob=blob.decode(HEX, "666f6f00626172"));
+    = blob.encode(blob=blob.decode(HEX, encoded="666f6f00626172"));
 
 The ``case`` ENUM is ignored for ``IDENTITY`` encodings.
 
@@ -176,7 +175,7 @@ byte. For example::
   set resp.http.Second = "def0";
   set resp.http.Hex-Decoded
       = blob.encode(HEX, blob=blob.decode(HEX,
-                         resp.http.First + resp.http.Second));
+                         encoded=resp.http.First + resp.http.Second));
 
 URL
 ---
@@ -189,16 +188,22 @@ The ``URL`` encoding implements "percent encoding" as per RFC3986. The
 affect alphabetic characters that are not percent-encoded.
 
 $Function BLOB decode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
-			    HEX, URL} decoding="IDENTITY", STRING_LIST encoded)
+                            HEX, URL} decoding="IDENTITY", INT length=0,
+                      STRING_LIST encoded)
 
 Returns the BLOB derived from the string ``encoded`` according to the
 scheme specified by ``decoding``.
 
+If ``length`` > 0, only decode the first ``length`` characters of the
+encoded string. If ``length`` <= 0 or greater than the length of the
+string, then decode the entire string. The default value of ``length``
+is 0.
+
 ``decoding`` defaults to IDENTITY.
 
 Example::
 
-	blob.decode(BASE64, "Zm9vYmFyYmF6");
+	blob.decode(BASE64, encoded="Zm9vYmFyYmF6");
 
 	# same with named parameters
 	blob.decode(encoded="Zm9vYmFyYmF6", decoding=BASE64);
@@ -206,15 +211,6 @@ Example::
 	# convert string to blob
 	blob.decode(encoded="foo");
 
-$Function BLOB decode_n(INT n,
-			ENUM {IDENTITY, BASE64, BASE64URL,
-			BASE64URLNOPAD, HEX, URL} decoding="IDENTITY",
-			STRING_LIST encoded)
-
-Same as ``decode()``, but only decode the first ``n`` characters of
-the encoded string. If ``n`` is greater than the length of the string,
-then return the same result as ``decode()``.
-
 $Function STRING encode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
 			      HEX, URL} encoding="IDENTITY",
 			ENUM {LOWER, UPPER} case="LOWER", BLOB blob)
@@ -228,7 +224,8 @@ Returns a string representation of the BLOB ``blob`` as specifed by
 Example::
 
 	set resp.http.encode1
-	    = blob.encode(HEX, blob=blob.decode(BASE64, "Zm9vYmFyYmF6"));
+	    = blob.encode(HEX,
+                          blob=blob.decode(BASE64, encoded="Zm9vYmFyYmF6"));
 
 	# same with named parameters
 	set resp.http.encode2
@@ -244,7 +241,7 @@ $Function STRING transcode(ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
 				 HEX, URL} decoding="IDENTITY",
 			   ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
 				 HEX, URL} encoding="IDENTITY",
-			   ENUM {LOWER, UPPER} case="LOWER",
+			   ENUM {LOWER, UPPER} case="LOWER", INT length=0,
 			   STRING_LIST encoded)
 
 Translates from one encoding to another, by first decoding the string
@@ -253,6 +250,10 @@ the encoding of the resulting blob according to the scheme
 ``encoding``. ``case`` determines the case of hex digits for the
 ``HEX`` and ``URL`` encodings, and is ignored for other encodings.
 
+As with ``decode()``: If ``length`` > 0, only decode the first
+``length`` characters of the encoded string, otherwise decode the
+entire string. The default value of ``length`` is 0.
+
 ``decoding`` and ``encoding`` default to IDENTITY, and ``case``
 defaults to LOWER.
 
@@ -274,17 +275,6 @@ Example::
 	set resp.http.urlencoded
 	    = blob.transcode(encoded="foo bar", encoding=URL);
 
-$Function STRING transcode_n(INT n,
-			     ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
-				   HEX, URL} decoding="IDENTITY",
-			     ENUM {IDENTITY, BASE64, BASE64URL, BASE64URLNOPAD,
-				   HEX, URL} encoding="IDENTITY",
-			     ENUM {LOWER, UPPER} case="LOWER",
-			     STRING_LIST encoded)
-
-Same as ``transcode()``, but only from the first ``n`` characters of
-the encoded string.
-
 $Function BOOL same(BLOB, BLOB)
 
 Returns true if and only if the two BLOB arguments are the same
@@ -326,7 +316,7 @@ Creates an object that contains the BLOB derived from the string
 
 Example::
 
-	new theblob1 = blob.blob(BASE64, "YmxvYg==");
+	new theblob1 = blob.blob(BASE64, encoded="YmxvYg==");
 
 	# same with named arguments
 	new theblob2 = blob.blob(encoded="YmxvYg==", decoding=BASE64);
diff --git a/lib/libvmod_blob/vmod_blob.c b/lib/libvmod_blob/vmod_blob.c
index 850f975..2da7781 100644
--- a/lib/libvmod_blob/vmod_blob.c
+++ b/lib/libvmod_blob/vmod_blob.c
@@ -336,11 +336,11 @@ find_nonempty_va(const char *restrict *p, va_list ap)
 	return (q);
 }
 
-static VCL_BLOB
-decode(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *restrict const p,
-       va_list ap)
+VCL_BLOB __match_proto__(td_blob_decode)
+vmod_decode(VRT_CTX, VCL_ENUM decs, VCL_INT length, const char *p, ...)
 {
 	enum encoding dec = parse_encoding(decs);
+	va_list ap;
 	struct wb_s wb;
 	struct vmod_priv *b;
 	char *buf;
@@ -364,8 +364,12 @@ decode(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *restrict const p,
 	}
 	buf = wb_buf(&wb);
 
+	if (length <= 0)
+		length = -1;
+	va_start(ap, p);
 	errno = 0;
-	len = func[dec].decode(dec, buf, wb_space(&wb), n, p, ap);
+	len = func[dec].decode(dec, buf, wb_space(&wb), length, p, ap);
+	va_end(ap);
 
 	if (len == -1) {
 		err_decode(ctx, p);
@@ -383,33 +387,7 @@ decode(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *restrict const p,
 	b->priv = buf;
 	b->len = len;
 	b->free = NULL;
-	return b;
-}
-
-VCL_BLOB __match_proto__(td_blob_decode)
-vmod_decode(VRT_CTX, VCL_ENUM decs, const char *p, ...)
-{
-	va_list ap;
-	VCL_BLOB r;
-
-	va_start(ap, p);
-	r = decode(ctx, -1, decs, p, ap);
-	va_end(ap);
-
-	return (r);
-}
-
-VCL_BLOB __match_proto__(td_blob_decode_n)
-vmod_decode_n(VRT_CTX, VCL_INT n, VCL_ENUM decs, const char *p, ...)
-{
-	va_list ap;
-	VCL_BLOB r;
-
-	va_start(ap, p);
-	r = decode(ctx, n, decs, p, ap);
-	va_end(ap);
-
-	return (r);
+	return (b);
 }
 
 static VCL_STRING
@@ -460,14 +438,14 @@ encodes_hex(enum encoding enc)
 	return (enc == HEX || enc == URL);
 }
 
-static VCL_STRING
-transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
-	  const char *restrict const p, va_list ap)
+VCL_STRING __match_proto__(td_blob_transcode)
+vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
+	       VCL_INT length, const char *p, ...)
 {
 	enum encoding dec = parse_encoding(decs);
 	enum encoding enc = parse_encoding(encs);
 	enum case_e kase = parse_case(case_s);
-	va_list aq;
+	va_list ap;
 	struct vmod_priv b;
 	VCL_STRING r;
 
@@ -481,9 +459,9 @@ transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
 	 * Allocate space for the decoded blob on the stack
 	 * ignoring the limitation imposed by n
 	 */
-	va_copy(aq, ap);
-	size_t l = decode_l_va(dec, p, aq);
-	va_end(aq);
+	va_start(ap, p);
+	size_t l = decode_l_va(dec, p, ap);
+	va_end(ap);
 	if (l == 0)
 		return "";
 	/* XXX: handle stack overflow? */
@@ -491,10 +469,12 @@ transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
 	b.free = NULL;
 	b.priv = buf;
 
+	if (length <= 0)
+		length = -1;
+	va_start(ap, p);
 	errno = 0;
-	va_copy(aq, ap);
-	b.len = func[dec].decode(dec, buf, l, n, p, aq);
-	va_end(aq);
+	b.len = func[dec].decode(dec, buf, l, length, p, ap);
+	va_end(ap);
 
 	if (b.len == -1) {
 		err_decode(ctx, p);
@@ -509,11 +489,11 @@ transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
 	 * since the call may specify upper- or lower-case that differs
 	 * from the encoded string.
 	 */
-	if (n == -1 && enc == dec && !encodes_hex(enc)) {
+	if (length == -1 && enc == dec && !encodes_hex(enc)) {
 		const char *q, *pp = p;
-		va_copy(aq, ap);
+		va_start(ap, p);
 		q = find_nonempty_va(&pp, ap);
-		va_end(aq);
+		va_end(ap);
 
 		if (pp == vrt_magic_string_end)
 			return "";
@@ -529,34 +509,6 @@ transcode(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
 	return (r);
 }
 
-VCL_STRING __match_proto__(td_blob_transcode)
-vmod_transcode(VRT_CTX, VCL_ENUM decs, VCL_ENUM encs, VCL_ENUM case_s,
-	       const char *p, ...)
-{
-	va_list ap;
-	VCL_STRING r;
-
-	va_start(ap, p);
-	r = transcode(ctx, -1, decs, encs, case_s, p, ap);
-	va_end(ap);
-
-	return (r);
-}
-
-VCL_STRING __match_proto__(td_blob_transcode_n)
-vmod_transcode_n(VRT_CTX, VCL_INT n, VCL_ENUM decs, VCL_ENUM encs,
-		 VCL_ENUM case_s, const char *p, ...)
-{
-	va_list ap;
-	VCL_STRING r;
-
-	va_start(ap, p);
-	r = transcode(ctx, n, decs, encs, case_s, p, ap);
-	va_end(ap);
-
-	return (r);
-}
-
 VCL_BOOL __match_proto__(td_blob_same)
 vmod_same(VRT_CTX, VCL_BLOB b1, VCL_BLOB b2)
 {


More information about the varnish-commit mailing list