go-rfc3986/pctencoded.go

128 lines
2.5 KiB
Go
Raw Normal View History

2023-10-07 04:08:00 +00:00
package rfc3986
import (
"io"
2023-10-07 07:54:15 +00:00
"sourcecode.social/reiver/go-erorr"
2023-10-07 04:08:00 +00:00
)
2023-10-07 07:54:15 +00:00
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
}
2023-10-07 04:08:00 +00:00
func WritePctEncodedByte(writer io.Writer, b byte) error {
if nil == writer {
return errNilWriter
}
var buffer [3]byte = [3]byte{'%','.','.'}
{
var x byte = ((b>>4) % 16)
if x < 10 {
x += '0'
} else {
x += ('A' - 10)
}
buffer[1] = x
}
{
var x byte = (b & 0x0f)
if x < 10 {
x += '0'
} else {
x += ('A' - 10)
}
buffer[2] = x
}
_, err := writer.Write(buffer[:])
return err
}