initial commits
							parent
							
								
									c2d871f6e0
								
							
						
					
					
						commit
						63e3bc4355
					
				|  | @ -5,5 +5,6 @@ import ( | |||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	errNilReader = erorr.Error("rfc3986: nil reader") | ||||
| 	errNilWriter = erorr.Error("rfc3986: nil writer") | ||||
| ) | ||||
|  |  | |||
|  | @ -2,8 +2,95 @@ package rfc3986 | |||
| 
 | ||||
| import ( | ||||
| 	"io" | ||||
| 
 | ||||
| 	"sourcecode.social/reiver/go-erorr" | ||||
| ) | ||||
| 
 | ||||
| func ReadPctEncodedByte(reader io.Reader) (byte, error) { | ||||
| 	if nil == reader { | ||||
| 		return 0, errNilReader | ||||
| 	} | ||||
| 
 | ||||
| 	var buffer [1]byte | ||||
| 	var p []byte = buffer[:] | ||||
| 
 | ||||
| 	{ | ||||
| 		const expected byte = '%' | ||||
| 
 | ||||
| 		n, err := reader.Read(p) | ||||
| 		if nil != err { | ||||
| 			return 0, erorr.Errorf("rfc3986: could not read the 1st byte in pct-encoded string because: %w", err) | ||||
| 		} | ||||
| 		if 1 != n { | ||||
| 			return 0, erorr.Errorf("rfc3986: problem reading the 1st byte in pct-encoded string — expected to have read 1 byte but actually read %d bytes.", n) | ||||
| 		} | ||||
| 
 | ||||
| 		actual := buffer[0] | ||||
| 
 | ||||
| 		if expected != actual { | ||||
| 			return 0, erorr.Errorf("rfc3986:the 1st byte in pct-encoded string is not a percent-sign (%U) (%q) is actually %U (%q)", expected, expected, actual, actual) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	var result byte = 0 | ||||
| 
 | ||||
| 	{ | ||||
| 		n, err := reader.Read(p) | ||||
| 		if nil != err { | ||||
| 			return 0, erorr.Errorf("rfc3986: could not read the 2nd byte in pct-encoded string because: %w", err) | ||||
| 		} | ||||
| 		if 1 != n { | ||||
| 			return 0, erorr.Errorf("rfc3986: problem reading the 2nd byte in pct-encoded string — expected to have read 1 byte but actually read %d bytes.", n) | ||||
| 		} | ||||
| 
 | ||||
| 		b0 := buffer[0] | ||||
| 
 | ||||
| 		switch { | ||||
| 		case '0' <= b0 && b0 <= '9': | ||||
| 			b0 -= '0' | ||||
| 		case 'A' <= b0 && b0 <= 'F': | ||||
| 			b0 -= 'A' | ||||
| 			b0 += 10 | ||||
| 		case 'a' <= b0 && b0 <= 'f': | ||||
| 			b0 -= 'a' | ||||
| 			b0 += 10 | ||||
| 		default: | ||||
| 			return 0, erorr.Errorf("rfc3986: the 2nd byte in the pct-encoded string is not an IETF RFC-2234 'HEXDIG'") | ||||
| 		} | ||||
| 
 | ||||
| 		result |= (b0 << 4) | ||||
| 	} | ||||
| 
 | ||||
| 	{ | ||||
| 		n, err := reader.Read(p) | ||||
| 		if nil != err { | ||||
| 			return 0, erorr.Errorf("rfc3986: could not read the 3rd byte in pct-encoded string because: %w", err) | ||||
| 		} | ||||
| 		if 1 != n { | ||||
| 			return 0, erorr.Errorf("rfc3986: problem reading the 3rd byte in pct-encoded string — expected to have read 1 byte but actually read %d bytes.", n) | ||||
| 		} | ||||
| 
 | ||||
| 		b0 := buffer[0] | ||||
| 
 | ||||
| 		switch { | ||||
| 		case '0' <= b0 && b0 <= '9': | ||||
| 			b0 -= '0' | ||||
| 		case 'A' <= b0 && b0 <= 'F': | ||||
| 			b0 -= 'A' | ||||
| 			b0 += 10 | ||||
| 		case 'a' <= b0 && b0 <= 'f': | ||||
| 			b0 -= 'a' | ||||
| 			b0 += 10 | ||||
| 		default: | ||||
| 			return 0, erorr.Errorf("rfc3986: the 2nd byte in the pct-encoded string is not an IETF RFC-2234 'HEXDIG'") | ||||
| 		} | ||||
| 
 | ||||
| 		result |= b0 | ||||
| 	} | ||||
| 
 | ||||
| 	return result, nil | ||||
| } | ||||
| 
 | ||||
| func WritePctEncodedByte(writer io.Writer, b byte) error { | ||||
| 	if nil == writer { | ||||
| 		return errNilWriter | ||||
|  |  | |||
|  | @ -0,0 +1,345 @@ | |||
| package rfc3986_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"io" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"sourcecode.social/reiver/go-rfc3986" | ||||
| ) | ||||
| 
 | ||||
| func TestReadPctEncodedByte(t *testing.T) { | ||||
| 
 | ||||
| 	tests := []struct{ | ||||
| 		Value string | ||||
| 		Expected byte | ||||
| 	}{ | ||||
| 		{ | ||||
| 			Value:    "%00", | ||||
| 			Expected:    0, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%01", | ||||
| 			Expected:    1, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%02", | ||||
| 			Expected:    2, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%03", | ||||
| 			Expected:    3, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%04", | ||||
| 			Expected:    4, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%05", | ||||
| 			Expected:    5, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%06", | ||||
| 			Expected:    6, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%07", | ||||
| 			Expected:    7, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%08", | ||||
| 			Expected:    8, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%09", | ||||
| 			Expected:    9, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0A", | ||||
| 			Expected:   10, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0B", | ||||
| 			Expected:   11, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0C", | ||||
| 			Expected:   12, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0D", | ||||
| 			Expected:   13, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0E", | ||||
| 			Expected:   14, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0F", | ||||
| 			Expected:   15, | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Value:    "%0a", | ||||
| 			Expected:   10, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0b", | ||||
| 			Expected:   11, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0c", | ||||
| 			Expected:   12, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0d", | ||||
| 			Expected:   13, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0e", | ||||
| 			Expected:   14, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%0f", | ||||
| 			Expected:   15, | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Value:    "%10", | ||||
| 			Expected:   16, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%11", | ||||
| 			Expected:   17, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%12", | ||||
| 			Expected:   18, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%13", | ||||
| 			Expected:   19, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%14", | ||||
| 			Expected:   20, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%15", | ||||
| 			Expected:   21, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%16", | ||||
| 			Expected:   22, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%17", | ||||
| 			Expected:   23, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%18", | ||||
| 			Expected:   24, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%19", | ||||
| 			Expected:   25, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1A", | ||||
| 			Expected:   26, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1B", | ||||
| 			Expected:   27, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1C", | ||||
| 			Expected:   28, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1D", | ||||
| 			Expected:   29, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1E", | ||||
| 			Expected:   30, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1F", | ||||
| 			Expected:   31, | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Value:    "%1a", | ||||
| 			Expected:   26, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1b", | ||||
| 			Expected:   27, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1c", | ||||
| 			Expected:   28, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1d", | ||||
| 			Expected:   29, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1e", | ||||
| 			Expected:   30, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%1f", | ||||
| 			Expected:   31, | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Value:    "%20F", | ||||
| 			Expected:   32, | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Value:    "%FA", | ||||
| 			Expected:  250, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%FB", | ||||
| 			Expected:  251, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%FC", | ||||
| 			Expected:  252, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%FD", | ||||
| 			Expected:  253, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%FE", | ||||
| 			Expected:  254, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%FF", | ||||
| 			Expected:  255, | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Value:    "%Fa", | ||||
| 			Expected:  250, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%Fb", | ||||
| 			Expected:  251, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%Fc", | ||||
| 			Expected:  252, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%Fd", | ||||
| 			Expected:  253, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%Fe", | ||||
| 			Expected:  254, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%Ff", | ||||
| 			Expected:  255, | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Value:    "%fA", | ||||
| 			Expected:  250, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%fB", | ||||
| 			Expected:  251, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%fC", | ||||
| 			Expected:  252, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%fD", | ||||
| 			Expected:  253, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%fE", | ||||
| 			Expected:  254, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%fF", | ||||
| 			Expected:  255, | ||||
| 		}, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		{ | ||||
| 			Value:    "%fa", | ||||
| 			Expected:  250, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%fb", | ||||
| 			Expected:  251, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%fc", | ||||
| 			Expected:  252, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%fd", | ||||
| 			Expected:  253, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%fe", | ||||
| 			Expected:  254, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Value:    "%ff", | ||||
| 			Expected:  255, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	for testNumber, test := range tests { | ||||
| 
 | ||||
| 		var reader io.Reader = strings.NewReader(test.Value) | ||||
| 
 | ||||
| 		actual, err := rfc3986.ReadPctEncodedByte(reader) | ||||
| 		if nil != err { | ||||
| 			t.Errorf("For test #%d, did not expect an error but actually got one." , testNumber) | ||||
| 			t.Logf("ERROR: (%T) %s", err, err) | ||||
| 			t.Logf("VALUE: %q", test.Value) | ||||
| 			t.Logf("EXPECTED: %d (0x%X)", test.Expected, test.Expected) | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		{ | ||||
| 			expected := test.Expected | ||||
| 
 | ||||
| 			if expected != actual { | ||||
| 				t.Errorf("For test #%d, the actual byte returned is not what was expected.", testNumber) | ||||
| 				t.Logf("EXPECTED: %d (0x%X)", expected, expected) | ||||
| 				t.Logf("ACTUAL:   %d (0x%X)", actual, actual) | ||||
| 				t.Logf("VALUE: %q", test.Value) | ||||
| 				continue | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue