Skip to main content

bacnet_rs/encoding/
mod.rs

1//! BACnet Encoding and Decoding Utilities
2//!
3//! This module provides comprehensive functionality for encoding and decoding BACnet protocol data
4//! according to ASHRAE Standard 135. It handles the serialization and deserialization of all
5//! BACnet data types, application tags, and protocol structures.
6//!
7//! # Overview
8//!
9//! The BACnet encoding system uses a tag-length-value (TLV) format where each data element
10//! consists of:
11//!
12//! - **Tag**: Identifies the data type and context
13//! - **Length**: Specifies the length of the value (for variable-length types)
14//! - **Value**: The actual data content
15//!
16//! This module provides functionality for:
17//!
18//! - **Primitive Types**: Boolean, Unsigned/Signed integers, Real numbers, Double precision, etc.
19//! - **String Types**: Character strings, Bit strings, Octet strings
20//! - **Time Types**: Date, Time, DateTime values
21//! - **Object Types**: Object identifiers, Property identifiers
22//! - **Constructed Types**: Arrays, Lists, Sequences
23//! - **Context Tags**: Application-specific encoding contexts
24//!
25//! # Application Tags
26//!
27//! BACnet defines standard application tags for common data types:
28//!
29//! | Tag | Type | Description |
30//! |-----|------|-------------|
31//! | 0 | Null | No value |
32//! | 1 | Boolean | True/False |
33//! | 2 | Unsigned Integer | 8, 16, 24, or 32-bit unsigned |
34//! | 3 | Signed Integer | 8, 16, 24, or 32-bit signed |
35//! | 4 | Real | 32-bit IEEE 754 float |
36//! | 5 | Double | 64-bit IEEE 754 double |
37//! | 6 | Octet String | Arbitrary byte sequence |
38//! | 7 | Character String | Text with encoding indicator |
39//! | 8 | Bit String | Bit field with unused bits count |
40//! | 9 | Enumerated | Unsigned integer representing enumeration |
41//! | 10 | Date | Year, month, day, day-of-week |
42//! | 11 | Time | Hour, minute, second, hundredths |
43//! | 12 | Object Identifier | Object type and instance |
44//!
45//! # Examples
46//!
47//! ## Encoding Basic Types
48//!
49//! ```rust
50//! use bacnet_rs::encoding::{encode_unsigned, encode_real, ApplicationTag};
51//!
52//! let mut buffer = Vec::new();
53//!
54//! // Encode an unsigned integer with application tag
55//! encode_unsigned(&mut buffer, 42).unwrap();
56//!
57//! // Encode a real number with application tag
58//! encode_real(&mut buffer, 23.5).unwrap();
59//!
60//! println!("Encoded {} bytes", buffer.len());
61//! ```
62//!
63//! ## Decoding Basic Types
64//!
65//! ```rust
66//! use bacnet_rs::encoding::{decode_unsigned, ApplicationTag};
67//!
68//! // Sample encoded data (tag + value)
69//! let data = vec![0x21, 0x2A]; // Unsigned integer 42
70//!
71//! // Decode the value
72//! let (value, consumed) = decode_unsigned(&data).unwrap();
73//! assert_eq!(value, 42);
74//! assert_eq!(consumed, 2);
75//! ```
76//!
77//! ## Working with Application Tags
78//!
79//! ```rust
80//! use bacnet_rs::encoding::{ApplicationTag, decode_application_tag};
81//!
82//! let data = vec![0x21, 0x2A]; // Unsigned integer
83//! let (tag, length, consumed) = decode_application_tag(&data).unwrap();
84//! assert_eq!(tag, ApplicationTag::UnsignedInt);
85//! ```
86//!
87//! ## Context-Specific Encoding
88//!
89//! ```rust
90//! use bacnet_rs::encoding::{encode_context_unsigned, decode_context_unsigned};
91//!
92//! // Encode with context tag 3
93//! let buffer = encode_context_unsigned(1000, 3).unwrap();
94//!
95//! // Decode with expected context tag 3
96//! let (value, consumed) = decode_context_unsigned(&buffer, 3).unwrap();
97//! assert_eq!(value, 1000);
98//! ```
99//!
100//! # Error Handling
101//!
102//! Encoding operations can fail for several reasons:
103//!
104//! - **Buffer Overflow**: Output buffer is too small
105//! - **Invalid Data**: Input data is malformed or invalid
106//! - **Type Mismatch**: Data doesn't match expected type
107//! - **Length Error**: Incorrect length fields
108//!
109//! ```rust
110//! use bacnet_rs::encoding::{EncodingError, decode_unsigned};
111//!
112//! let invalid_data = vec![0x21]; // Missing value byte
113//! match decode_unsigned(&invalid_data) {
114//!     Ok((value, _)) => println!("Value: {}", value),
115//!     Err(EncodingError::BufferUnderflow) => println!("Not enough data"),
116//!     Err(e) => println!("Other error: {:?}", e),
117//! }
118//! ```
119//!
120//! # Performance Notes
121//!
122//! - Encoding functions write directly to provided buffers for efficiency
123//! - Decoding functions return both the decoded value and bytes consumed
124//! - No dynamic allocation is required for basic encoding/decoding operations
125//! - Context tag validation is performed during decoding for safety
126
127#[cfg(feature = "std")]
128use std::error::Error;
129
130#[cfg(not(feature = "std"))]
131use core::fmt;
132
133#[cfg(feature = "std")]
134use std::fmt;
135
136#[cfg(not(feature = "std"))]
137use alloc::{string::String, vec::Vec};
138
139use crate::object::ObjectIdentifier;
140
141/// Result type for encoding operations
142#[cfg(feature = "std")]
143pub type Result<T> = std::result::Result<T, EncodingError>;
144
145#[cfg(not(feature = "std"))]
146pub type Result<T> = core::result::Result<T, EncodingError>;
147
148/// Errors that can occur during encoding/decoding operations
149#[derive(Debug, Clone)]
150pub enum EncodingError {
151    /// Buffer overflow during encoding
152    BufferOverflow,
153    /// Buffer underflow during decoding
154    BufferUnderflow,
155    /// Invalid tag number encountered
156    InvalidTag,
157    /// Invalid length value
158    InvalidLength,
159    /// Unexpected end of data during decoding
160    UnexpectedEndOfData,
161    /// Invalid encoding format
162    InvalidFormat(String),
163    /// Value out of valid range
164    ValueOutOfRange,
165}
166
167impl fmt::Display for EncodingError {
168    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169        match self {
170            EncodingError::BufferOverflow => write!(f, "Buffer overflow during encoding"),
171            EncodingError::BufferUnderflow => write!(f, "Buffer underflow during decoding"),
172            EncodingError::InvalidTag => write!(f, "Invalid tag number encountered"),
173            EncodingError::InvalidLength => write!(f, "Invalid length value"),
174            EncodingError::UnexpectedEndOfData => write!(f, "Unexpected end of data"),
175            EncodingError::InvalidFormat(msg) => write!(f, "Invalid format: {}", msg),
176            EncodingError::ValueOutOfRange => write!(f, "Value out of valid range"),
177        }
178    }
179}
180
181#[cfg(feature = "std")]
182impl Error for EncodingError {}
183
184/// BACnet application tag numbers
185#[derive(Debug, Clone, Copy, PartialEq, Eq)]
186#[repr(u8)]
187pub enum ApplicationTag {
188    Null = 0,
189    Boolean = 1,
190    UnsignedInt = 2,
191    SignedInt = 3,
192    Real = 4,
193    Double = 5,
194    OctetString = 6,
195    CharacterString = 7,
196    BitString = 8,
197    Enumerated = 9,
198    Date = 10,
199    Time = 11,
200    ObjectIdentifier = 12,
201    Reserved13 = 13,
202    Reserved14 = 14,
203    Reserved15 = 15,
204}
205
206#[derive(Debug, Clone, Copy, PartialEq, Eq)]
207pub enum BACnetTag {
208    Application(ApplicationTag),
209    Context(u8),
210}
211
212pub fn decode_tag(data: &[u8]) -> Result<(BACnetTag, usize, usize)> {
213    if data.is_empty() {
214        return Err(EncodingError::InvalidTag);
215    }
216
217    let tag_byte = data[0];
218    let tag_type = tag_byte & 0x08;
219    let mut length = (tag_byte & 0x07) as usize;
220    let mut consumed = 1;
221
222    let tag = if tag_type == 0 {
223        BACnetTag::Application(ApplicationTag::try_from(tag_byte >> 4)?)
224    } else {
225        BACnetTag::Context(tag_byte >> 4)
226    };
227
228    if length == 5 {
229        if data.len() < 2 {
230            return Err(EncodingError::BufferUnderflow);
231        }
232
233        let len_byte = data[1];
234        consumed += 1;
235
236        match len_byte {
237            0..=253 => {
238                length = len_byte as usize;
239            }
240            254 => {
241                if data.len() < 4 {
242                    return Err(EncodingError::BufferUnderflow);
243                }
244                length = u16::from_be_bytes([data[2], data[3]]) as usize;
245                consumed += 2;
246            }
247            255 => {
248                if data.len() < 6 {
249                    return Err(EncodingError::BufferUnderflow);
250                }
251                length = u32::from_be_bytes([data[2], data[3], data[4], data[5]]) as usize;
252                consumed += 4;
253            }
254        }
255    }
256
257    Ok((tag, length, consumed))
258}
259
260/// Encode a BACnet application tag
261pub fn encode_application_tag(buffer: &mut Vec<u8>, tag: ApplicationTag, length: usize) {
262    let tag_byte = if length < 5 {
263        (tag as u8) << 4 | (length as u8)
264    } else {
265        (tag as u8) << 4 | 5
266    };
267
268    buffer.push(tag_byte);
269
270    if length >= 5 {
271        if length < 254 {
272            buffer.push(length as u8);
273        } else if length < 65536 {
274            buffer.push(254);
275            buffer.extend_from_slice(&(length as u16).to_be_bytes());
276        } else {
277            buffer.push(255);
278            buffer.extend_from_slice(&(length as u32).to_be_bytes());
279        }
280    }
281}
282
283/// Decode a BACnet application tag
284pub fn decode_application_tag(data: &[u8]) -> Result<(ApplicationTag, usize, usize)> {
285    if data.is_empty() {
286        return Err(EncodingError::InvalidTag);
287    }
288
289    let tag_byte = data[0];
290    let tag = ApplicationTag::try_from(tag_byte >> 4)?;
291    let mut length = (tag_byte & 0x0F) as usize;
292    let mut consumed = 1;
293
294    if length == 5 {
295        if data.len() < 2 {
296            return Err(EncodingError::BufferUnderflow);
297        }
298
299        let len_byte = data[1];
300        consumed += 1;
301
302        match len_byte {
303            0..=253 => {
304                length = len_byte as usize;
305            }
306            254 => {
307                if data.len() < 4 {
308                    return Err(EncodingError::BufferUnderflow);
309                }
310                length = u16::from_be_bytes([data[2], data[3]]) as usize;
311                consumed += 2;
312            }
313            255 => {
314                if data.len() < 6 {
315                    return Err(EncodingError::BufferUnderflow);
316                }
317                length = u32::from_be_bytes([data[2], data[3], data[4], data[5]]) as usize;
318                consumed += 4;
319            }
320        }
321    }
322
323    Ok((tag, length, consumed))
324}
325
326/// Encode a BACnet boolean value
327pub fn encode_boolean(buffer: &mut Vec<u8>, value: bool) -> Result<()> {
328    encode_application_tag(buffer, ApplicationTag::Boolean, if value { 1 } else { 0 });
329    Ok(())
330}
331
332/// Decode a BACnet boolean value
333pub fn decode_boolean(data: &[u8]) -> Result<(bool, usize)> {
334    let (tag, length, consumed) = decode_application_tag(data)?;
335
336    if tag != ApplicationTag::Boolean {
337        return Err(EncodingError::InvalidTag);
338    }
339
340    let value = match length {
341        0 => false,
342        1 => true,
343        _ => return Err(EncodingError::InvalidLength),
344    };
345
346    Ok((value, consumed))
347}
348
349/// Encode a BACnet unsigned integer
350pub fn encode_unsigned(buffer: &mut Vec<u8>, value: u32) -> Result<()> {
351    let bytes = if value == 0 {
352        vec![0]
353    } else if value <= 0xFF {
354        vec![value as u8]
355    } else if value <= 0xFFFF {
356        (value as u16).to_be_bytes().to_vec()
357    } else if value <= 0xFFFFFF {
358        let bytes = value.to_be_bytes();
359        bytes[1..].to_vec()
360    } else {
361        value.to_be_bytes().to_vec()
362    };
363
364    encode_application_tag(buffer, ApplicationTag::UnsignedInt, bytes.len());
365    buffer.extend_from_slice(&bytes);
366    Ok(())
367}
368
369pub fn encode_unsigned64(buffer: &mut Vec<u8>, value: u64) {
370    let bytes = if value == 0 {
371        vec![0]
372    } else if value <= 0xFF {
373        vec![value as u8]
374    } else if value <= 0xFFFF {
375        (value as u16).to_be_bytes().to_vec()
376    } else if value <= 0xFFFFFF {
377        let bytes = value.to_be_bytes();
378        bytes[1..].to_vec()
379    } else if value <= 0xFFFFFFFF {
380        (value as u32).to_be_bytes().to_vec()
381    } else {
382        value.to_be_bytes().to_vec()
383    };
384
385    encode_application_tag(buffer, ApplicationTag::UnsignedInt, bytes.len());
386    buffer.extend_from_slice(&bytes);
387}
388
389/// Decode a BACnet unsigned integer
390pub fn decode_unsigned(data: &[u8]) -> Result<(u32, usize)> {
391    let (tag, length, mut consumed) = decode_application_tag(data)?;
392
393    if tag != ApplicationTag::UnsignedInt {
394        return Err(EncodingError::InvalidTag);
395    }
396
397    if data.len() < consumed + length {
398        return Err(EncodingError::BufferUnderflow);
399    }
400
401    let value = match length {
402        1 => data[consumed] as u32,
403        2 => u16::from_be_bytes([data[consumed], data[consumed + 1]]) as u32,
404        3 => {
405            let bytes = [0, data[consumed], data[consumed + 1], data[consumed + 2]];
406            u32::from_be_bytes(bytes)
407        }
408        4 => u32::from_be_bytes([
409            data[consumed],
410            data[consumed + 1],
411            data[consumed + 2],
412            data[consumed + 3],
413        ]),
414        _ => return Err(EncodingError::InvalidLength),
415    };
416
417    consumed += length;
418    Ok((value, consumed))
419}
420
421/// Decode a BACnet unsigned integer into a u64
422pub fn decode_unsigned64(data: &[u8]) -> Result<(u64, usize)> {
423    let (tag, length, mut consumed) = decode_application_tag(data)?;
424
425    if tag != ApplicationTag::UnsignedInt {
426        return Err(EncodingError::InvalidTag);
427    }
428
429    if data.len() < consumed + length {
430        return Err(EncodingError::BufferUnderflow);
431    }
432
433    let unused = 8 - length;
434    let mut value = [0; 8];
435    value[unused..].copy_from_slice(&data[consumed..consumed + length]);
436
437    let value = u64::from_be_bytes(value);
438
439    consumed += length;
440    Ok((value, consumed))
441}
442
443/// Encode a BACnet signed integer
444pub fn encode_signed(buffer: &mut Vec<u8>, value: i32) -> Result<()> {
445    let bytes = if (-128..=127).contains(&value) {
446        vec![value as u8]
447    } else if (-32768..=32767).contains(&value) {
448        (value as i16).to_be_bytes().to_vec()
449    } else if (-8388608..=8388607).contains(&value) {
450        let bytes = value.to_be_bytes();
451        bytes[1..].to_vec()
452    } else {
453        value.to_be_bytes().to_vec()
454    };
455
456    encode_application_tag(buffer, ApplicationTag::SignedInt, bytes.len());
457    buffer.extend_from_slice(&bytes);
458    Ok(())
459}
460
461pub fn encode_signed64(buffer: &mut Vec<u8>, value: i64) {
462    let bytes = if (-128..=127).contains(&value) {
463        vec![value as u8]
464    } else if (-32768..=32767).contains(&value) {
465        (value as i16).to_be_bytes().to_vec()
466    } else if (-8388608..=8388607).contains(&value) {
467        let bytes = value.to_be_bytes();
468        bytes[1..].to_vec()
469    } else if (i32::MIN as i64..=i32::MAX as i64).contains(&value) {
470        (value as i32).to_be_bytes().to_vec()
471    } else {
472        value.to_be_bytes().to_vec()
473    };
474
475    encode_application_tag(buffer, ApplicationTag::SignedInt, bytes.len());
476    buffer.extend_from_slice(&bytes);
477}
478
479/// Decode a BACnet signed integer
480pub fn decode_signed(data: &[u8]) -> Result<(i32, usize)> {
481    let (tag, length, mut consumed) = decode_application_tag(data)?;
482
483    if tag != ApplicationTag::SignedInt {
484        return Err(EncodingError::InvalidTag);
485    }
486
487    if data.len() < consumed + length {
488        return Err(EncodingError::BufferUnderflow);
489    }
490
491    let value = match length {
492        1 => data[consumed] as i8 as i32,
493        2 => i16::from_be_bytes([data[consumed], data[consumed + 1]]) as i32,
494        3 => {
495            let sign_extend = if data[consumed] & 0x80 != 0 {
496                0xFF
497            } else {
498                0x00
499            };
500            let bytes = [
501                sign_extend,
502                data[consumed],
503                data[consumed + 1],
504                data[consumed + 2],
505            ];
506            i32::from_be_bytes(bytes)
507        }
508        4 => i32::from_be_bytes([
509            data[consumed],
510            data[consumed + 1],
511            data[consumed + 2],
512            data[consumed + 3],
513        ]),
514        _ => return Err(EncodingError::InvalidLength),
515    };
516
517    consumed += length;
518    Ok((value, consumed))
519}
520
521/// Decode a BACnet signed integer into a i64
522pub fn decode_signed64(data: &[u8]) -> Result<(i64, usize)> {
523    let (tag, length, mut consumed) = decode_application_tag(data)?;
524
525    if tag != ApplicationTag::SignedInt {
526        return Err(EncodingError::InvalidTag);
527    }
528
529    if data.len() < consumed + length {
530        return Err(EncodingError::BufferUnderflow);
531    }
532
533    let unused = 8 - length;
534    let mut value = [0; 8];
535    value[unused..].copy_from_slice(&data[consumed..consumed + length]);
536
537    let value = match length {
538        1 => data[consumed] as i8 as i64,
539        2 => i16::from_be_bytes([data[consumed], data[consumed + 1]]) as i64,
540        v if (3..8).contains(&v) => {
541            let sign_extend = if data[consumed] & 0x80 != 0 {
542                0xFF
543            } else {
544                0x00
545            };
546
547            let mut value = [sign_extend; 8];
548            value[unused..].copy_from_slice(&data[consumed..consumed + length]);
549            i64::from_be_bytes(value)
550        }
551        8 => {
552            let mut value = [0; 8];
553            value.copy_from_slice(&data[consumed..consumed + length]);
554            i64::from_be_bytes(value)
555        }
556        _ => return Err(EncodingError::InvalidLength),
557    };
558
559    consumed += length;
560    Ok((value, consumed))
561}
562
563/// Encode a BACnet real (float) value
564pub fn encode_real(buffer: &mut Vec<u8>, value: f32) -> Result<()> {
565    encode_application_tag(buffer, ApplicationTag::Real, 4);
566    buffer.extend_from_slice(&value.to_be_bytes());
567    Ok(())
568}
569
570/// Decode a BACnet real (float) value
571pub fn decode_real(data: &[u8]) -> Result<(f32, usize)> {
572    let (tag, length, mut consumed) = decode_application_tag(data)?;
573
574    if tag != ApplicationTag::Real {
575        return Err(EncodingError::InvalidTag);
576    }
577
578    if length != 4 {
579        return Err(EncodingError::InvalidLength);
580    }
581
582    if data.len() < consumed + 4 {
583        return Err(EncodingError::BufferUnderflow);
584    }
585
586    let value = f32::from_be_bytes([
587        data[consumed],
588        data[consumed + 1],
589        data[consumed + 2],
590        data[consumed + 3],
591    ]);
592
593    consumed += 4;
594    Ok((value, consumed))
595}
596
597/// Encode a BACnet octet string
598pub fn encode_octet_string(buffer: &mut Vec<u8>, value: &[u8]) -> Result<()> {
599    encode_application_tag(buffer, ApplicationTag::OctetString, value.len());
600    buffer.extend_from_slice(value);
601    Ok(())
602}
603
604/// Decode a BACnet octet string
605pub fn decode_octet_string(data: &[u8]) -> Result<(Vec<u8>, usize)> {
606    let (tag, length, mut consumed) = decode_application_tag(data)?;
607
608    if tag != ApplicationTag::OctetString {
609        return Err(EncodingError::InvalidTag);
610    }
611
612    if data.len() < consumed + length {
613        return Err(EncodingError::BufferUnderflow);
614    }
615
616    let value = data[consumed..consumed + length].to_vec();
617    consumed += length;
618
619    Ok((value, consumed))
620}
621
622/// Encode a BACnet character string
623pub fn encode_character_string(buffer: &mut Vec<u8>, value: &str) -> Result<()> {
624    let string_bytes = value.as_bytes();
625    encode_application_tag(
626        buffer,
627        ApplicationTag::CharacterString,
628        string_bytes.len() + 1,
629    );
630    buffer.push(0); // Character set encoding (0 = ANSI X3.4)
631    buffer.extend_from_slice(string_bytes);
632    Ok(())
633}
634
635/// Decode a BACnet character string
636pub fn decode_character_string(data: &[u8]) -> Result<(String, usize)> {
637    let (tag, length, mut consumed) = decode_application_tag(data)?;
638
639    if tag != ApplicationTag::CharacterString {
640        return Err(EncodingError::InvalidTag);
641    }
642
643    if data.len() < consumed + length || length == 0 {
644        return Err(EncodingError::BufferUnderflow);
645    }
646
647    // Skip character set encoding byte
648    let _encoding = data[consumed];
649    consumed += 1;
650
651    let string_data = &data[consumed..consumed + length - 1];
652    let value = String::from_utf8(string_data.to_vec())
653        .map_err(|_| EncodingError::InvalidFormat("Invalid UTF-8 string".to_string()))?;
654
655    consumed += length - 1;
656
657    Ok((value, consumed))
658}
659
660/// Encode a BACnet enumerated value
661pub fn encode_enumerated(buffer: &mut Vec<u8>, value: u32) {
662    let bytes = if value <= 0xFF {
663        vec![value as u8]
664    } else if value <= 0xFFFF {
665        (value as u16).to_be_bytes().to_vec()
666    } else if value <= 0xFFFFFF {
667        let bytes = value.to_be_bytes();
668        bytes[1..].to_vec()
669    } else {
670        value.to_be_bytes().to_vec()
671    };
672
673    encode_application_tag(buffer, ApplicationTag::Enumerated, bytes.len());
674    buffer.extend_from_slice(&bytes);
675}
676
677/// Decode a BACnet enumerated value
678pub fn decode_enumerated(data: &[u8]) -> Result<(u32, usize)> {
679    let (tag, length, mut consumed) = decode_application_tag(data)?;
680
681    if tag != ApplicationTag::Enumerated {
682        return Err(EncodingError::InvalidTag);
683    }
684
685    if data.len() < consumed + length {
686        return Err(EncodingError::BufferUnderflow);
687    }
688
689    let value = match length {
690        1 => data[consumed] as u32,
691        2 => u16::from_be_bytes([data[consumed], data[consumed + 1]]) as u32,
692        3 => {
693            let bytes = [0, data[consumed], data[consumed + 1], data[consumed + 2]];
694            u32::from_be_bytes(bytes)
695        }
696        4 => u32::from_be_bytes([
697            data[consumed],
698            data[consumed + 1],
699            data[consumed + 2],
700            data[consumed + 3],
701        ]),
702        _ => return Err(EncodingError::InvalidLength),
703    };
704
705    consumed += length;
706    Ok((value, consumed))
707}
708
709/// Encode a BACnet date
710pub fn encode_date(buffer: &mut Vec<u8>, year: u16, month: u8, day: u8, weekday: u8) -> Result<()> {
711    encode_application_tag(buffer, ApplicationTag::Date, 4);
712    buffer.push(((year - 1900) % 256) as u8);
713    buffer.push(month);
714    buffer.push(day);
715    buffer.push(weekday);
716    Ok(())
717}
718
719/// Decode a BACnet date
720pub fn decode_date(data: &[u8]) -> Result<((u16, u8, u8, u8), usize)> {
721    let (tag, length, mut consumed) = decode_application_tag(data)?;
722
723    if tag != ApplicationTag::Date {
724        return Err(EncodingError::InvalidTag);
725    }
726
727    if length != 4 || data.len() < consumed + 4 {
728        return Err(EncodingError::InvalidLength);
729    }
730
731    let year = if data[consumed] == 255 {
732        255
733    } else {
734        1900 + data[consumed] as u16
735    };
736    let month = data[consumed + 1];
737    let day = data[consumed + 2];
738    let weekday = data[consumed + 3];
739
740    consumed += 4;
741    Ok(((year, month, day, weekday), consumed))
742}
743
744/// Encode a BACnet time
745pub fn encode_time(
746    buffer: &mut Vec<u8>,
747    hour: u8,
748    minute: u8,
749    second: u8,
750    hundredths: u8,
751) -> Result<()> {
752    encode_application_tag(buffer, ApplicationTag::Time, 4);
753    buffer.push(hour);
754    buffer.push(minute);
755    buffer.push(second);
756    buffer.push(hundredths);
757    Ok(())
758}
759
760/// Decode a BACnet time
761pub fn decode_time(data: &[u8]) -> Result<((u8, u8, u8, u8), usize)> {
762    let (tag, length, mut consumed) = decode_application_tag(data)?;
763
764    if tag != ApplicationTag::Time {
765        return Err(EncodingError::InvalidTag);
766    }
767
768    if length != 4 || data.len() < consumed + 4 {
769        return Err(EncodingError::InvalidLength);
770    }
771
772    let hour = data[consumed];
773    let minute = data[consumed + 1];
774    let second = data[consumed + 2];
775    let hundredths = data[consumed + 3];
776
777    consumed += 4;
778    Ok(((hour, minute, second, hundredths), consumed))
779}
780
781/// Encode a BACnet object identifier
782pub fn encode_object_identifier(buffer: &mut Vec<u8>, object_id: ObjectIdentifier) -> Result<()> {
783    let object_id: u32 = object_id
784        .try_into()
785        .map_err(|_| EncodingError::ValueOutOfRange)?;
786    encode_application_tag(buffer, ApplicationTag::ObjectIdentifier, 4);
787    buffer.extend_from_slice(&object_id.to_be_bytes());
788    Ok(())
789}
790
791/// Decode a BACnet object identifier
792pub fn decode_object_identifier(data: &[u8]) -> Result<(ObjectIdentifier, usize)> {
793    let (tag, length, mut consumed) = decode_application_tag(data)?;
794
795    if tag != ApplicationTag::ObjectIdentifier {
796        return Err(EncodingError::InvalidTag);
797    }
798
799    if length != 4 || data.len() < consumed + 4 {
800        return Err(EncodingError::InvalidLength);
801    }
802
803    let object_id = u32::from_be_bytes([
804        data[consumed],
805        data[consumed + 1],
806        data[consumed + 2],
807        data[consumed + 3],
808    ]);
809
810    let object_type = object_id >> 22;
811    let instance = object_id & 0x3FFFFF;
812    let object_id = ObjectIdentifier::new(object_type.into(), instance);
813
814    consumed += 4;
815    Ok((object_id, consumed))
816}
817
818/// Encode a BACnet double (64-bit float)
819pub fn encode_double(buffer: &mut Vec<u8>, value: f64) -> Result<()> {
820    encode_application_tag(buffer, ApplicationTag::Double, 8);
821    buffer.extend_from_slice(&value.to_be_bytes());
822    Ok(())
823}
824
825/// Decode a BACnet double (64-bit float)
826pub fn decode_double(data: &[u8]) -> Result<(f64, usize)> {
827    let (tag, length, mut consumed) = decode_application_tag(data)?;
828
829    if tag != ApplicationTag::Double {
830        return Err(EncodingError::InvalidTag);
831    }
832
833    if length != 8 || data.len() < consumed + 8 {
834        return Err(EncodingError::InvalidLength);
835    }
836
837    let value = f64::from_be_bytes([
838        data[consumed],
839        data[consumed + 1],
840        data[consumed + 2],
841        data[consumed + 3],
842        data[consumed + 4],
843        data[consumed + 5],
844        data[consumed + 6],
845        data[consumed + 7],
846    ]);
847
848    consumed += 8;
849    Ok((value, consumed))
850}
851
852/// Encode a context-specific tag
853pub fn encode_context_tag(buffer: &mut Vec<u8>, tag_number: u8, length: usize) -> Result<()> {
854    if tag_number > 14 {
855        return Err(EncodingError::ValueOutOfRange);
856    }
857
858    let tag_byte = if length < 5 {
859        0x08 | (tag_number << 4) | (length as u8)
860    } else {
861        0x08 | (tag_number << 4) | 5
862    };
863
864    buffer.push(tag_byte);
865
866    if length >= 5 {
867        if length < 254 {
868            buffer.push(length as u8);
869        } else if length < 65536 {
870            buffer.push(254);
871            buffer.extend_from_slice(&(length as u16).to_be_bytes());
872        } else {
873            buffer.push(255);
874            buffer.extend_from_slice(&(length as u32).to_be_bytes());
875        }
876    }
877
878    Ok(())
879}
880
881/// Encode a context-specific unsigned integer
882pub fn encode_context_unsigned(value: u32, tag_number: u8) -> Result<Vec<u8>> {
883    let mut buffer = Vec::new();
884
885    // Determine the number of bytes needed for the unsigned value
886    let bytes = if value == 0 {
887        vec![0]
888    } else if value <= 0xFF {
889        vec![value as u8]
890    } else if value <= 0xFFFF {
891        (value as u16).to_be_bytes().to_vec()
892    } else if value <= 0xFFFFFF {
893        let bytes = value.to_be_bytes();
894        bytes[1..].to_vec()
895    } else {
896        value.to_be_bytes().to_vec()
897    };
898
899    // Encode the context tag
900    encode_context_tag(&mut buffer, tag_number, bytes.len())?;
901
902    // Add the value bytes
903    buffer.extend_from_slice(&bytes);
904
905    Ok(buffer)
906}
907
908/// Decode a context-specific tag
909pub fn decode_context_tag(data: &[u8]) -> Result<(u8, usize, usize)> {
910    if data.is_empty() {
911        return Err(EncodingError::InvalidTag);
912    }
913
914    let tag_byte = data[0];
915    if (tag_byte & 0x08) == 0 {
916        return Err(EncodingError::InvalidTag);
917    }
918
919    let tag_number = (tag_byte >> 4) & 0x0F;
920    let mut length = (tag_byte & 0x07) as usize;
921    let mut consumed = 1;
922
923    if length == 5 {
924        if data.len() < 2 {
925            return Err(EncodingError::BufferUnderflow);
926        }
927
928        let len_byte = data[1];
929        consumed += 1;
930
931        match len_byte {
932            0..=253 => {
933                length = len_byte as usize;
934            }
935            254 => {
936                if data.len() < 4 {
937                    return Err(EncodingError::BufferUnderflow);
938                }
939                length = u16::from_be_bytes([data[2], data[3]]) as usize;
940                consumed += 2;
941            }
942            255 => {
943                if data.len() < 6 {
944                    return Err(EncodingError::BufferUnderflow);
945                }
946                length = u32::from_be_bytes([data[2], data[3], data[4], data[5]]) as usize;
947                consumed += 4;
948            }
949        }
950    }
951
952    Ok((tag_number, length, consumed))
953}
954
955/// Decode a context-specific unsigned integer
956pub fn decode_context_unsigned(data: &[u8], expected_tag: u8) -> Result<(u32, usize)> {
957    let (tag_number, length, tag_consumed) = decode_context_tag(data)?;
958
959    if tag_number != expected_tag {
960        return Err(EncodingError::InvalidTag);
961    }
962
963    if data.len() < tag_consumed + length {
964        return Err(EncodingError::BufferUnderflow);
965    }
966
967    let value = match length {
968        0 => 0,
969        1 => data[tag_consumed] as u32,
970        2 => u16::from_be_bytes([data[tag_consumed], data[tag_consumed + 1]]) as u32,
971        3 => {
972            let bytes = [
973                0,
974                data[tag_consumed],
975                data[tag_consumed + 1],
976                data[tag_consumed + 2],
977            ];
978            u32::from_be_bytes(bytes)
979        }
980        4 => u32::from_be_bytes([
981            data[tag_consumed],
982            data[tag_consumed + 1],
983            data[tag_consumed + 2],
984            data[tag_consumed + 3],
985        ]),
986        _ => return Err(EncodingError::InvalidLength),
987    };
988
989    Ok((value, tag_consumed + length))
990}
991
992/// Encode a context-specific enumerated value
993pub fn encode_context_enumerated(value: u32, tag_number: u8) -> Result<Vec<u8>> {
994    // Enumerated values use the same encoding as unsigned integers
995    encode_context_unsigned(value, tag_number)
996}
997
998/// Decode a context-specific enumerated value
999pub fn decode_context_enumerated(data: &[u8], expected_tag: u8) -> Result<(u32, usize)> {
1000    // Enumerated values use the same decoding as unsigned integers
1001    decode_context_unsigned(data, expected_tag)
1002}
1003
1004/// Encode a context-specific object identifier
1005pub fn encode_context_object_id(object_id: ObjectIdentifier, tag_number: u8) -> Result<Vec<u8>> {
1006    let mut buffer = Vec::new();
1007
1008    // Combine object type and instance into 4-byte object identifier
1009    let object_id: u32 = object_id.try_into()?;
1010
1011    // Encode context tag with length 4
1012    encode_context_tag(&mut buffer, tag_number, 4)?;
1013
1014    // Add the object identifier bytes
1015    buffer.extend_from_slice(&object_id.to_be_bytes());
1016
1017    Ok(buffer)
1018}
1019
1020/// Decode a context-specific object identifier
1021pub fn decode_context_object_id(
1022    data: &[u8],
1023    expected_tag: u8,
1024) -> Result<(ObjectIdentifier, usize)> {
1025    let (tag_number, length, tag_consumed) = decode_context_tag(data)?;
1026
1027    if tag_number != expected_tag {
1028        return Err(EncodingError::InvalidTag);
1029    }
1030
1031    if length != 4 {
1032        return Err(EncodingError::InvalidLength);
1033    }
1034
1035    if data.len() < tag_consumed + 4 {
1036        return Err(EncodingError::BufferUnderflow);
1037    }
1038
1039    let object_id = u32::from_be_bytes([
1040        data[tag_consumed],
1041        data[tag_consumed + 1],
1042        data[tag_consumed + 2],
1043        data[tag_consumed + 3],
1044    ]);
1045
1046    Ok((object_id.into(), tag_consumed + 4))
1047}
1048
1049impl TryFrom<u8> for ApplicationTag {
1050    type Error = EncodingError;
1051
1052    fn try_from(value: u8) -> Result<Self> {
1053        match value {
1054            0 => Ok(ApplicationTag::Null),
1055            1 => Ok(ApplicationTag::Boolean),
1056            2 => Ok(ApplicationTag::UnsignedInt),
1057            3 => Ok(ApplicationTag::SignedInt),
1058            4 => Ok(ApplicationTag::Real),
1059            5 => Ok(ApplicationTag::Double),
1060            6 => Ok(ApplicationTag::OctetString),
1061            7 => Ok(ApplicationTag::CharacterString),
1062            8 => Ok(ApplicationTag::BitString),
1063            9 => Ok(ApplicationTag::Enumerated),
1064            10 => Ok(ApplicationTag::Date),
1065            11 => Ok(ApplicationTag::Time),
1066            12 => Ok(ApplicationTag::ObjectIdentifier),
1067            _ => Err(EncodingError::InvalidTag),
1068        }
1069    }
1070}
1071
1072/// Advanced encoding features and optimizations
1073pub mod advanced {
1074    use super::*;
1075    #[cfg(not(feature = "std"))]
1076    use alloc::{collections::BTreeMap, vec::Vec};
1077
1078    /// Buffer manager for efficient encoding/decoding operations
1079    #[derive(Debug)]
1080    pub struct BufferManager {
1081        /// Reusable buffers for encoding operations
1082        #[cfg(feature = "std")]
1083        encode_buffers: Vec<Vec<u8>>,
1084        #[cfg(not(feature = "std"))]
1085        encode_buffers: alloc::vec::Vec<alloc::vec::Vec<u8>>,
1086        /// Maximum buffer size to cache
1087        max_buffer_size: usize,
1088        /// Statistics for buffer usage
1089        pub stats: BufferStats,
1090    }
1091
1092    /// Buffer usage statistics
1093    #[derive(Debug, Default)]
1094    pub struct BufferStats {
1095        pub total_allocations: u64,
1096        pub buffer_reuses: u64,
1097        pub max_buffer_size_used: usize,
1098        pub total_bytes_encoded: u64,
1099        pub total_bytes_decoded: u64,
1100    }
1101
1102    impl BufferManager {
1103        /// Create a new buffer manager
1104        pub fn new(max_buffer_size: usize) -> Self {
1105            Self {
1106                encode_buffers: Vec::with_capacity(8),
1107                max_buffer_size,
1108                stats: BufferStats::default(),
1109            }
1110        }
1111
1112        /// Get a buffer for encoding, reusing if possible
1113        pub fn get_encode_buffer(&mut self) -> Vec<u8> {
1114            if let Some(mut buffer) = self.encode_buffers.pop() {
1115                buffer.clear();
1116                self.stats.buffer_reuses += 1;
1117                buffer
1118            } else {
1119                self.stats.total_allocations += 1;
1120                Vec::with_capacity(256)
1121            }
1122        }
1123
1124        /// Return a buffer for reuse
1125        pub fn return_buffer(&mut self, buffer: Vec<u8>) {
1126            self.stats.total_bytes_encoded += buffer.len() as u64;
1127            if buffer.capacity() <= self.max_buffer_size && self.encode_buffers.len() < 16 {
1128                self.encode_buffers.push(buffer);
1129            }
1130        }
1131
1132        /// Update decoding statistics
1133        pub fn update_decode_stats(&mut self, bytes_decoded: usize) {
1134            self.stats.total_bytes_decoded += bytes_decoded as u64;
1135        }
1136    }
1137
1138    /// Context-specific tag encoding/decoding
1139    pub mod context {
1140        use super::*;
1141
1142        /// Encode a context-specific tag
1143        pub fn encode_context_tag(
1144            buffer: &mut Vec<u8>,
1145            tag_number: u8,
1146            length: usize,
1147        ) -> Result<()> {
1148            if tag_number > 14 {
1149                return Err(EncodingError::ValueOutOfRange);
1150            }
1151
1152            let tag_byte = if length < 5 {
1153                0x08 | (tag_number << 4) | (length as u8)
1154            } else {
1155                0x08 | (tag_number << 4) | 5
1156            };
1157
1158            buffer.push(tag_byte);
1159
1160            if length >= 5 {
1161                if length < 254 {
1162                    buffer.push(length as u8);
1163                } else if length < 65536 {
1164                    buffer.push(254);
1165                    buffer.extend_from_slice(&(length as u16).to_be_bytes());
1166                } else {
1167                    buffer.push(255);
1168                    buffer.extend_from_slice(&(length as u32).to_be_bytes());
1169                }
1170            }
1171
1172            Ok(())
1173        }
1174
1175        /// Decode a context-specific tag
1176        pub fn decode_context_tag(data: &[u8]) -> Result<(u8, usize, usize)> {
1177            if data.is_empty() {
1178                return Err(EncodingError::InvalidTag);
1179            }
1180
1181            let tag_byte = data[0];
1182            if (tag_byte & 0x08) == 0 {
1183                return Err(EncodingError::InvalidTag);
1184            }
1185
1186            let tag_number = (tag_byte >> 4) & 0x0F;
1187            let mut length = (tag_byte & 0x07) as usize;
1188            let mut consumed = 1;
1189
1190            if length == 5 {
1191                if data.len() < 2 {
1192                    return Err(EncodingError::BufferUnderflow);
1193                }
1194
1195                let len_byte = data[1];
1196                consumed += 1;
1197
1198                match len_byte {
1199                    0..=253 => {
1200                        length = len_byte as usize;
1201                    }
1202                    254 => {
1203                        if data.len() < 4 {
1204                            return Err(EncodingError::BufferUnderflow);
1205                        }
1206                        length = u16::from_be_bytes([data[2], data[3]]) as usize;
1207                        consumed += 2;
1208                    }
1209                    255 => {
1210                        if data.len() < 6 {
1211                            return Err(EncodingError::BufferUnderflow);
1212                        }
1213                        length = u32::from_be_bytes([data[2], data[3], data[4], data[5]]) as usize;
1214                        consumed += 4;
1215                    }
1216                }
1217            }
1218
1219            Ok((tag_number, length, consumed))
1220        }
1221
1222        /// Encode opening tag for constructed data
1223        pub fn encode_opening_tag(buffer: &mut Vec<u8>, tag_number: u8) -> Result<()> {
1224            if tag_number > 14 {
1225                return Err(EncodingError::ValueOutOfRange);
1226            }
1227            buffer.push(0x0E | (tag_number << 4));
1228            Ok(())
1229        }
1230
1231        /// Encode closing tag for constructed data
1232        pub fn encode_closing_tag(buffer: &mut Vec<u8>, tag_number: u8) -> Result<()> {
1233            if tag_number > 14 {
1234                return Err(EncodingError::ValueOutOfRange);
1235            }
1236            buffer.push(0x0F | (tag_number << 4));
1237            Ok(())
1238        }
1239    }
1240
1241    /// Bit string encoding/decoding utilities
1242    pub mod bitstring {
1243        use super::*;
1244
1245        /// Encode a bit string
1246        #[allow(clippy::manual_is_multiple_of)]
1247        pub fn encode_bit_string(buffer: &mut Vec<u8>, bits: &[bool]) -> Result<()> {
1248            let byte_count = bits.len().div_ceil(8);
1249            let unused_bits = if bits.len() % 8 == 0 {
1250                0
1251            } else {
1252                8 - (bits.len() % 8)
1253            };
1254
1255            encode_application_tag(buffer, ApplicationTag::BitString, byte_count + 1);
1256            buffer.push(unused_bits as u8);
1257
1258            let mut current_byte = 0u8;
1259            let mut bit_pos = 0;
1260
1261            for &bit in bits {
1262                if bit {
1263                    current_byte |= 1 << (7 - bit_pos);
1264                }
1265                bit_pos += 1;
1266
1267                if bit_pos == 8 {
1268                    buffer.push(current_byte);
1269                    current_byte = 0;
1270                    bit_pos = 0;
1271                }
1272            }
1273
1274            if bit_pos > 0 {
1275                buffer.push(current_byte);
1276            }
1277
1278            Ok(())
1279        }
1280
1281        /// Decode a bit string
1282        pub fn decode_bit_string(data: &[u8]) -> Result<(Vec<bool>, usize)> {
1283            let (tag, length, mut consumed) = decode_application_tag(data)?;
1284
1285            if tag != ApplicationTag::BitString {
1286                return Err(EncodingError::InvalidTag);
1287            }
1288
1289            if length == 0 || data.len() < consumed + length {
1290                return Err(EncodingError::BufferUnderflow);
1291            }
1292
1293            let unused_bits = data[consumed] as usize;
1294            consumed += 1;
1295
1296            if unused_bits > 7 {
1297                return Err(EncodingError::InvalidFormat(
1298                    "Invalid unused bits count".to_string(),
1299                ));
1300            }
1301
1302            let mut bits = Vec::new();
1303            let byte_count = length - 1;
1304
1305            for i in 0..byte_count {
1306                let byte_val = data[consumed + i];
1307                let bits_in_byte = if i == byte_count - 1 {
1308                    8 - unused_bits
1309                } else {
1310                    8
1311                };
1312
1313                for bit_pos in 0..bits_in_byte {
1314                    bits.push((byte_val & (1 << (7 - bit_pos))) != 0);
1315                }
1316            }
1317
1318            consumed += byte_count;
1319            Ok((bits, consumed))
1320        }
1321    }
1322
1323    /// Performance optimization utilities
1324    pub mod perf {
1325        use super::*;
1326
1327        /// Fast path encoder for common data types
1328        pub struct FastEncoder {
1329            buffer: Vec<u8>,
1330        }
1331
1332        impl FastEncoder {
1333            /// Create a new fast encoder
1334            pub fn new(capacity: usize) -> Self {
1335                Self {
1336                    buffer: Vec::with_capacity(capacity),
1337                }
1338            }
1339
1340            /// Get the encoded data
1341            pub fn data(&self) -> &[u8] {
1342                &self.buffer
1343            }
1344
1345            /// Clear the buffer for reuse
1346            pub fn clear(&mut self) {
1347                self.buffer.clear();
1348            }
1349
1350            /// Fast encode unsigned integer (optimized for common sizes)
1351            pub fn encode_unsigned_fast(&mut self, value: u32) -> Result<()> {
1352                match value {
1353                    0 => {
1354                        self.buffer.extend_from_slice(&[0x21, 0x00]);
1355                    }
1356                    1..=255 => {
1357                        self.buffer.extend_from_slice(&[0x21, value as u8]);
1358                    }
1359                    256..=65535 => {
1360                        let bytes = (value as u16).to_be_bytes();
1361                        self.buffer.extend_from_slice(&[0x22]);
1362                        self.buffer.extend_from_slice(&bytes);
1363                    }
1364                    65536..=16777215 => {
1365                        let bytes = value.to_be_bytes();
1366                        self.buffer.extend_from_slice(&[0x23]);
1367                        self.buffer.extend_from_slice(&bytes[1..]);
1368                    }
1369                    _ => {
1370                        let bytes = value.to_be_bytes();
1371                        self.buffer.extend_from_slice(&[0x24]);
1372                        self.buffer.extend_from_slice(&bytes);
1373                    }
1374                }
1375                Ok(())
1376            }
1377
1378            /// Fast encode boolean
1379            pub fn encode_boolean_fast(&mut self, value: bool) -> Result<()> {
1380                self.buffer.push(if value { 0x11 } else { 0x10 });
1381                Ok(())
1382            }
1383
1384            /// Fast encode real (32-bit float)
1385            pub fn encode_real_fast(&mut self, value: f32) -> Result<()> {
1386                self.buffer.push(0x44);
1387                self.buffer.extend_from_slice(&value.to_be_bytes());
1388                Ok(())
1389            }
1390        }
1391    }
1392
1393    /// Validation utilities for encoded data
1394    pub mod validation {
1395        use super::*;
1396
1397        /// Validate encoded BACnet data
1398        pub struct DataValidator {
1399            /// Maximum allowed tag depth for constructed data
1400            max_tag_depth: usize,
1401            /// Maximum allowed string length
1402            max_string_length: usize,
1403        }
1404
1405        impl DataValidator {
1406            /// Create a new data validator
1407            pub fn new(max_tag_depth: usize, max_string_length: usize) -> Self {
1408                Self {
1409                    max_tag_depth,
1410                    max_string_length,
1411                }
1412            }
1413
1414            /// Validate a complete BACnet data structure
1415            pub fn validate(&self, data: &[u8]) -> Result<()> {
1416                self.validate_recursive(data, 0)
1417            }
1418
1419            fn validate_recursive(&self, data: &[u8], depth: usize) -> Result<()> {
1420                if depth > self.max_tag_depth {
1421                    return Err(EncodingError::InvalidFormat(
1422                        "Maximum tag depth exceeded".to_string(),
1423                    ));
1424                }
1425
1426                let mut pos = 0;
1427                while pos < data.len() {
1428                    let (tag, length, consumed) = decode_application_tag(&data[pos..])?;
1429                    pos += consumed;
1430
1431                    match tag {
1432                        ApplicationTag::CharacterString if length > self.max_string_length => {
1433                            return Err(EncodingError::InvalidFormat(
1434                                "String too long".to_string(),
1435                            ));
1436                        }
1437                        ApplicationTag::OctetString if length > self.max_string_length * 2 => {
1438                            return Err(EncodingError::InvalidFormat(
1439                                "Octet string too long".to_string(),
1440                            ));
1441                        }
1442                        _ => {}
1443                    }
1444
1445                    pos += length;
1446                }
1447
1448                Ok(())
1449            }
1450        }
1451    }
1452}
1453
1454/// Encoding stream for efficient multi-value encoding
1455pub struct EncodingStream {
1456    buffer: Vec<u8>,
1457    position: usize,
1458    max_size: usize,
1459}
1460
1461impl EncodingStream {
1462    /// Create a new encoding stream
1463    pub fn new(max_size: usize) -> Self {
1464        Self {
1465            buffer: Vec::with_capacity(max_size),
1466            position: 0,
1467            max_size,
1468        }
1469    }
1470
1471    /// Encode an application tagged value
1472    pub fn encode_tagged<T: EncodableValue>(
1473        &mut self,
1474        tag: ApplicationTag,
1475        value: T,
1476    ) -> Result<()> {
1477        if self.buffer.len() >= self.max_size {
1478            return Err(EncodingError::BufferOverflow);
1479        }
1480        value.encode_to(tag, &mut self.buffer)
1481    }
1482
1483    /// Encode a context tagged value
1484    pub fn encode_context<T: EncodableValue>(&mut self, tag_number: u8, value: T) -> Result<()> {
1485        if self.buffer.len() >= self.max_size {
1486            return Err(EncodingError::BufferOverflow);
1487        }
1488        value.encode_context_to(tag_number, &mut self.buffer)
1489    }
1490
1491    /// Get the encoded data
1492    pub fn data(&self) -> &[u8] {
1493        &self.buffer
1494    }
1495
1496    /// Take the buffer
1497    pub fn into_buffer(self) -> Vec<u8> {
1498        self.buffer
1499    }
1500
1501    /// Clear the stream
1502    pub fn clear(&mut self) {
1503        self.buffer.clear();
1504        self.position = 0;
1505    }
1506}
1507
1508/// Trait for values that can be encoded
1509pub trait EncodableValue {
1510    /// Encode with application tag
1511    fn encode_to(&self, tag: ApplicationTag, buffer: &mut Vec<u8>) -> Result<()>;
1512
1513    /// Encode with context tag
1514    fn encode_context_to(&self, tag_number: u8, buffer: &mut Vec<u8>) -> Result<()>;
1515}
1516
1517impl EncodableValue for bool {
1518    fn encode_to(&self, _tag: ApplicationTag, buffer: &mut Vec<u8>) -> Result<()> {
1519        encode_boolean(buffer, *self)
1520    }
1521
1522    fn encode_context_to(&self, tag_number: u8, buffer: &mut Vec<u8>) -> Result<()> {
1523        advanced::context::encode_context_tag(buffer, tag_number, if *self { 1 } else { 0 })
1524    }
1525}
1526
1527impl EncodableValue for u32 {
1528    fn encode_to(&self, _tag: ApplicationTag, buffer: &mut Vec<u8>) -> Result<()> {
1529        encode_unsigned(buffer, *self)
1530    }
1531
1532    fn encode_context_to(&self, tag_number: u8, buffer: &mut Vec<u8>) -> Result<()> {
1533        let temp_buffer = Vec::new();
1534        let mut temp = temp_buffer;
1535        encode_unsigned(&mut temp, *self)?;
1536        advanced::context::encode_context_tag(buffer, tag_number, temp.len() - 1)?;
1537        buffer.extend_from_slice(&temp[1..]);
1538        Ok(())
1539    }
1540}
1541
1542impl EncodableValue for i32 {
1543    fn encode_to(&self, _tag: ApplicationTag, buffer: &mut Vec<u8>) -> Result<()> {
1544        encode_signed(buffer, *self)
1545    }
1546
1547    fn encode_context_to(&self, tag_number: u8, buffer: &mut Vec<u8>) -> Result<()> {
1548        let temp_buffer = Vec::new();
1549        let mut temp = temp_buffer;
1550        encode_signed(&mut temp, *self)?;
1551        advanced::context::encode_context_tag(buffer, tag_number, temp.len() - 1)?;
1552        buffer.extend_from_slice(&temp[1..]);
1553        Ok(())
1554    }
1555}
1556
1557impl EncodableValue for f32 {
1558    fn encode_to(&self, _tag: ApplicationTag, buffer: &mut Vec<u8>) -> Result<()> {
1559        encode_real(buffer, *self)
1560    }
1561
1562    fn encode_context_to(&self, tag_number: u8, buffer: &mut Vec<u8>) -> Result<()> {
1563        advanced::context::encode_context_tag(buffer, tag_number, 4)?;
1564        buffer.extend_from_slice(&self.to_be_bytes());
1565        Ok(())
1566    }
1567}
1568
1569impl EncodableValue for f64 {
1570    fn encode_to(&self, _tag: ApplicationTag, buffer: &mut Vec<u8>) -> Result<()> {
1571        encode_double(buffer, *self)
1572    }
1573
1574    fn encode_context_to(&self, tag_number: u8, buffer: &mut Vec<u8>) -> Result<()> {
1575        advanced::context::encode_context_tag(buffer, tag_number, 8)?;
1576        buffer.extend_from_slice(&self.to_be_bytes());
1577        Ok(())
1578    }
1579}
1580
1581impl EncodableValue for &str {
1582    fn encode_to(&self, _tag: ApplicationTag, buffer: &mut Vec<u8>) -> Result<()> {
1583        encode_character_string(buffer, self)
1584    }
1585
1586    fn encode_context_to(&self, tag_number: u8, buffer: &mut Vec<u8>) -> Result<()> {
1587        advanced::context::encode_context_tag(buffer, tag_number, self.len() + 1)?;
1588        buffer.push(0); // Character set
1589        buffer.extend_from_slice(self.as_bytes());
1590        Ok(())
1591    }
1592}
1593
1594/// Decoding stream for efficient multi-value decoding
1595pub struct DecodingStream<'a> {
1596    data: &'a [u8],
1597    position: usize,
1598}
1599
1600impl<'a> DecodingStream<'a> {
1601    /// Create a new decoding stream
1602    pub fn new(data: &'a [u8]) -> Self {
1603        Self { data, position: 0 }
1604    }
1605
1606    /// Check if stream has more data
1607    pub fn has_data(&self) -> bool {
1608        self.position < self.data.len()
1609    }
1610
1611    /// Get remaining bytes
1612    pub fn remaining(&self) -> usize {
1613        self.data.len().saturating_sub(self.position)
1614    }
1615
1616    /// Peek at the next tag without consuming
1617    pub fn peek_tag(&self) -> Result<ApplicationTag> {
1618        if self.position >= self.data.len() {
1619            return Err(EncodingError::UnexpectedEndOfData);
1620        }
1621
1622        let tag_byte = self.data[self.position];
1623        let tag = ApplicationTag::try_from(tag_byte >> 4)?;
1624        Ok(tag)
1625    }
1626
1627    /// Decode a boolean
1628    pub fn decode_boolean(&mut self) -> Result<bool> {
1629        let (value, consumed) = decode_boolean(&self.data[self.position..])?;
1630        self.position += consumed;
1631        Ok(value)
1632    }
1633
1634    /// Decode an unsigned integer
1635    pub fn decode_unsigned(&mut self) -> Result<u32> {
1636        let (value, consumed) = decode_unsigned(&self.data[self.position..])?;
1637        self.position += consumed;
1638        Ok(value)
1639    }
1640
1641    /// Decode a signed integer
1642    pub fn decode_signed(&mut self) -> Result<i32> {
1643        let (value, consumed) = decode_signed(&self.data[self.position..])?;
1644        self.position += consumed;
1645        Ok(value)
1646    }
1647
1648    /// Decode a real number
1649    pub fn decode_real(&mut self) -> Result<f32> {
1650        let (value, consumed) = decode_real(&self.data[self.position..])?;
1651        self.position += consumed;
1652        Ok(value)
1653    }
1654
1655    /// Decode a double
1656    pub fn decode_double(&mut self) -> Result<f64> {
1657        let (value, consumed) = decode_double(&self.data[self.position..])?;
1658        self.position += consumed;
1659        Ok(value)
1660    }
1661
1662    /// Decode a character string
1663    pub fn decode_character_string(&mut self) -> Result<String> {
1664        let (value, consumed) = decode_character_string(&self.data[self.position..])?;
1665        self.position += consumed;
1666        Ok(value)
1667    }
1668
1669    /// Decode an octet string
1670    pub fn decode_octet_string(&mut self) -> Result<Vec<u8>> {
1671        let (value, consumed) = decode_octet_string(&self.data[self.position..])?;
1672        self.position += consumed;
1673        Ok(value)
1674    }
1675
1676    /// Decode an enumerated value
1677    pub fn decode_enumerated(&mut self) -> Result<u32> {
1678        let (value, consumed) = decode_enumerated(&self.data[self.position..])?;
1679        self.position += consumed;
1680        Ok(value)
1681    }
1682
1683    /// Decode a date
1684    pub fn decode_date(&mut self) -> Result<(u16, u8, u8, u8)> {
1685        let (value, consumed) = decode_date(&self.data[self.position..])?;
1686        self.position += consumed;
1687        Ok(value)
1688    }
1689
1690    /// Decode a time
1691    pub fn decode_time(&mut self) -> Result<(u8, u8, u8, u8)> {
1692        let (value, consumed) = decode_time(&self.data[self.position..])?;
1693        self.position += consumed;
1694        Ok(value)
1695    }
1696
1697    /// Decode an object identifier
1698    pub fn decode_object_identifier(&mut self) -> Result<ObjectIdentifier> {
1699        let (identifier, consumed) = decode_object_identifier(&self.data[self.position..])?;
1700        self.position += consumed;
1701        Ok(identifier)
1702    }
1703
1704    /// Skip a value
1705    pub fn skip_value(&mut self) -> Result<()> {
1706        let (_tag, length, consumed) = decode_application_tag(&self.data[self.position..])?;
1707        self.position += consumed + length;
1708        Ok(())
1709    }
1710
1711    /// Get current position
1712    pub fn position(&self) -> usize {
1713        self.position
1714    }
1715
1716    /// Set position
1717    pub fn set_position(&mut self, position: usize) -> Result<()> {
1718        if position > self.data.len() {
1719            return Err(EncodingError::ValueOutOfRange);
1720        }
1721        self.position = position;
1722        Ok(())
1723    }
1724}
1725
1726/// Property array encoder
1727#[derive(Default)]
1728pub struct PropertyArrayEncoder {
1729    buffer: Vec<u8>,
1730    count: usize,
1731}
1732
1733impl PropertyArrayEncoder {
1734    /// Create a new property array encoder
1735    pub fn new() -> Self {
1736        Self::default()
1737    }
1738
1739    /// Add a property value
1740    pub fn add_property<T: EncodableValue>(&mut self, property_id: u32, value: T) -> Result<()> {
1741        // Encode property identifier with context tag 0
1742        advanced::context::encode_context_tag(&mut self.buffer, 0, 4)?;
1743        self.buffer.extend_from_slice(&property_id.to_be_bytes());
1744
1745        // Open context tag 1 for value
1746        advanced::context::encode_opening_tag(&mut self.buffer, 1)?;
1747
1748        // Encode the value
1749        value.encode_to(ApplicationTag::Null, &mut self.buffer)?;
1750
1751        // Close context tag 1
1752        advanced::context::encode_closing_tag(&mut self.buffer, 1)?;
1753
1754        self.count += 1;
1755        Ok(())
1756    }
1757
1758    /// Get the encoded data
1759    pub fn data(&self) -> &[u8] {
1760        &self.buffer
1761    }
1762
1763    /// Get the property count
1764    pub fn count(&self) -> usize {
1765        self.count
1766    }
1767
1768    /// Clear the encoder
1769    pub fn clear(&mut self) {
1770        self.buffer.clear();
1771        self.count = 0;
1772    }
1773}
1774
1775/// Error encoder for BACnet error PDUs
1776#[derive(Default)]
1777pub struct ErrorEncoder {
1778    buffer: Vec<u8>,
1779}
1780
1781impl ErrorEncoder {
1782    /// Create a new error encoder
1783    pub fn new() -> Self {
1784        Self::default()
1785    }
1786
1787    /// Encode an error class and code
1788    pub fn encode_error(&mut self, error_class: u32, error_code: u32) -> Result<()> {
1789        // Error class with context tag 0
1790        advanced::context::encode_context_tag(
1791            &mut self.buffer,
1792            0,
1793            if error_class <= 0xFF {
1794                1
1795            } else if error_class <= 0xFFFF {
1796                2
1797            } else {
1798                4
1799            },
1800        )?;
1801        encode_enumerated(&mut self.buffer, error_class);
1802
1803        // Error code with context tag 1
1804        advanced::context::encode_context_tag(
1805            &mut self.buffer,
1806            1,
1807            if error_code <= 0xFF {
1808                1
1809            } else if error_code <= 0xFFFF {
1810                2
1811            } else {
1812                4
1813            },
1814        )?;
1815        encode_enumerated(&mut self.buffer, error_code);
1816
1817        Ok(())
1818    }
1819
1820    /// Get the encoded data
1821    pub fn data(&self) -> &[u8] {
1822        &self.buffer
1823    }
1824
1825    /// Clear the encoder
1826    pub fn clear(&mut self) {
1827        self.buffer.clear();
1828    }
1829}
1830
1831/// Encoding performance analyzer
1832#[derive(Debug, Default)]
1833pub struct EncodingAnalyzer {
1834    /// Encoding operation statistics
1835    pub stats: EncodingStatistics,
1836    /// Performance benchmarks
1837    benchmarks: Vec<EncodingBenchmark>,
1838    /// Error patterns
1839    error_patterns: Vec<ErrorPattern>,
1840}
1841
1842/// Encoding operation statistics
1843#[derive(Debug, Default)]
1844pub struct EncodingStatistics {
1845    /// Total encoding operations
1846    pub total_encodings: u64,
1847    /// Total decoding operations
1848    pub total_decodings: u64,
1849    /// Total bytes encoded
1850    pub bytes_encoded: u64,
1851    /// Total bytes decoded
1852    pub bytes_decoded: u64,
1853    /// Encoding errors
1854    pub encoding_errors: u64,
1855    /// Decoding errors
1856    pub decoding_errors: u64,
1857    /// Average encoding time (microseconds)
1858    pub avg_encode_time_us: f64,
1859    /// Average decoding time (microseconds)
1860    pub avg_decode_time_us: f64,
1861}
1862
1863/// Performance benchmark data
1864#[derive(Debug, Clone)]
1865struct EncodingBenchmark {
1866    /// Data type being benchmarked
1867    _data_type: &'static str,
1868    /// Data size in bytes
1869    _size: usize,
1870    /// Encoding time in microseconds
1871    _encode_time_us: u64,
1872    /// Decoding time in microseconds
1873    _decode_time_us: u64,
1874    /// Timestamp
1875    #[cfg(feature = "std")]
1876    _timestamp: std::time::Instant,
1877}
1878
1879/// Error pattern tracking
1880#[derive(Debug, Clone)]
1881struct ErrorPattern {
1882    /// Error type
1883    error_type: EncodingError,
1884    /// Frequency count
1885    count: u32,
1886    /// Last occurrence
1887    #[cfg(feature = "std")]
1888    last_seen: std::time::Instant,
1889}
1890
1891impl EncodingAnalyzer {
1892    /// Create a new encoding analyzer
1893    pub fn new() -> Self {
1894        Self::default()
1895    }
1896
1897    /// Record an encoding operation
1898    pub fn record_encoding(&mut self, data_type: &'static str, bytes: usize, duration_us: u64) {
1899        self.stats.total_encodings += 1;
1900        self.stats.bytes_encoded += bytes as u64;
1901
1902        // Update average encoding time
1903        let total_time = self.stats.avg_encode_time_us * (self.stats.total_encodings - 1) as f64;
1904        self.stats.avg_encode_time_us =
1905            (total_time + duration_us as f64) / self.stats.total_encodings as f64;
1906
1907        // Store benchmark data
1908        self.benchmarks.push(EncodingBenchmark {
1909            _data_type: data_type,
1910            _size: bytes,
1911            _encode_time_us: duration_us,
1912            _decode_time_us: 0,
1913            #[cfg(feature = "std")]
1914            _timestamp: std::time::Instant::now(),
1915        });
1916
1917        // Keep only recent benchmarks (last 1000)
1918        if self.benchmarks.len() > 1000 {
1919            self.benchmarks.remove(0);
1920        }
1921    }
1922
1923    /// Record a decoding operation
1924    pub fn record_decoding(&mut self, _data_type: &'static str, bytes: usize, duration_us: u64) {
1925        self.stats.total_decodings += 1;
1926        self.stats.bytes_decoded += bytes as u64;
1927
1928        // Update average decoding time
1929        let total_time = self.stats.avg_decode_time_us * (self.stats.total_decodings - 1) as f64;
1930        self.stats.avg_decode_time_us =
1931            (total_time + duration_us as f64) / self.stats.total_decodings as f64;
1932    }
1933
1934    /// Record an encoding error
1935    pub fn record_error(&mut self, error: EncodingError) {
1936        self.stats.encoding_errors += 1;
1937
1938        // Update error pattern
1939        if let Some(pattern) = self
1940            .error_patterns
1941            .iter_mut()
1942            .find(|p| std::mem::discriminant(&p.error_type) == std::mem::discriminant(&error))
1943        {
1944            pattern.count += 1;
1945            #[cfg(feature = "std")]
1946            {
1947                pattern.last_seen = std::time::Instant::now();
1948            }
1949        } else {
1950            self.error_patterns.push(ErrorPattern {
1951                error_type: error,
1952                count: 1,
1953                #[cfg(feature = "std")]
1954                last_seen: std::time::Instant::now(),
1955            });
1956        }
1957    }
1958
1959    /// Get encoding throughput (bytes per second)
1960    pub fn get_encoding_throughput(&self) -> f64 {
1961        if self.stats.avg_encode_time_us > 0.0 {
1962            (self.stats.bytes_encoded as f64 / self.stats.total_encodings as f64)
1963                / (self.stats.avg_encode_time_us / 1_000_000.0)
1964        } else {
1965            0.0
1966        }
1967    }
1968
1969    /// Get decoding throughput (bytes per second)
1970    pub fn get_decoding_throughput(&self) -> f64 {
1971        if self.stats.avg_decode_time_us > 0.0 {
1972            (self.stats.bytes_decoded as f64 / self.stats.total_decodings as f64)
1973                / (self.stats.avg_decode_time_us / 1_000_000.0)
1974        } else {
1975            0.0
1976        }
1977    }
1978
1979    /// Get most common errors
1980    pub fn get_top_errors(&self, limit: usize) -> Vec<(&EncodingError, u32)> {
1981        let mut errors: Vec<_> = self
1982            .error_patterns
1983            .iter()
1984            .map(|p| (&p.error_type, p.count))
1985            .collect();
1986        errors.sort_by_key(|b| std::cmp::Reverse(b.1));
1987        errors.truncate(limit);
1988        errors
1989    }
1990
1991    /// Reset statistics
1992    pub fn reset(&mut self) {
1993        self.stats = EncodingStatistics::default();
1994        self.benchmarks.clear();
1995        self.error_patterns.clear();
1996    }
1997}
1998
1999/// Encoding cache for frequently used values
2000#[derive(Debug)]
2001pub struct EncodingCache {
2002    /// Cached encoded values
2003    cache: Vec<CacheEntry>,
2004    /// Maximum cache size
2005    max_size: usize,
2006    /// Cache hit statistics
2007    pub hits: u64,
2008    /// Cache miss statistics
2009    pub misses: u64,
2010}
2011
2012/// Cache entry
2013#[derive(Debug, Clone)]
2014struct CacheEntry {
2015    /// Hash of the original value
2016    hash: u64,
2017    /// Encoded data
2018    encoded: Vec<u8>,
2019    /// Access count
2020    access_count: u32,
2021    /// Last access time
2022    #[cfg(feature = "std")]
2023    last_access: std::time::Instant,
2024}
2025
2026impl EncodingCache {
2027    /// Create a new encoding cache
2028    pub fn new(max_size: usize) -> Self {
2029        Self {
2030            cache: Vec::with_capacity(max_size),
2031            max_size,
2032            hits: 0,
2033            misses: 0,
2034        }
2035    }
2036
2037    /// Get cached encoding if available
2038    pub fn get(&mut self, hash: u64) -> Option<Vec<u8>> {
2039        if let Some(entry) = self.cache.iter_mut().find(|e| e.hash == hash) {
2040            entry.access_count += 1;
2041            #[cfg(feature = "std")]
2042            {
2043                entry.last_access = std::time::Instant::now();
2044            }
2045            self.hits += 1;
2046            Some(entry.encoded.clone())
2047        } else {
2048            self.misses += 1;
2049            None
2050        }
2051    }
2052
2053    /// Store encoded value in cache
2054    pub fn put(&mut self, hash: u64, encoded: Vec<u8>) {
2055        // Check if already exists
2056        if self.cache.iter().any(|e| e.hash == hash) {
2057            return;
2058        }
2059
2060        // Remove least recently used if cache is full
2061        if self.cache.len() >= self.max_size {
2062            self.cache.sort_by_key(|e| e.access_count);
2063            self.cache.remove(0);
2064        }
2065
2066        self.cache.push(CacheEntry {
2067            hash,
2068            encoded,
2069            access_count: 1,
2070            #[cfg(feature = "std")]
2071            last_access: std::time::Instant::now(),
2072        });
2073    }
2074
2075    /// Clear the cache
2076    pub fn clear(&mut self) {
2077        self.cache.clear();
2078        self.hits = 0;
2079        self.misses = 0;
2080    }
2081
2082    /// Get cache hit ratio
2083    pub fn hit_ratio(&self) -> f64 {
2084        let total = self.hits + self.misses;
2085        if total > 0 {
2086            self.hits as f64 / total as f64
2087        } else {
2088            0.0
2089        }
2090    }
2091}
2092
2093/// Encoding configuration manager
2094#[derive(Debug, Clone)]
2095pub struct EncodingConfig {
2096    /// Use compression for large data
2097    pub use_compression: bool,
2098    /// Compression threshold (bytes)
2099    pub compression_threshold: usize,
2100    /// Enable caching
2101    pub enable_caching: bool,
2102    /// Cache size
2103    pub cache_size: usize,
2104    /// Enable performance tracking
2105    pub enable_performance_tracking: bool,
2106    /// Validation level
2107    pub validation_level: ValidationLevel,
2108    /// Maximum string length
2109    pub max_string_length: usize,
2110    /// Maximum array size
2111    pub max_array_size: usize,
2112}
2113
2114/// Validation levels
2115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2116pub enum ValidationLevel {
2117    /// No validation
2118    None,
2119    /// Basic validation
2120    Basic,
2121    /// Strict validation
2122    Strict,
2123    /// Paranoid validation (slowest)
2124    Paranoid,
2125}
2126
2127impl Default for EncodingConfig {
2128    fn default() -> Self {
2129        Self {
2130            use_compression: false,
2131            compression_threshold: 1024,
2132            enable_caching: true,
2133            cache_size: 1000,
2134            enable_performance_tracking: true,
2135            validation_level: ValidationLevel::Basic,
2136            max_string_length: 4096,
2137            max_array_size: 1000,
2138        }
2139    }
2140}
2141
2142/// High-level encoding manager
2143#[derive(Debug)]
2144pub struct EncodingManager {
2145    /// Configuration
2146    _config: EncodingConfig,
2147    /// Performance analyzer
2148    analyzer: Option<EncodingAnalyzer>,
2149    /// Encoding cache
2150    cache: Option<EncodingCache>,
2151    /// Buffer manager
2152    buffer_manager: advanced::BufferManager,
2153}
2154
2155impl EncodingManager {
2156    /// Create a new encoding manager
2157    pub fn new(config: EncodingConfig) -> Self {
2158        let analyzer = if config.enable_performance_tracking {
2159            Some(EncodingAnalyzer::new())
2160        } else {
2161            None
2162        };
2163
2164        let cache = if config.enable_caching {
2165            Some(EncodingCache::new(config.cache_size))
2166        } else {
2167            None
2168        };
2169
2170        Self {
2171            _config: config,
2172            analyzer,
2173            cache,
2174            buffer_manager: advanced::BufferManager::new(8192),
2175        }
2176    }
2177
2178    /// Encode a value with full management features
2179    pub fn encode<T: EncodableValue>(&mut self, value: T, tag: ApplicationTag) -> Result<Vec<u8>> {
2180        #[cfg(feature = "std")]
2181        let start_time = std::time::Instant::now();
2182
2183        let mut buffer = self.buffer_manager.get_encode_buffer();
2184        let result = value.encode_to(tag, &mut buffer);
2185
2186        #[cfg(feature = "std")]
2187        let duration = start_time.elapsed();
2188
2189        match result {
2190            Ok(_) => {
2191                if let Some(ref mut analyzer) = self.analyzer {
2192                    #[cfg(feature = "std")]
2193                    analyzer.record_encoding("generic", buffer.len(), duration.as_micros() as u64);
2194                    #[cfg(not(feature = "std"))]
2195                    analyzer.record_encoding("generic", buffer.len(), 0);
2196                }
2197
2198                let result_buffer = buffer.clone();
2199                self.buffer_manager.return_buffer(buffer);
2200                Ok(result_buffer)
2201            }
2202            Err(e) => {
2203                if let Some(ref mut analyzer) = self.analyzer {
2204                    analyzer.record_error(e.clone());
2205                }
2206                self.buffer_manager.return_buffer(buffer);
2207                Err(e)
2208            }
2209        }
2210    }
2211
2212    /// Decode a value with full management features
2213    pub fn decode<T>(
2214        &mut self,
2215        data: &[u8],
2216        decoder: impl Fn(&[u8]) -> Result<(T, usize)>,
2217    ) -> Result<T> {
2218        #[cfg(feature = "std")]
2219        let start_time = std::time::Instant::now();
2220
2221        let result = decoder(data);
2222
2223        #[cfg(feature = "std")]
2224        let duration = start_time.elapsed();
2225
2226        match result {
2227            Ok((value, consumed)) => {
2228                if let Some(ref mut analyzer) = self.analyzer {
2229                    #[cfg(feature = "std")]
2230                    analyzer.record_decoding("generic", consumed, duration.as_micros() as u64);
2231                    #[cfg(not(feature = "std"))]
2232                    analyzer.record_decoding("generic", consumed, 0);
2233                }
2234                Ok(value)
2235            }
2236            Err(e) => {
2237                if let Some(ref mut analyzer) = self.analyzer {
2238                    analyzer.record_error(e.clone());
2239                }
2240                Err(e)
2241            }
2242        }
2243    }
2244
2245    /// Get performance statistics
2246    pub fn get_stats(&self) -> Option<&EncodingStatistics> {
2247        self.analyzer.as_ref().map(|a| &a.stats)
2248    }
2249
2250    /// Get cache statistics
2251    pub fn get_cache_stats(&self) -> Option<(u64, u64, f64)> {
2252        self.cache
2253            .as_ref()
2254            .map(|c| (c.hits, c.misses, c.hit_ratio()))
2255    }
2256
2257    /// Reset all statistics
2258    pub fn reset_stats(&mut self) {
2259        if let Some(ref mut analyzer) = self.analyzer {
2260            analyzer.reset();
2261        }
2262        if let Some(ref mut cache) = self.cache {
2263            cache.clear();
2264        }
2265    }
2266}
2267
2268impl Default for EncodingManager {
2269    fn default() -> Self {
2270        Self::new(EncodingConfig::default())
2271    }
2272}
2273
2274#[cfg(test)]
2275mod tests {
2276    use crate::ObjectType;
2277
2278    use super::*;
2279
2280    #[test]
2281    fn test_encode_decode_boolean() {
2282        let mut buffer = Vec::new();
2283
2284        // Test true
2285        encode_boolean(&mut buffer, true).unwrap();
2286        let (value, consumed) = decode_boolean(&buffer).unwrap();
2287        assert!(value);
2288        assert_eq!(consumed, 1);
2289
2290        // Test false
2291        buffer.clear();
2292        encode_boolean(&mut buffer, false).unwrap();
2293        let (value, consumed) = decode_boolean(&buffer).unwrap();
2294        assert!(!value);
2295        assert_eq!(consumed, 1);
2296    }
2297
2298    #[test]
2299    fn test_encode_decode_unsigned() {
2300        let mut buffer = Vec::new();
2301        let test_values = [0, 255, 65535, 16777215, 4294967295];
2302
2303        for &test_value in &test_values {
2304            buffer.clear();
2305            encode_unsigned(&mut buffer, test_value).unwrap();
2306            let (value, _) = decode_unsigned(&buffer).unwrap();
2307            assert_eq!(value, test_value);
2308        }
2309    }
2310
2311    #[test]
2312    fn test_encode_decode_signed() {
2313        let mut buffer = Vec::new();
2314        let test_values = [-128, -1, 0, 1, 127, -32768, 32767, -8388608, 8388607];
2315
2316        for &test_value in &test_values {
2317            buffer.clear();
2318            encode_signed(&mut buffer, test_value).unwrap();
2319            let (value, _) = decode_signed(&buffer).unwrap();
2320            assert_eq!(value, test_value);
2321        }
2322    }
2323
2324    #[test]
2325    fn test_encode_decode_real() {
2326        let mut buffer = Vec::new();
2327        let test_values = [
2328            0.0,
2329            1.0,
2330            -1.0,
2331            std::f32::consts::PI,
2332            -273.15,
2333            f32::MAX,
2334            f32::MIN,
2335        ];
2336
2337        for &test_value in &test_values {
2338            buffer.clear();
2339            encode_real(&mut buffer, test_value).unwrap();
2340            let (value, _) = decode_real(&buffer).unwrap();
2341            assert_eq!(value, test_value);
2342        }
2343    }
2344
2345    #[test]
2346    fn test_encode_decode_character_string() {
2347        let mut buffer = Vec::new();
2348        let test_strings = ["Hello", "BACnet", "Temperature Sensor", ""];
2349
2350        for &test_string in &test_strings {
2351            buffer.clear();
2352            encode_character_string(&mut buffer, test_string).unwrap();
2353            let (value, _) = decode_character_string(&buffer).unwrap();
2354            assert_eq!(value, test_string);
2355        }
2356    }
2357
2358    #[test]
2359    fn test_encode_decode_octet_string() {
2360        let mut buffer = Vec::new();
2361        let test_data = vec![0x01, 0x02, 0x03, 0xFF, 0x00];
2362
2363        encode_octet_string(&mut buffer, &test_data).unwrap();
2364        let (decoded, _) = decode_octet_string(&buffer).unwrap();
2365        assert_eq!(decoded, test_data);
2366    }
2367
2368    #[test]
2369    fn test_encode_decode_enumerated() {
2370        let mut buffer = Vec::new();
2371        let test_values = [0, 1, 255, 256, 65535, 65536, 16777215];
2372
2373        for &test_value in &test_values {
2374            buffer.clear();
2375            encode_enumerated(&mut buffer, test_value);
2376            let (value, _) = decode_enumerated(&buffer).unwrap();
2377            assert_eq!(value, test_value);
2378        }
2379    }
2380
2381    #[test]
2382    fn test_encode_decode_date() {
2383        let mut buffer = Vec::new();
2384
2385        encode_date(&mut buffer, 2024, 3, 15, 5).unwrap(); // Friday, March 15, 2024
2386        let ((year, month, day, weekday), _) = decode_date(&buffer).unwrap();
2387        assert_eq!(year, 2024);
2388        assert_eq!(month, 3);
2389        assert_eq!(day, 15);
2390        assert_eq!(weekday, 5);
2391    }
2392
2393    #[test]
2394    fn test_encode_decode_time() {
2395        let mut buffer = Vec::new();
2396
2397        encode_time(&mut buffer, 14, 30, 45, 50).unwrap(); // 14:30:45.50
2398        let ((hour, minute, second, hundredths), _) = decode_time(&buffer).unwrap();
2399        assert_eq!(hour, 14);
2400        assert_eq!(minute, 30);
2401        assert_eq!(second, 45);
2402        assert_eq!(hundredths, 50);
2403    }
2404
2405    #[test]
2406    fn test_encode_decode_object_identifier() {
2407        let mut buffer = Vec::new();
2408
2409        let object_id = ObjectIdentifier::new(ObjectType::AnalogValue, 12345);
2410        encode_object_identifier(&mut buffer, object_id).unwrap(); // Analog Value 12345
2411        let (object_id, _) = decode_object_identifier(&buffer).unwrap();
2412        assert_eq!(object_id.object_type, ObjectType::AnalogValue);
2413        assert_eq!(object_id.instance, 12345);
2414    }
2415
2416    #[test]
2417    fn test_encode_decode_double() {
2418        let mut buffer = Vec::new();
2419        let test_values = [
2420            0.0,
2421            1.0,
2422            -1.0,
2423            std::f64::consts::PI,
2424            -273.15,
2425            f64::MAX,
2426            f64::MIN,
2427        ];
2428
2429        for &test_value in &test_values {
2430            buffer.clear();
2431            encode_double(&mut buffer, test_value).unwrap();
2432            let (value, _) = decode_double(&buffer).unwrap();
2433            assert_eq!(value, test_value);
2434        }
2435    }
2436
2437    #[test]
2438    fn test_buffer_manager() {
2439        use advanced::BufferManager;
2440
2441        let mut manager = BufferManager::new(1024);
2442
2443        // Test getting and returning buffers
2444        let buffer1 = manager.get_encode_buffer();
2445        let buffer2 = manager.get_encode_buffer();
2446
2447        assert_eq!(manager.stats.total_allocations, 2);
2448        assert_eq!(manager.stats.buffer_reuses, 0);
2449
2450        manager.return_buffer(buffer1);
2451        let buffer3 = manager.get_encode_buffer();
2452
2453        assert_eq!(manager.stats.total_allocations, 2);
2454        assert_eq!(manager.stats.buffer_reuses, 1);
2455
2456        manager.return_buffer(buffer2);
2457        manager.return_buffer(buffer3);
2458    }
2459
2460    #[test]
2461    fn test_context_specific_encoding() {
2462        use advanced::context::*;
2463
2464        let mut buffer = Vec::new();
2465
2466        // Test context-specific tag encoding
2467        encode_context_tag(&mut buffer, 5, 10).unwrap();
2468        let (tag_number, length, consumed) = decode_context_tag(&buffer).unwrap();
2469
2470        assert_eq!(tag_number, 5);
2471        assert_eq!(length, 10);
2472        assert_eq!(consumed, 2);
2473    }
2474
2475    #[test]
2476    fn test_opening_closing_tags() {
2477        use advanced::context::*;
2478
2479        let mut buffer = Vec::new();
2480
2481        // Test opening and closing tags
2482        encode_opening_tag(&mut buffer, 3).unwrap();
2483        encode_closing_tag(&mut buffer, 3).unwrap();
2484
2485        assert_eq!(buffer, vec![0x3E, 0x3F]);
2486    }
2487
2488    #[test]
2489    fn test_bit_string_encoding() {
2490        use advanced::bitstring::*;
2491
2492        let mut buffer = Vec::new();
2493        let bits = vec![true, false, true, true, false, false, true, false, true];
2494
2495        encode_bit_string(&mut buffer, &bits).unwrap();
2496        let (decoded_bits, _) = decode_bit_string(&buffer).unwrap();
2497
2498        assert_eq!(decoded_bits, bits);
2499    }
2500
2501    #[test]
2502    fn test_fast_encoder() {
2503        use advanced::perf::FastEncoder;
2504
2505        let mut encoder = FastEncoder::new(256);
2506
2507        // Test fast encoding
2508        encoder.encode_unsigned_fast(42).unwrap();
2509        encoder.encode_boolean_fast(true).unwrap();
2510        encoder.encode_real_fast(std::f32::consts::PI).unwrap();
2511
2512        let data = encoder.data();
2513        assert!(!data.is_empty());
2514
2515        encoder.clear();
2516        assert_eq!(encoder.data().len(), 0);
2517    }
2518
2519    #[test]
2520    fn test_data_validator() {
2521        use advanced::validation::DataValidator;
2522
2523        let validator = DataValidator::new(10, 1000);
2524
2525        // Test with valid data
2526        let mut buffer = Vec::new();
2527        encode_unsigned(&mut buffer, 42).unwrap();
2528        encode_character_string(&mut buffer, "Hello").unwrap();
2529
2530        assert!(validator.validate(&buffer).is_ok());
2531    }
2532
2533    #[test]
2534    fn test_encode_decode_performance() {
2535        let mut buffer = Vec::new();
2536        let iterations = 1000;
2537
2538        // Performance test for encoding/decoding
2539        for i in 0..iterations {
2540            buffer.clear();
2541            encode_unsigned(&mut buffer, i).unwrap();
2542            let (value, _) = decode_unsigned(&buffer).unwrap();
2543            assert_eq!(value, i);
2544        }
2545    }
2546
2547    #[test]
2548    fn test_encode_decode_i64() {
2549        let mut buffer = Vec::new();
2550        let test_values = [
2551            0,
2552            1,
2553            -1,
2554            -330,
2555            i32::MAX as i64,
2556            i32::MIN as i64,
2557            i32::MAX as i64 + 10,
2558            i32::MIN as i64 - 10,
2559            i64::MAX,
2560            i64::MIN,
2561            i64::MAX as i32 as i64,
2562            i64::MIN as i32 as i64,
2563        ];
2564
2565        for &test_value in &test_values {
2566            buffer.clear();
2567            encode_signed64(&mut buffer, test_value);
2568            let (value, _) = decode_signed64(&buffer).unwrap();
2569            assert_eq!(value, test_value);
2570        }
2571    }
2572
2573    #[test]
2574    fn test_encode_decode_u64() {
2575        let mut buffer = Vec::new();
2576        let test_values = [
2577            0,
2578            1,
2579            255,
2580            330,
2581            u32::MAX as u64,
2582            u32::MIN as u64,
2583            u32::MAX as u64 + 10,
2584            u64::MAX,
2585            u64::MIN,
2586            u64::MAX as u32 as u64,
2587            u64::MIN as u32 as u64,
2588        ];
2589
2590        for &test_value in &test_values {
2591            buffer.clear();
2592            encode_unsigned64(&mut buffer, test_value);
2593            let (value, _) = decode_unsigned64(&buffer).unwrap();
2594            assert_eq!(value, test_value);
2595        }
2596    }
2597
2598    #[test]
2599    fn test_decode_bacnet_tag() {
2600        let data = [0x21];
2601        let (tag, length, consumed) = decode_tag(&data).unwrap();
2602        assert_eq!(tag, BACnetTag::Application(ApplicationTag::UnsignedInt));
2603        assert_eq!(length, 1);
2604        assert_eq!(consumed, 1);
2605
2606        let data = [0x1E];
2607        let (tag, length, consumed) = decode_tag(&data).unwrap();
2608        assert_eq!(tag, BACnetTag::Context(1));
2609        assert_eq!(length, 6);
2610        assert_eq!(consumed, 1);
2611
2612        let data = [0x0C];
2613        let (tag, length, consumed) = decode_tag(&data).unwrap();
2614        assert_eq!(tag, BACnetTag::Context(0));
2615        assert_eq!(length, 4);
2616        assert_eq!(consumed, 1);
2617
2618        let data = [0x35, 0x08];
2619        let (tag, length, consumed) = decode_tag(&data).unwrap();
2620        assert_eq!(tag, BACnetTag::Application(ApplicationTag::SignedInt));
2621        assert_eq!(length, 8);
2622        assert_eq!(consumed, 2);
2623    }
2624}