From ba922fd94b20ae572edbe094418b20425f7a7c7e Mon Sep 17 00:00:00 2001 From: Vladimir Panteleev Date: Mon, 11 Feb 2013 17:25:44 +0200 Subject: [PATCH] std.base64: Introduce Base64Exception --- std/base64.d | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/std/base64.d b/std/base64.d index c015287b850..c9f7b294215 100644 --- a/std/base64.d +++ b/std/base64.d @@ -486,7 +486,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') */ void popFront() { - enforce(!empty, "Cannot call popFront on Encoder with no data remaining"); + enforce(!empty, new Base64Exception("Cannot call popFront on Encoder with no data remaining")); range_.popFront(); @@ -597,7 +597,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') */ void popFront() { - enforce(!empty, "Cannot call popFront on Encoder with no data remaining"); + enforce(!empty, new Base64Exception("Cannot call popFront on Encoder with no data remaining")); static if (Padding != NoPadding) if (padding) { @@ -807,7 +807,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') if (srcLen == 0) return []; static if (Padding != NoPadding) - enforce(srcLen % 4 == 0, "Invalid length of encoded data"); + enforce(srcLen % 4 == 0, new Base64Exception("Invalid length of encoded data")); immutable blocks = srcLen / 4; auto srcptr = source.ptr; @@ -875,7 +875,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') if (srcLen == 0) return []; static if (Padding != NoPadding) - enforce(srcLen % 4 == 0, "Invalid length of encoded data"); + enforce(srcLen % 4 == 0, new Base64Exception("Invalid length of encoded data")); immutable blocks = srcLen / 4; auto bufptr = buffer.ptr; @@ -953,7 +953,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') if (srcLen == 0) return 0; static if (Padding != NoPadding) - enforce(srcLen % 4 == 0, "Invalid length of encoded data"); + enforce(srcLen % 4 == 0, new Base64Exception("Invalid length of encoded data")); immutable blocks = srcLen / 4; auto srcptr = source.ptr; @@ -1023,7 +1023,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') if (srcLen == 0) return 0; static if (Padding != NoPadding) - enforce(srcLen % 4 == 0, "Invalid length of encoded data"); + enforce(srcLen % 4 == 0, new Base64Exception("Invalid length of encoded data")); immutable blocks = srcLen / 4; size_t pcount; @@ -1152,7 +1152,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') */ void popFront() { - enforce(!empty, "Cannot call popFront on Decoder with no data remaining."); + enforce(!empty, new Base64Exception("Cannot call popFront on Decoder with no data remaining.")); range_.popFront(); @@ -1230,7 +1230,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') range_ = range_.save; static if (Padding != NoPadding && hasLength!Range) - enforce(range_.length % 4 == 0); + enforce(range_.length % 4 == 0, new Base64Exception("Invalid length of encoded data")); if (range_.empty) pos = -1; @@ -1273,7 +1273,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') */ void popFront() { - enforce(!empty, "Cannot call popFront on Decoder with no data remaining"); + enforce(!empty, new Base64Exception("Cannot call popFront on Decoder with no data remaining")); static if (Padding == NoPadding) { bool endCondition() @@ -1283,7 +1283,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') } else { bool endCondition() { - enforce(!range_.empty, "Missing padding"); + enforce(!range_.empty, new Base64Exception("Missing padding")); return range_.front == Padding; } } @@ -1295,12 +1295,12 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') final switch (pos) { case 0: - enforce(!endCondition(), "Premature end of data found"); + enforce(!endCondition(), new Base64Exception("Premature end of data found")); immutable t = DecodeMap[range_.front] << 2; range_.popFront(); - enforce(!endCondition(), "Premature end of data found"); + enforce(!endCondition(), new Base64Exception("Premature end of data found")); first = cast(ubyte)(t | (DecodeMap[range_.front] >> 4)); break; case 1: @@ -1407,7 +1407,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') // enforce can't be a pure function, so I use trivial check. if (val == 0 && chr != 'A') - throw new Exception("Invalid character: " ~ chr); + throw new Base64Exception("Invalid character: " ~ chr); return val; } @@ -1418,13 +1418,25 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') { // See above comment. if (chr > 0x7f) - throw new Exception("Base64-encoded character must be a single byte"); + throw new Base64Exception("Base64-encoded character must be a single byte"); return decodeChar(cast(char)chr); } } +/** + * Exception thrown on Base64 errors. + */ +class Base64Exception : Exception +{ + this(string s, string fn = __FILE__, size_t ln = __LINE__) + { + super(s, fn, ln); + } +} + + unittest { alias Base64Impl!('!', '=', Base64.NoPadding) Base64Re; @@ -1475,7 +1487,7 @@ unittest assert(Base64.decode(Base64.encode(tv["fooba"])) == tv["fooba"]); assert(Base64.decode(Base64.encode(tv["foobar"])) == tv["foobar"]); - assertThrown(Base64.decode("ab|c")); + assertThrown!Base64Exception(Base64.decode("ab|c")); // Test decoding incomplete strings. RFC does not specify the correct // behavior, but the code should never throw Errors on invalid input. @@ -1486,10 +1498,10 @@ unittest assert(Base64.decodeLength(3) <= 2); // may throw Exceptions, may not throw Errors - assertThrown(Base64.decode("Zg")); - assertThrown(Base64.decode("Zg=")); - assertThrown(Base64.decode("Zm8")); - assertThrown(Base64.decode("Zg==;")); + assertThrown!Base64Exception(Base64.decode("Zg")); + assertThrown!Base64Exception(Base64.decode("Zg=")); + assertThrown!Base64Exception(Base64.decode("Zm8")); + assertThrown!Base64Exception(Base64.decode("Zg==;")); } { // No padding