update micodus_server
This commit is contained in:
parent
bcd452c117
commit
65461f6f9e
69
src/main.rs
69
src/main.rs
@ -1,6 +1,5 @@
|
|||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|
||||||
pub use crate::parser::body::*;
|
|
||||||
pub use crate::parser::*;
|
pub use crate::parser::*;
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -28,48 +27,46 @@ pub async fn apiserver() -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
tokio::spawn(async move {
|
loop {
|
||||||
loop {
|
let (socket, _remote_addr) = listener.accept().await?;
|
||||||
match listener.accept().await {
|
tokio::spawn(async move {
|
||||||
Ok((socket, _remote_addr)) => {
|
let mut buf = vec![0; 1024];
|
||||||
let mut buf = vec![0; 1024];
|
loop {
|
||||||
|
match socket.readable().await {
|
||||||
match socket.readable().await {
|
Ok(_) => {
|
||||||
Ok(_) => {
|
match socket.try_read(&mut buf) {
|
||||||
match socket.try_read(&mut buf) {
|
Ok(_) => match handle(&buf) {
|
||||||
Ok(_) => match handle(&buf) {
|
Some(o) => {
|
||||||
Some(o) => {
|
let _ = socket.try_write(&o).unwrap();
|
||||||
let _ = socket.try_write(&o).unwrap();
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
println!("error: {e}");
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
};
|
None => {
|
||||||
}
|
break;
|
||||||
Err(e) => {
|
}
|
||||||
println!("error: {e}");
|
},
|
||||||
continue;
|
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("error read: {e}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("error socket readable: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
|
||||||
println!("error: {err}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle(buf: &Vec<u8>) -> Option<Vec<u8>> {
|
pub fn handle(buf: &Vec<u8>) -> Option<Vec<u8>> {
|
||||||
let mut rawdata = DataWrapper::new(buf.to_vec());
|
let mut rawdata = InboundDataWrapper::new(buf.to_vec());
|
||||||
let reply = match parse_inbound_msg(&mut rawdata) {
|
let reply = match parse_inbound_msg(&mut rawdata) {
|
||||||
Ok(o) => {
|
Ok(mut o) => {
|
||||||
println!("query: {}", o);
|
println!("query: {}", o);
|
||||||
println!("raw query: {:?}", o.to_raw());
|
println!("raw query: {:X?}", o.to_raw());
|
||||||
|
Message::store(&o);
|
||||||
Message::set_reply(o)
|
Message::set_reply(o)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -79,9 +76,9 @@ pub fn handle(buf: &Vec<u8>) -> Option<Vec<u8>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match reply {
|
match reply {
|
||||||
Some(o) => {
|
Some(mut o) => {
|
||||||
println!("reply: {}", o);
|
println!("reply: {}", o);
|
||||||
println!("raw reply {:?}", o.to_raw());
|
println!("raw reply {:X?}", o.to_raw());
|
||||||
return Some(o.to_raw().into());
|
return Some(o.to_raw().into());
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use bcd_convert::BcdNumber;
|
||||||
use encoding_rs::*;
|
use encoding_rs::*;
|
||||||
|
|
||||||
macro_rules! generate_impl {
|
macro_rules! generate_impl {
|
||||||
@ -80,7 +81,16 @@ pub struct TerminalHeartbeat {}
|
|||||||
|
|
||||||
impl TerminalHeartbeat {
|
impl TerminalHeartbeat {
|
||||||
pub const ID: u16 = 0x0002;
|
pub const ID: u16 = 0x0002;
|
||||||
|
|
||||||
pub fn parse(&mut self, rawbody: &Vec<u8>) {}
|
pub fn parse(&mut self, rawbody: &Vec<u8>) {}
|
||||||
|
|
||||||
|
pub fn generate_reply(&self, answer_id: u16, serial: u16) -> PlatformUniversalResponse {
|
||||||
|
let mut res = PlatformUniversalResponse::default();
|
||||||
|
res.answer_serial_no = serial;
|
||||||
|
res.answer_id = answer_id;
|
||||||
|
res.result = TerminalRegistrationResult::Success as u8;
|
||||||
|
res
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
@ -296,15 +306,87 @@ pub struct LocationInformationReport {
|
|||||||
pub status: u32,
|
pub status: u32,
|
||||||
pub latitude: u32,
|
pub latitude: u32,
|
||||||
pub longitude: u32,
|
pub longitude: u32,
|
||||||
pub height: u32,
|
pub height: u16,
|
||||||
pub speed: u32,
|
pub speed: u16,
|
||||||
pub direction: u32,
|
pub direction: u16,
|
||||||
pub time: u32,
|
pub time: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocationInformationReport {
|
impl LocationInformationReport {
|
||||||
pub const ID: u16 = 0x0200;
|
pub const ID: u16 = 0x0200;
|
||||||
pub fn parse(&mut self, rawbody: &Vec<u8>) {}
|
|
||||||
|
pub fn parse(&mut self, rawbody: &Vec<u8>) {
|
||||||
|
let mut bd = rawbody.into_iter();
|
||||||
|
self.alert_mark = u32::from_be_bytes(
|
||||||
|
vec![
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
self.status = u32::from_be_bytes(
|
||||||
|
vec![
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
self.latitude = u32::from_be_bytes(
|
||||||
|
vec![
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
self.longitude = u32::from_be_bytes(
|
||||||
|
vec![
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
*bd.next().unwrap(),
|
||||||
|
]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
self.height = u16::from_be_bytes(
|
||||||
|
vec![*bd.next().unwrap(), *bd.next().unwrap()]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
self.speed = u16::from_be_bytes(
|
||||||
|
vec![*bd.next().unwrap(), *bd.next().unwrap()]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
self.direction = u16::from_be_bytes(
|
||||||
|
vec![*bd.next().unwrap(), *bd.next().unwrap()]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
let mut tmptime: [u8; 6] = [0; 6];
|
||||||
|
for i in 0..tmptime.len() {
|
||||||
|
tmptime[i] = *bd.next().unwrap();
|
||||||
|
}
|
||||||
|
let code = BcdNumber::try_from(&tmptime as &[u8]).unwrap();
|
||||||
|
self.time = code.to_u64().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_reply(&self, answer_id: u16, serial: u16) -> PlatformUniversalResponse {
|
||||||
|
let mut res = PlatformUniversalResponse::default();
|
||||||
|
res.answer_serial_no = serial;
|
||||||
|
res.answer_id = answer_id;
|
||||||
|
res.result = TerminalRegistrationResult::Success as u8;
|
||||||
|
res
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod body;
|
mod body;
|
||||||
pub mod error;
|
mod error;
|
||||||
|
|
||||||
use body::*;
|
use body::*;
|
||||||
use error::*;
|
use error::*;
|
||||||
@ -20,12 +20,14 @@ const PROPS_RESERVED_MASK: u16 = 0xC000;
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const PROPS_DATAENCRYPTION_MASK: u16 = 0x0E00;
|
const PROPS_DATAENCRYPTION_MASK: u16 = 0x0E00;
|
||||||
|
|
||||||
pub fn parse_inbound_msg(rawdata: &mut DataWrapper) -> std::result::Result<Message, MessageError> {
|
pub fn parse_inbound_msg(
|
||||||
|
rawdata: &mut InboundDataWrapper,
|
||||||
|
) -> std::result::Result<Message, MessageError> {
|
||||||
let mut msg: Message = Message::default();
|
let mut msg: Message = Message::default();
|
||||||
|
|
||||||
match msg.parse_header(rawdata) {
|
match msg.parse_header(rawdata) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
msg.check(rawdata);
|
msg.inbound_check(rawdata);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("error parsing header {e}");
|
println!("error parsing header {e}");
|
||||||
@ -37,30 +39,49 @@ pub fn parse_inbound_msg(rawdata: &mut DataWrapper) -> std::result::Result<Messa
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct DataWrapper {
|
pub struct InboundDataWrapper {
|
||||||
pub data: VecDeque<u8>,
|
pub data: VecDeque<u8>,
|
||||||
pub count: usize,
|
pub count: usize,
|
||||||
|
pub start: bool,
|
||||||
|
pub end: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DataWrapper {
|
impl InboundDataWrapper {
|
||||||
pub fn new(data: Vec<u8>) -> DataWrapper {
|
pub fn new(data: Vec<u8>) -> InboundDataWrapper {
|
||||||
DataWrapper {
|
InboundDataWrapper {
|
||||||
data: data.into(),
|
data: data.into(),
|
||||||
count: 0,
|
count: 0,
|
||||||
|
start: false,
|
||||||
|
end: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for DataWrapper {
|
impl Iterator for InboundDataWrapper {
|
||||||
type Item = u8;
|
type Item = u8;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let res: Option<u8>;
|
let res: Option<u8>;
|
||||||
|
|
||||||
if self.count < 6 {
|
loop {
|
||||||
res = self.data.pop_front()
|
match self.data.pop_front() {
|
||||||
} else {
|
Some(o) => {
|
||||||
res = None
|
if o == FLAGDELIMITER {
|
||||||
|
if self.start {
|
||||||
|
self.end = true;
|
||||||
|
res = None;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
self.start = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
res = Some(o);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
res = None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
|
|
||||||
@ -88,22 +109,22 @@ impl std::fmt::Display for Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
pub fn parse_header(
|
fn parse_header(
|
||||||
&mut self,
|
&mut self,
|
||||||
rawdata: &mut DataWrapper,
|
rawdata: &mut InboundDataWrapper,
|
||||||
) -> std::result::Result<(), NotOurProtocolError> {
|
) -> std::result::Result<(), NotOurProtocolError> {
|
||||||
let mut data = rawdata.data.clone().into_iter();
|
let data = rawdata.into_iter();
|
||||||
let first_byte = data.next().unwrap();
|
self.header.id = u16::from_be_bytes(
|
||||||
if first_byte != FLAGDELIMITER {
|
vec![data.next().unwrap(), data.next().unwrap()]
|
||||||
return Err(NotOurProtocolError);
|
.try_into()
|
||||||
};
|
.unwrap(),
|
||||||
let mut tmpid = vec![];
|
);
|
||||||
tmpid.push(data.next().unwrap());
|
|
||||||
tmpid.push(data.next().unwrap());
|
|
||||||
self.header.id = u16::from_be_bytes(tmpid.try_into().unwrap());
|
|
||||||
//self.header.id = ((data.next().unwrap() as u16) << 8) + data.next().unwrap() as u16;
|
|
||||||
|
|
||||||
self.header.properties = ((data.next().unwrap() as u16) << 8) + data.next().unwrap() as u16;
|
self.header.properties = u16::from_be_bytes(
|
||||||
|
vec![data.next().unwrap(), data.next().unwrap()]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
self.parse_properties();
|
self.parse_properties();
|
||||||
|
|
||||||
for i in 0..self.header.raw_terminal_id.len() {
|
for i in 0..self.header.raw_terminal_id.len() {
|
||||||
@ -111,8 +132,11 @@ impl Message {
|
|||||||
}
|
}
|
||||||
self.parse_terminal_id();
|
self.parse_terminal_id();
|
||||||
|
|
||||||
self.header.serial_number =
|
self.header.serial_number = u16::from_be_bytes(
|
||||||
((data.next().unwrap() as u16) << 8) + data.next().unwrap() as u16;
|
vec![data.next().unwrap(), data.next().unwrap()]
|
||||||
|
.try_into()
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
for _ in 0..self.header.bodylength as usize {
|
for _ in 0..self.header.bodylength as usize {
|
||||||
self.body.push(data.next().unwrap());
|
self.body.push(data.next().unwrap());
|
||||||
@ -120,14 +144,11 @@ impl Message {
|
|||||||
|
|
||||||
self.checksum = data.next().unwrap();
|
self.checksum = data.next().unwrap();
|
||||||
|
|
||||||
if data.next().unwrap() != FLAGDELIMITER {
|
|
||||||
return Err(NotOurProtocolError);
|
|
||||||
}
|
|
||||||
self.parse_body();
|
self.parse_body();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_properties(&mut self) {
|
fn parse_properties(&mut self) {
|
||||||
self.header.bodylength = (self.header.properties & PROPS_SIZE_MASK) as u8;
|
self.header.bodylength = (self.header.properties & PROPS_SIZE_MASK) as u8;
|
||||||
self.header.encryption =
|
self.header.encryption =
|
||||||
((self.header.properties & PROPS_DATAENCRYPTION_MASK) as u16 >> 10) as u8;
|
((self.header.properties & PROPS_DATAENCRYPTION_MASK) as u16 >> 10) as u8;
|
||||||
@ -137,36 +158,29 @@ impl Message {
|
|||||||
self.header.reserved = ((self.header.properties & PROPS_RESERVED_MASK) as u16 >> 14) as u16;
|
self.header.reserved = ((self.header.properties & PROPS_RESERVED_MASK) as u16 >> 14) as u16;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_terminal_id(&mut self) {
|
fn parse_terminal_id(&mut self) {
|
||||||
let code = BcdNumber::try_from(&self.header.raw_terminal_id as &[u8]).unwrap();
|
let code = BcdNumber::try_from(&self.header.raw_terminal_id as &[u8]).unwrap();
|
||||||
self.header.terminal_id = code.to_u64().unwrap();
|
self.header.terminal_id = code.to_u64().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check(&mut self, rawdata: &mut DataWrapper) {
|
pub fn inbound_check(&mut self, rawdata: &mut InboundDataWrapper) {
|
||||||
let mut data = rawdata.data.iter();
|
let data = rawdata.into_iter();
|
||||||
data.next().unwrap();
|
|
||||||
let mut check: u8 = 0;
|
let mut check: u8 = 0;
|
||||||
|
|
||||||
loop {
|
let _ = data.map(|b| check ^= b);
|
||||||
let b = data.next().unwrap();
|
|
||||||
if *b == FLAGDELIMITER {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
check = *b ^ check;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.validate(check);
|
self.inbound_validate(check);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&mut self, check: u8) {
|
fn inbound_validate(&mut self, check: u8) {
|
||||||
self.valid = check == 0;
|
self.valid = check == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_valid(&self) -> bool {
|
fn _is_valid(&self) -> bool {
|
||||||
self.valid
|
self.valid
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_body(&mut self) {
|
fn parse_body(&mut self) {
|
||||||
match self.header.id {
|
match self.header.id {
|
||||||
TerminalUniversalResponse::ID => {
|
TerminalUniversalResponse::ID => {
|
||||||
self.content = MessageType::TerminalUniversalResponse(
|
self.content = MessageType::TerminalUniversalResponse(
|
||||||
@ -253,19 +267,57 @@ impl Message {
|
|||||||
reply.header.serial_number = rng.gen();
|
reply.header.serial_number = rng.gen();
|
||||||
reply.content = MessageType::PlatformUniversalResponse(cnt);
|
reply.content = MessageType::PlatformUniversalResponse(cnt);
|
||||||
}
|
}
|
||||||
|
MessageType::LocationInformationReport(t) => {
|
||||||
|
let cnt =
|
||||||
|
t.generate_reply(LocationInformationReport::ID, inmsg.header.serial_number);
|
||||||
|
reply.header.id = PlatformUniversalResponse::ID;
|
||||||
|
reply.header.raw_terminal_id = inmsg.header.raw_terminal_id;
|
||||||
|
reply.header.properties = cnt.to_raw().len() as u16;
|
||||||
|
reply.header.serial_number = rng.gen();
|
||||||
|
reply.content = MessageType::PlatformUniversalResponse(cnt);
|
||||||
|
}
|
||||||
|
MessageType::TerminalHeartbeat(t) => {
|
||||||
|
let cnt = t.generate_reply(TerminalHeartbeat::ID, inmsg.header.serial_number);
|
||||||
|
reply.header.id = PlatformUniversalResponse::ID;
|
||||||
|
reply.header.raw_terminal_id = inmsg.header.raw_terminal_id;
|
||||||
|
reply.header.properties = cnt.to_raw().len() as u16;
|
||||||
|
reply.header.serial_number = rng.gen();
|
||||||
|
reply.content = MessageType::PlatformUniversalResponse(cnt);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("no type");
|
println!("no type");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
reply.outbound_finalize();
|
||||||
Some(reply)
|
Some(reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_raw(&self) -> VecDeque<u8> {
|
pub fn store(inmsg: &Message) {
|
||||||
let mut resp: VecDeque<u8> = vec![].into();
|
match inmsg.content {
|
||||||
|
MessageType::LocationInformationReport(ref t) => {
|
||||||
|
println!("{:?}", t);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn outbound_finalize(&mut self) {
|
||||||
let mut checksum: u8 = 0;
|
let mut checksum: u8 = 0;
|
||||||
|
|
||||||
|
for v in vec![self.header.to_raw(), self.content.to_raw()] {
|
||||||
|
for b in v {
|
||||||
|
checksum = checksum ^ b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.checksum = checksum;
|
||||||
|
self.valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_raw(&mut self) -> VecDeque<u8> {
|
||||||
|
let mut resp: VecDeque<u8> = vec![].into();
|
||||||
|
|
||||||
for b in self.header.to_raw() {
|
for b in self.header.to_raw() {
|
||||||
resp.push_back(b);
|
resp.push_back(b);
|
||||||
}
|
}
|
||||||
@ -274,11 +326,7 @@ impl Message {
|
|||||||
resp.push_back(b);
|
resp.push_back(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
for b in resp.iter() {
|
resp.push_back(self.checksum);
|
||||||
checksum = checksum ^ b;
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.push_back(checksum);
|
|
||||||
|
|
||||||
resp.push_front(FLAGDELIMITER);
|
resp.push_front(FLAGDELIMITER);
|
||||||
resp.push_back(FLAGDELIMITER);
|
resp.push_back(FLAGDELIMITER);
|
||||||
@ -371,23 +419,3 @@ impl std::fmt::Display for MessageType {
|
|||||||
write!(f, "{:?}", self)
|
write!(f, "{:?}", self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
macro_rules! generate_switch {
|
|
||||||
($($t:ty),*) => {
|
|
||||||
$(
|
|
||||||
//impl BodyMessage for $t {
|
|
||||||
// fn build() {}
|
|
||||||
// fn body_to_iter<'a>(&'a self, rawbody: &'a Vec<u8>) -> std::slice::Iter<'a, u8> {
|
|
||||||
// rawbody.into_iter()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
impl $t {
|
|
||||||
pub fn new(rawbody: &Vec<u8>) -> Self {
|
|
||||||
let mut res = Self::default();
|
|
||||||
res.parse(rawbody);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
})*
|
|
||||||
};
|
|
||||||
}*/
|
|
||||||
|
Loading…
Reference in New Issue
Block a user