mirror of
https://github.com/NLnetLabs/domain.git
synced 2026-09-23 18:24:59 +02:00
Add a type for <character-string>.
This commit is contained in:
@@ -4,6 +4,7 @@ use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use super::cstring::CString;
|
||||
use super::error::{ComposeError, ComposeResult};
|
||||
use super::name::{DName, DNameSlice, Label, OwnedDName};
|
||||
|
||||
@@ -62,6 +63,9 @@ pub trait ComposeBytes: Sized + fmt::Debug {
|
||||
fn push_dname_compressed<D: DName>(&mut self, name: &D)
|
||||
-> ComposeResult<()>;
|
||||
|
||||
fn push_cstring<S: CString>(&mut self, cstring: &S) -> ComposeResult<()> {
|
||||
cstring.compose(self)
|
||||
}
|
||||
|
||||
//--- Checkpoint and rollback.
|
||||
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
//! Character strings.
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::cmp;
|
||||
use std::hash;
|
||||
use std::ops::Deref;
|
||||
use super::compose::ComposeBytes;
|
||||
use super::error::{ComposeResult, ParseResult};
|
||||
use super::parse::ParseBytes;
|
||||
|
||||
//------------ CString ------------------------------------------------------
|
||||
|
||||
pub trait CString {
|
||||
fn compose<C: ComposeBytes>(&self, target: &mut C) -> ComposeResult<()>;
|
||||
}
|
||||
|
||||
//------------ CStringRef ---------------------------------------------------
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CStringRef<'a> {
|
||||
inner: &'a [u8]
|
||||
}
|
||||
|
||||
impl <'a> CStringRef<'a> {
|
||||
unsafe fn from_bytes(bytes: &'a [u8]) -> Self {
|
||||
CStringRef { inner: bytes }
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &CStringRef {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn to_owned(&self) -> OwnedCString {
|
||||
unsafe { OwnedCString::from_bytes(self.inner) }
|
||||
}
|
||||
|
||||
pub fn parse<P: ParseBytes<'a>>(parser: &mut P) -> ParseResult<Self> {
|
||||
let len = try!(parser.parse_u8()) as usize;
|
||||
parser.parse_bytes(len)
|
||||
.map(|bytes| unsafe {CStringRef::from_bytes(bytes) })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- CString
|
||||
|
||||
impl<'a> CString for CStringRef<'a> {
|
||||
fn compose<C: ComposeBytes>(&self, target: &mut C) -> ComposeResult<()> {
|
||||
assert!(self.inner.len() < 256);
|
||||
try!(target.push_u8(self.inner.len() as u8));
|
||||
try!(target.push_bytes(self.inner));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- Deref, Borrow, AsRef
|
||||
|
||||
impl<'a> Deref for CStringRef<'a> {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Borrow<[u8]> for CStringRef<'a> {
|
||||
fn borrow(&self) -> &[u8] {
|
||||
self.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AsRef<[u8]> for CStringRef<'a> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.deref()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- PartialEq, Eq
|
||||
|
||||
impl<'a, T: AsRef<[u8]>> PartialEq<T> for CStringRef<'a> {
|
||||
fn eq(&self, other: &T) -> bool {
|
||||
self.deref().eq(other.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Eq for CStringRef<'a> { }
|
||||
|
||||
|
||||
//--- PartialOrd, Ord
|
||||
|
||||
impl<'a, T: AsRef<[u8]>> PartialOrd<T> for CStringRef<'a> {
|
||||
fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
|
||||
self.deref().partial_cmp(other.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Ord for CStringRef<'a> {
|
||||
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
||||
self.deref().cmp(other.deref())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- Hash
|
||||
|
||||
impl<'a> hash::Hash for CStringRef<'a> {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
self.deref().hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- Display
|
||||
|
||||
// XXX TODO
|
||||
|
||||
|
||||
//------------ OwnedCString -------------------------------------------------
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OwnedCString {
|
||||
inner: Vec<u8>
|
||||
}
|
||||
|
||||
|
||||
impl OwnedCString {
|
||||
unsafe fn from_bytes(bytes: &[u8]) -> Self {
|
||||
OwnedCString { inner: Vec::from(bytes) }
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
OwnedCString { inner: Vec::new() }
|
||||
}
|
||||
|
||||
// XXX TODO from_str
|
||||
|
||||
pub fn parse<'a, P: ParseBytes<'a>>(parser: &mut P)
|
||||
-> ParseResult<Self> {
|
||||
Ok(try!(CStringRef::parse(parser)).to_owned())
|
||||
}
|
||||
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// XXX TODO Manipulations.
|
||||
|
||||
|
||||
//--- CString
|
||||
|
||||
impl CString for OwnedCString {
|
||||
fn compose<C: ComposeBytes>(&self, target: &mut C) -> ComposeResult<()> {
|
||||
assert!(self.inner.len() < 256);
|
||||
try!(target.push_u8(self.inner.len() as u8));
|
||||
try!(target.push_bytes(&self.inner));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- FromStr
|
||||
|
||||
// XXX TODO
|
||||
|
||||
|
||||
//--- Deref, Borrow, AsRef
|
||||
|
||||
impl Deref for OwnedCString {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.inner.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<[u8]> for OwnedCString {
|
||||
fn borrow(&self) -> &[u8] {
|
||||
self.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for OwnedCString {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- PartialEq and Eq
|
||||
|
||||
impl<T: AsRef<[u8]>> PartialEq<T> for OwnedCString {
|
||||
fn eq(&self, other: &T) -> bool {
|
||||
self.deref().eq(other.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for OwnedCString { }
|
||||
|
||||
|
||||
//--- PartialOrd and Ord
|
||||
|
||||
impl<T: AsRef<[u8]>> PartialOrd<T> for OwnedCString {
|
||||
fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
|
||||
self.deref().partial_cmp(other.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for OwnedCString {
|
||||
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
||||
self.deref().cmp(other.deref())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- Hash
|
||||
|
||||
impl hash::Hash for OwnedCString {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
self.deref().hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--- Display
|
||||
|
||||
// XXX TODO
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//! flavors as well as the actual flavors as types.
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use super::cstring;
|
||||
use super::name;
|
||||
use super::nest;
|
||||
|
||||
@@ -20,6 +21,7 @@ use super::nest;
|
||||
/// the associated types for each flavor.
|
||||
pub trait Flavor: Sized {
|
||||
type DName: name::DName;
|
||||
type CString: cstring::CString;
|
||||
}
|
||||
|
||||
/// The trait for DNS data that is stored in unparsed format.
|
||||
@@ -32,6 +34,7 @@ pub struct Owned;
|
||||
|
||||
impl Flavor for Owned {
|
||||
type DName = name::OwnedDName;
|
||||
type CString = cstring::OwnedCString;
|
||||
}
|
||||
|
||||
/// The flavor for DNS data referencing an underlying bytes slice.
|
||||
@@ -41,6 +44,7 @@ pub struct Ref<'a> {
|
||||
|
||||
impl<'a> Flavor for Ref<'a> {
|
||||
type DName = name::DNameRef<'a>;
|
||||
type CString = cstring::CStringRef<'a>;
|
||||
}
|
||||
|
||||
impl<'a> FlatFlavor<'a> for Ref<'a> {
|
||||
@@ -55,6 +59,7 @@ pub struct Lazy<'a> {
|
||||
|
||||
impl<'a> Flavor for Lazy<'a> {
|
||||
type DName = name::LazyDName<'a>;
|
||||
type CString = cstring::CStringRef<'a>;
|
||||
}
|
||||
|
||||
impl<'a> FlatFlavor<'a> for Lazy<'a> {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! DNS data.
|
||||
|
||||
pub mod compose;
|
||||
pub mod cstring;
|
||||
pub mod error;
|
||||
pub mod flavor;
|
||||
pub mod header;
|
||||
|
||||
+1
-1
@@ -398,7 +398,7 @@ impl<'a> DName for DNameRef<'a> {
|
||||
//--- From
|
||||
|
||||
impl<'a> From<&'a DNameSlice> for DNameRef<'a> {
|
||||
fn from(slice: &'a DNameSlice) -> DNameRef {
|
||||
fn from(slice: &'a DNameSlice) -> Self {
|
||||
Self::from_slice(slice)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Parsing of wire-format DNS data.
|
||||
|
||||
use std::mem;
|
||||
use super::cstring::CStringRef;
|
||||
use super::error::{ParseResult, ParseError};
|
||||
use super::flavor::{self, FlatFlavor};
|
||||
use super::name::{DNameRef, LazyDName};
|
||||
@@ -66,6 +67,7 @@ pub trait ParseLazy<'a>: ParseBytes<'a> {
|
||||
/// `ParseBytes` trait only for specific flavors.
|
||||
pub trait ParseFlavor<'a, F: FlatFlavor<'a>>: ParseBytes<'a> {
|
||||
fn parse_name(&mut self) -> ParseResult<F::DName>;
|
||||
fn parse_cstring(&mut self) -> ParseResult<F::CString>;
|
||||
fn parse_nest(&mut self, len: usize) -> ParseResult<F::Nest>;
|
||||
}
|
||||
|
||||
@@ -73,6 +75,10 @@ impl<'a, P: ParseBytes<'a>> ParseFlavor<'a, flavor::Ref<'a>> for P {
|
||||
fn parse_name(&mut self) -> ParseResult<DNameRef<'a>> {
|
||||
DNameRef::parse(self)
|
||||
}
|
||||
|
||||
fn parse_cstring(&mut self) -> ParseResult<CStringRef<'a>> {
|
||||
CStringRef::parse(self)
|
||||
}
|
||||
|
||||
fn parse_nest(&mut self, len: usize) -> ParseResult<NestRef<'a>> {
|
||||
NestRef::parse(self, len)
|
||||
@@ -84,6 +90,10 @@ impl<'a> ParseFlavor<'a, flavor::Lazy<'a>> for ContextParser<'a> {
|
||||
LazyDName::parse(self)
|
||||
}
|
||||
|
||||
fn parse_cstring(&mut self) -> ParseResult<CStringRef<'a>> {
|
||||
CStringRef::parse(self)
|
||||
}
|
||||
|
||||
fn parse_nest(&mut self, len: usize) -> ParseResult<LazyNest<'a>> {
|
||||
LazyNest::parse(self, len)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user