1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00
v/vlib/crypto/pem/encode.v

60 lines
1.6 KiB
V

module pem
import encoding.base64
import arrays
// encode encodes the given block into a
// string using the EncodeConfig. It returns an error if `block_type` is undefined
// or if a value in `headers` contains an invalid character ':'
//
// default EncodeConfig values wrap lines at 64 bytes and use '\n' for newlines
pub fn (block Block) encode(config EncodeConfig) !string {
if block.block_type == '' {
return error('crypto.pem: `encode` called with undefined `block_type`')
}
if block.headers.keys().any(it.contains(':')) || block.headers.values().any(it.contains(':')) {
return error('crypto.pem: invalid header character `:`')
}
// to avoid repeated struct access
newline := config.line_ending
length := config.line_length
mut inner := ''
if block.headers.len > 0 {
// Proc-Type must be written first if it is present
if block.headers['Proc-Type'].len > 0 {
inner += 'Proc-Type: 4,${block.headers['Proc-Type'][0].trim_string_left('4,')}' +
newline
}
for key, value in block.headers {
if key == 'Proc-Type' {
continue
}
for _, subvalue in value {
inner += '${key}: '
if key.len + subvalue.len < length {
inner += subvalue
} else {
inner += newline + wrap_lines(subvalue, newline, length)
}
inner += newline
}
}
inner += newline
}
inner += wrap_lines(base64.encode(block.data), newline, length)
return '${pem_begin}${block.block_type}${pem_eol}${newline}' + '${inner}' +
'${pem_end}${block.block_type}${pem_eol}'
}
[inline]
fn wrap_lines(str string, newline string, length int) string {
return arrays.chunk(str.bytes(), length).map(it.bytestr()).join(newline)
}