1use crate::ClientError;
8use bytes::{Buf, BufMut, Bytes, BytesMut};
9use core::marker::PhantomData;
10use rseip_core::{codec::*, Error};
11use smallvec::SmallVec;
12
13#[allow(clippy::upper_case_acronyms)]
15#[allow(unused)]
16pub type BOOL = bool;
17#[allow(clippy::upper_case_acronyms)]
19#[allow(unused)]
20pub type DWORD = u32;
21#[allow(clippy::upper_case_acronyms)]
23#[allow(unused)]
24pub type SINT = i8;
25#[allow(clippy::upper_case_acronyms)]
27#[allow(unused)]
28pub type INT = i16;
29#[allow(clippy::upper_case_acronyms)]
31#[allow(unused)]
32pub type DINT = i32;
33#[allow(clippy::upper_case_acronyms)]
35#[allow(unused)]
36pub type LINT = i64;
37#[allow(clippy::upper_case_acronyms)]
39#[allow(unused)]
40pub type REAL = f32;
41
42#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub enum TagType {
45 Bool,
47 Dword,
49 Sint,
51 Int,
53 Dint,
55 Lint,
57 Real,
59 Structure(u16),
61}
62
63impl TagType {
64 #[inline]
66 pub fn type_code(&self) -> u16 {
67 match self {
68 Self::Bool => 0xC1,
69 Self::Dword => 0xD3,
70 Self::Sint => 0xC2,
71 Self::Int => 0xC3,
72 Self::Dint => 0xC4,
73 Self::Lint => 0xC5,
74 Self::Real => 0xCA,
75 Self::Structure { .. } => 0x02A0,
76 }
77 }
78
79 pub fn is_structure(&self) -> bool {
81 match self {
82 Self::Structure(_) => true,
83 _ => false,
84 }
85 }
86
87 pub fn is_atomic(&self) -> bool {
89 !self.is_structure()
90 }
91
92 pub fn structure_handle(&self) -> Option<u16> {
94 match self {
95 Self::Structure(v) => Some(*v),
96 _ => None,
97 }
98 }
99}
100
101impl Encode for TagType {
102 #[inline]
103 fn encode_by_ref<A: Encoder>(
104 &self,
105 buf: &mut BytesMut,
106 encoder: &mut A,
107 ) -> Result<(), A::Error> {
108 match self {
109 Self::Bool => {
110 encoder.encode_u16(0xC1, buf)?;
111 }
112 Self::Sint => {
113 encoder.encode_u16(0xC2, buf)?;
114 }
115 Self::Int => {
116 encoder.encode_u16(0xC3, buf)?;
117 }
118 Self::Dint => {
119 encoder.encode_u16(0xC4, buf)?;
120 }
121 Self::Real => {
122 encoder.encode_u16(0xCA, buf)?;
123 }
124 Self::Dword => {
125 encoder.encode_u16(0xD3, buf)?;
126 }
127 Self::Lint => {
128 encoder.encode_u16(0xC5, buf)?;
129 }
130 Self::Structure(handle) => {
131 encoder.encode(&[0xA0, 0x02], buf)?;
132 encoder.encode_u16(*handle, buf)?;
133 }
134 }
135 Ok(())
136 }
137
138 #[inline(always)]
139 fn bytes_count(&self) -> usize {
140 match self {
141 Self::Structure(_) => 4,
142 _ => 2,
143 }
144 }
145}
146
147impl<'de> Decode<'de> for TagType {
148 #[inline]
149 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
150 where
151 D: Decoder<'de>,
152 {
153 decoder.ensure_size(3)?;
154 let type_code = decoder.decode_u16();
155 let val = match type_code {
156 0xC2 => TagType::Sint,
157 0xC3 => TagType::Int,
158 0xC4 => TagType::Dint,
159 0xCA => TagType::Real,
160 0xD3 => TagType::Dword,
161 0xC5 => TagType::Lint,
162 0xC1 => TagType::Bool,
163 0x02A0 => {
164 decoder.ensure_size(2)?;
165 TagType::Structure(decoder.decode_u16())
166 }
167 _ => {
168 return Err(Error::custom(format!(
169 "unexpected type code: {}",
170 type_code
171 )))
172 }
173 };
174 Ok(val)
175 }
176}
177
178#[derive(Debug, Clone, PartialEq, Eq)]
179pub struct TagValue<V> {
180 pub tag_type: TagType,
181 pub value: V,
182}
183
184macro_rules! impl_atomic {
185 ($ty:ty, $size: tt) => {
186 impl<'de> Decode<'de> for TagValue<$ty> {
187 #[inline]
188 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
189 where
190 D: Decoder<'de>,
191 {
192 let tag_type = decoder.decode_any()?;
193 let value = decoder.decode_any()?;
194 Ok(Self { tag_type, value })
195 }
196 }
197
198 impl Encode for TagValue<$ty> {
199 #[inline]
200 fn encode<A: Encoder>(
201 self,
202 buf: &mut BytesMut,
203 encoder: &mut A,
204 ) -> Result<(), A::Error> {
205 self.tag_type.encode(buf, encoder)?;
206 buf.put_slice(&[1, 0]);
207 self.value.encode(buf, encoder)?;
208 Ok(())
209 }
210 #[inline]
211 fn encode_by_ref<A: Encoder>(
212 &self,
213 buf: &mut BytesMut,
214 encoder: &mut A,
215 ) -> Result<(), A::Error> {
216 self.tag_type.encode(buf, encoder)?;
217 buf.put_slice(&[1, 0]);
218 self.value.encode_by_ref(buf, encoder)?;
219 Ok(())
220 }
221
222 #[inline]
223 fn bytes_count(&self) -> usize {
224 self.tag_type.bytes_count() + 2 + $size
225 }
226 }
227 };
228}
229
230impl_atomic!(bool, 1);
231impl_atomic!(i8, 1);
232impl_atomic!(u8, 1);
233impl_atomic!(i16, 2);
234impl_atomic!(u16, 2);
235impl_atomic!(i32, 4);
236impl_atomic!(u32, 4);
237impl_atomic!(i64, 8);
238impl_atomic!(u64, 8);
239impl_atomic!(f32, 4);
240impl_atomic!(f64, 8);
241
242macro_rules! impl_seq {
243 ($ty:tt) => {
244 impl<T> Encode for TagValue<$ty<T>>
245 where
246 T: Encode,
247 {
248 #[inline]
249 fn encode<A: Encoder>(self, buf: &mut BytesMut, encoder: &mut A) -> Result<(), A::Error>
250 where
251 Self: Sized,
252 {
253 self.tag_type.encode(buf, encoder)?;
254 encoder.encode_u16(self.value.len() as u16, buf)?;
255 self.value.encode(buf, encoder)?;
256 Ok(())
257 }
258
259 #[inline]
260 fn encode_by_ref<A: Encoder>(
261 &self,
262 buf: &mut BytesMut,
263 encoder: &mut A,
264 ) -> Result<(), A::Error> {
265 self.tag_type.encode(buf, encoder)?;
266 encoder.encode_u16(self.value.len() as u16, buf)?;
267 self.value.encode_by_ref(buf, encoder)?;
268 Ok(())
269 }
270
271 #[inline]
272 fn bytes_count(&self) -> usize {
273 self.tag_type.bytes_count() + 2 + self.value.bytes_count()
274 }
275 }
276 };
277}
278
279impl_seq!(Vec);
280
281impl<T, const N: usize> Encode for TagValue<[T; N]>
282where
283 T: Encode,
284{
285 #[inline]
286 fn encode<A: Encoder>(self, buf: &mut BytesMut, encoder: &mut A) -> Result<(), A::Error>
287 where
288 Self: Sized,
289 {
290 self.tag_type.encode(buf, encoder)?;
291 encoder.encode_u16(self.value.len() as u16, buf)?;
292 self.value.encode(buf, encoder)?;
293 Ok(())
294 }
295
296 #[inline]
297 fn encode_by_ref<A: Encoder>(
298 &self,
299 buf: &mut BytesMut,
300 encoder: &mut A,
301 ) -> Result<(), A::Error> {
302 self.tag_type.encode(buf, encoder)?;
303 encoder.encode_u16(self.value.len() as u16, buf)?;
304 self.value.encode_by_ref(buf, encoder)?;
305 Ok(())
306 }
307
308 #[inline]
309 fn bytes_count(&self) -> usize {
310 self.tag_type.bytes_count() + 2 + self.value.bytes_count()
311 }
312}
313
314impl<T> Encode for TagValue<&[T]>
315where
316 T: Encode,
317{
318 #[inline]
319 fn encode_by_ref<A: Encoder>(
320 &self,
321 buf: &mut BytesMut,
322 encoder: &mut A,
323 ) -> Result<(), A::Error> {
324 self.tag_type.encode(buf, encoder)?;
325 encoder.encode_u16(self.value.len() as u16, buf)?;
326 for item in self.value.iter() {
327 item.encode_by_ref(buf, encoder)?;
328 }
329 Ok(())
330 }
331
332 #[inline]
333 fn bytes_count(&self) -> usize {
334 self.tag_type.bytes_count() + 2 + self.value.iter().map(|v| v.bytes_count()).sum::<usize>()
335 }
336}
337
338impl<'de> Decode<'de> for TagValue<Bytes> {
339 #[inline]
340 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
341 where
342 D: Decoder<'de>,
343 {
344 let tag_type: TagType = decoder.decode_any()?;
345 let data: BytesHolder = decoder.decode_any()?;
346 Ok(Self {
347 tag_type,
348 value: data.into(),
349 })
350 }
351}
352
353impl<'de, T> Decode<'de> for TagValue<Vec<T>>
354where
355 T: Decode<'de>,
356{
357 #[inline]
358 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
359 where
360 D: Decoder<'de>,
361 {
362 let tag_type: TagType = decoder.decode_any()?;
363 let mut data = Vec::new();
364 while decoder.buf().has_remaining() {
365 let v: T = decoder.decode_any()?;
366 data.push(v);
367 }
368 Ok(Self {
369 tag_type,
370 value: data,
371 })
372 }
373}
374
375impl<'de, T> Decode<'de> for TagValue<SmallVec<T>>
376where
377 T: smallvec::Array,
378 T::Item: Decode<'de>,
379{
380 #[inline]
381 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
382 where
383 D: Decoder<'de>,
384 {
385 let tag_type: TagType = decoder.decode_any()?;
386 let mut data = SmallVec::new();
387 while decoder.buf().has_remaining() {
388 let v: T::Item = decoder.decode_any()?;
389 data.push(v);
390 }
391 Ok(Self {
392 tag_type,
393 value: data,
394 })
395 }
396}
397
398#[derive(Debug)]
399pub struct TagValueTypedIter<T> {
400 tag_type: TagType,
401 decoder: LittleEndianDecoder<ClientError>,
402 _marker: PhantomData<T>,
403}
404
405impl<T> TagValueTypedIter<T> {
406 #[allow(unused)]
407 pub fn tag_type(&self) -> TagType {
408 self.tag_type
409 }
410
411 pub fn from_bytes(buf: Bytes) -> Result<Self, ClientError> {
412 let mut decoder = LittleEndianDecoder::new(buf);
413 let tag_type = decoder.decode_any()?;
414 Ok(Self {
415 tag_type,
416 decoder,
417 _marker: Default::default(),
418 })
419 }
420}
421
422impl<'de, T> Iterator for TagValueTypedIter<T>
423where
424 T: Decode<'de>,
425{
426 type Item = Result<T, ClientError>;
427 #[inline]
428 fn next(&mut self) -> Option<Self::Item> {
429 if self.decoder.has_remaining() {
430 Some(self.decoder.decode_any())
431 } else {
432 None
433 }
434 }
435}
436
437impl<'de, T> Decode<'de> for TagValueTypedIter<T> {
438 #[inline]
439 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
440 where
441 D: Decoder<'de>,
442 {
443 let tag_type: TagType = decoder.decode_any()?;
444 let len = decoder.buf_mut().remaining();
445 let buf = decoder.buf_mut().copy_to_bytes(len);
446 let res = Self {
447 tag_type,
448 decoder: LittleEndianDecoder::new(buf),
449 _marker: Default::default(),
450 };
451 Ok(res)
452 }
453}
454
455#[derive(Debug)]
456pub struct TagValueIter {
457 tag_type: TagType,
458 decoder: LittleEndianDecoder<ClientError>,
459}
460
461impl TagValueIter {
462 #[allow(unused)]
463 pub fn tag_type(&self) -> TagType {
464 self.tag_type
465 }
466
467 pub fn from_bytes(buf: Bytes) -> Result<Self, ClientError> {
468 let mut decoder = LittleEndianDecoder::new(buf);
469 let tag_type = decoder.decode_any()?;
470 Ok(Self { tag_type, decoder })
471 }
472}
473
474impl TagValueIter {
475 #[inline]
476 pub fn next<'de, T>(&mut self) -> Option<Result<T, ClientError>>
477 where
478 T: Decode<'de>,
479 {
480 if self.decoder.has_remaining() {
481 Some(self.decoder.decode_any())
482 } else {
483 None
484 }
485 }
486}
487
488impl<'de> Decode<'de> for TagValueIter {
489 #[inline]
490 fn decode<D>(mut decoder: D) -> Result<Self, D::Error>
491 where
492 D: Decoder<'de>,
493 {
494 let tag_type: TagType = decoder.decode_any()?;
495 let len = decoder.buf_mut().remaining();
496 let buf = decoder.buf_mut().copy_to_bytes(len);
497 let res = Self {
498 tag_type,
499 decoder: LittleEndianDecoder::new(buf),
500 };
501 Ok(res)
502 }
503}