///|
fn token_requires_quotes(text : String) -> Bool {
if text.length() == 0 {
return true
}
for index = 0; index < text.length(); index = index + 1 {
let code = text[index].to_int()
if code <= 32 ||
code == 34 ||
code == 40 ||
code == 41 ||
code == 59 ||
code == 92 {
return true
}
}
false
}
///|
fn quote_zone_text(text : String) -> String {
let mut result = "\""
for index = 0; index < text.length(); index = index + 1 {
let code = text[index].to_int()
if code == 34 || code == 92 || code == 59 {
result = result + "\\" + ascii_character(code)
} else if code < 32 || code > 126 {
let hundreds = code / 100
let tens = code / 10 % 10
let ones = code % 10
result = result +
"\\" +
hundreds.to_string() +
tens.to_string() +
ones.to_string()
} else {
result = result + ascii_character(code)
}
}
result + "\""
}
///|
fn render_zone_token(text : String) -> String {
if token_requires_quotes(text) {
quote_zone_text(text)
} else {
text
}
}
///|
fn join_rendered_fields(fields : Array[String]) -> String {
let mut result = ""
for index, field in fields {
if index > 0 {
result = result + " "
}
result = result + field
}
result
}
///|
pub fn render_record_data(data : RecordData) -> String {
match data {
AData(value) => value.to_text()
AaaaData(value) => value.to_text()
NsData(value) | CnameData(value) | PtrData(value) => value.to_text()
MxData(value) =>
value.preference().to_string() + " " + value.exchange().to_text()
TxtData(values) => {
let fields : Array[String] = []
for value in values {
fields.push(quote_zone_text(value))
}
join_rendered_fields(fields)
}
SrvData(value) =>
value.priority().to_string() +
" " +
value.weight().to_string() +
" " +
value.port().to_string() +
" " +
value.target().to_text()
CaaData(value) =>
value.flags().to_string() +
" " +
value.tag() +
" " +
quote_zone_text(value.value())
SoaData(value) =>
value.primary_name().to_text() +
" " +
value.responsible_name().to_text() +
" " +
value.serial().to_string() +
" " +
value.refresh().to_text() +
" " +
value.retry().to_text() +
" " +
value.expire().to_text() +
" " +
value.minimum().to_text()
GenericData(value) => {
let fields : Array[String] = []
for field in value.fields() {
fields.push(render_zone_token(field))
}
join_rendered_fields(fields)
}
}
}
///|
pub fn ZoneRecord::to_text(self : ZoneRecord) -> String {
self.owner().to_text() +
" " +
self.ttl().to_text() +
" IN " +
self.record_type() +
" " +
render_record_data(self.data())
}
///|
pub fn render_zone(zone : ZoneDocument) -> String {
let lines : Array[String] = []
match zone.origin() {
Some(value) => lines.push("$ORIGIN " + value.to_text())
None => ()
}
match zone.default_ttl() {
Some(value) => lines.push("$TTL " + value.to_text())
None => ()
}
for record in zone.records() {
lines.push(record.to_text())
}
let mut result = ""
for index, line in lines {
if index > 0 {
result = result + "\n"
}
result = result + line
}
result
}