1use bytes::{Buf, BufMut, Bytes};
31
32use crate::codec::{read_b_varchar, read_us_varchar};
33use crate::error::ProtocolError;
34use crate::types::TypeId;
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
38#[repr(u8)]
39pub enum TokenType {
40 ColMetaData = 0x81,
42 Error = 0xAA,
44 Info = 0xAB,
46 LoginAck = 0xAD,
48 Row = 0xD1,
50 NbcRow = 0xD2,
52 EnvChange = 0xE3,
54 Sspi = 0xED,
56 Done = 0xFD,
58 DoneInProc = 0xFF,
60 DoneProc = 0xFE,
62 ReturnStatus = 0x79,
64 ReturnValue = 0xAC,
66 Order = 0xA9,
68 FeatureExtAck = 0xAE,
70 SessionState = 0xE4,
72 FedAuthInfo = 0xEE,
74 ColInfo = 0xA5,
76 TabName = 0xA4,
78 Offset = 0x78,
80}
81
82impl TokenType {
83 pub fn from_u8(value: u8) -> Option<Self> {
85 match value {
86 0x81 => Some(Self::ColMetaData),
87 0xAA => Some(Self::Error),
88 0xAB => Some(Self::Info),
89 0xAD => Some(Self::LoginAck),
90 0xD1 => Some(Self::Row),
91 0xD2 => Some(Self::NbcRow),
92 0xE3 => Some(Self::EnvChange),
93 0xED => Some(Self::Sspi),
94 0xFD => Some(Self::Done),
95 0xFF => Some(Self::DoneInProc),
96 0xFE => Some(Self::DoneProc),
97 0x79 => Some(Self::ReturnStatus),
98 0xAC => Some(Self::ReturnValue),
99 0xA9 => Some(Self::Order),
100 0xAE => Some(Self::FeatureExtAck),
101 0xE4 => Some(Self::SessionState),
102 0xEE => Some(Self::FedAuthInfo),
103 0xA5 => Some(Self::ColInfo),
104 0xA4 => Some(Self::TabName),
105 0x78 => Some(Self::Offset),
106 _ => None,
107 }
108 }
109}
110
111#[derive(Debug, Clone)]
116pub enum Token {
117 ColMetaData(ColMetaData),
119 Row(RawRow),
121 NbcRow(NbcRow),
123 Done(Done),
125 DoneProc(DoneProc),
127 DoneInProc(DoneInProc),
129 ReturnStatus(i32),
131 ReturnValue(ReturnValue),
133 Error(ServerError),
135 Info(ServerInfo),
137 LoginAck(LoginAck),
139 EnvChange(EnvChange),
141 Order(Order),
143 FeatureExtAck(FeatureExtAck),
145 Sspi(SspiToken),
147 SessionState(SessionState),
149 FedAuthInfo(FedAuthInfo),
151}
152
153#[derive(Debug, Clone, Default)]
155pub struct ColMetaData {
156 pub columns: Vec<ColumnData>,
158}
159
160#[derive(Debug, Clone)]
162pub struct ColumnData {
163 pub name: String,
165 pub type_id: TypeId,
167 pub col_type: u8,
169 pub flags: u16,
171 pub user_type: u32,
173 pub type_info: TypeInfo,
175}
176
177#[derive(Debug, Clone, Default)]
179pub struct TypeInfo {
180 pub max_length: Option<u32>,
182 pub precision: Option<u8>,
184 pub scale: Option<u8>,
186 pub collation: Option<Collation>,
188}
189
190#[derive(Debug, Clone, Copy, Default)]
192pub struct Collation {
193 pub lcid: u32,
195 pub sort_id: u8,
197}
198
199#[derive(Debug, Clone)]
201pub struct RawRow {
202 pub data: bytes::Bytes,
204}
205
206#[derive(Debug, Clone)]
208pub struct NbcRow {
209 pub null_bitmap: Vec<u8>,
211 pub data: bytes::Bytes,
213}
214
215#[derive(Debug, Clone, Copy)]
217pub struct Done {
218 pub status: DoneStatus,
220 pub cur_cmd: u16,
222 pub row_count: u64,
224}
225
226#[derive(Debug, Clone, Copy, Default)]
228pub struct DoneStatus {
229 pub more: bool,
231 pub error: bool,
233 pub in_xact: bool,
235 pub count: bool,
237 pub attn: bool,
239 pub srverror: bool,
241}
242
243#[derive(Debug, Clone, Copy)]
245pub struct DoneInProc {
246 pub status: DoneStatus,
248 pub cur_cmd: u16,
250 pub row_count: u64,
252}
253
254#[derive(Debug, Clone, Copy)]
256pub struct DoneProc {
257 pub status: DoneStatus,
259 pub cur_cmd: u16,
261 pub row_count: u64,
263}
264
265#[derive(Debug, Clone)]
267pub struct ReturnValue {
268 pub param_ordinal: u16,
270 pub param_name: String,
272 pub status: u8,
274 pub user_type: u32,
276 pub flags: u16,
278 pub type_info: TypeInfo,
280 pub value: bytes::Bytes,
282}
283
284#[derive(Debug, Clone)]
286pub struct ServerError {
287 pub number: i32,
289 pub state: u8,
291 pub class: u8,
293 pub message: String,
295 pub server: String,
297 pub procedure: String,
299 pub line: i32,
301}
302
303#[derive(Debug, Clone)]
305pub struct ServerInfo {
306 pub number: i32,
308 pub state: u8,
310 pub class: u8,
312 pub message: String,
314 pub server: String,
316 pub procedure: String,
318 pub line: i32,
320}
321
322#[derive(Debug, Clone)]
324pub struct LoginAck {
325 pub interface: u8,
327 pub tds_version: u32,
329 pub prog_name: String,
331 pub prog_version: u32,
333}
334
335#[derive(Debug, Clone)]
337pub struct EnvChange {
338 pub env_type: EnvChangeType,
340 pub new_value: EnvChangeValue,
342 pub old_value: EnvChangeValue,
344}
345
346#[derive(Debug, Clone, Copy, PartialEq, Eq)]
348#[repr(u8)]
349pub enum EnvChangeType {
350 Database = 1,
352 Language = 2,
354 CharacterSet = 3,
356 PacketSize = 4,
358 UnicodeSortingLocalId = 5,
360 UnicodeComparisonFlags = 6,
362 SqlCollation = 7,
364 BeginTransaction = 8,
366 CommitTransaction = 9,
368 RollbackTransaction = 10,
370 EnlistDtcTransaction = 11,
372 DefectTransaction = 12,
374 RealTimeLogShipping = 13,
376 PromoteTransaction = 15,
378 TransactionManagerAddress = 16,
380 TransactionEnded = 17,
382 ResetConnectionCompletionAck = 18,
384 UserInstanceStarted = 19,
386 Routing = 20,
388}
389
390#[derive(Debug, Clone)]
392pub enum EnvChangeValue {
393 String(String),
395 Binary(bytes::Bytes),
397 Routing {
399 host: String,
401 port: u16,
403 },
404}
405
406#[derive(Debug, Clone)]
408pub struct Order {
409 pub columns: Vec<u16>,
411}
412
413#[derive(Debug, Clone)]
415pub struct FeatureExtAck {
416 pub features: Vec<FeatureAck>,
418}
419
420#[derive(Debug, Clone)]
422pub struct FeatureAck {
423 pub feature_id: u8,
425 pub data: bytes::Bytes,
427}
428
429#[derive(Debug, Clone)]
431pub struct SspiToken {
432 pub data: bytes::Bytes,
434}
435
436#[derive(Debug, Clone)]
438pub struct SessionState {
439 pub data: bytes::Bytes,
441}
442
443#[derive(Debug, Clone)]
445pub struct FedAuthInfo {
446 pub sts_url: String,
448 pub spn: String,
450}
451
452impl ColMetaData {
457 pub const NO_METADATA: u16 = 0xFFFF;
459
460 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
462 if src.remaining() < 2 {
463 return Err(ProtocolError::UnexpectedEof);
464 }
465
466 let column_count = src.get_u16_le();
467
468 if column_count == Self::NO_METADATA {
470 return Ok(Self {
471 columns: Vec::new(),
472 });
473 }
474
475 let mut columns = Vec::with_capacity(column_count as usize);
476
477 for _ in 0..column_count {
478 let column = Self::decode_column(src)?;
479 columns.push(column);
480 }
481
482 Ok(Self { columns })
483 }
484
485 fn decode_column(src: &mut impl Buf) -> Result<ColumnData, ProtocolError> {
487 if src.remaining() < 7 {
489 return Err(ProtocolError::UnexpectedEof);
490 }
491
492 let user_type = src.get_u32_le();
493 let flags = src.get_u16_le();
494 let col_type = src.get_u8();
495
496 let type_id = TypeId::from_u8(col_type).unwrap_or(TypeId::Null); let type_info = Self::decode_type_info(src, type_id, col_type)?;
500
501 let name = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
503
504 Ok(ColumnData {
505 name,
506 type_id,
507 col_type,
508 flags,
509 user_type,
510 type_info,
511 })
512 }
513
514 fn decode_type_info(
516 src: &mut impl Buf,
517 type_id: TypeId,
518 col_type: u8,
519 ) -> Result<TypeInfo, ProtocolError> {
520 match type_id {
521 TypeId::Null => Ok(TypeInfo::default()),
523 TypeId::Int1 | TypeId::Bit => Ok(TypeInfo::default()),
524 TypeId::Int2 => Ok(TypeInfo::default()),
525 TypeId::Int4 => Ok(TypeInfo::default()),
526 TypeId::Int8 => Ok(TypeInfo::default()),
527 TypeId::Float4 => Ok(TypeInfo::default()),
528 TypeId::Float8 => Ok(TypeInfo::default()),
529 TypeId::Money => Ok(TypeInfo::default()),
530 TypeId::Money4 => Ok(TypeInfo::default()),
531 TypeId::DateTime => Ok(TypeInfo::default()),
532 TypeId::DateTime4 => Ok(TypeInfo::default()),
533
534 TypeId::IntN | TypeId::BitN | TypeId::FloatN | TypeId::MoneyN | TypeId::DateTimeN => {
536 if src.remaining() < 1 {
537 return Err(ProtocolError::UnexpectedEof);
538 }
539 let max_length = src.get_u8() as u32;
540 Ok(TypeInfo {
541 max_length: Some(max_length),
542 ..Default::default()
543 })
544 }
545
546 TypeId::Guid => {
548 if src.remaining() < 1 {
549 return Err(ProtocolError::UnexpectedEof);
550 }
551 let max_length = src.get_u8() as u32;
552 Ok(TypeInfo {
553 max_length: Some(max_length),
554 ..Default::default()
555 })
556 }
557
558 TypeId::Decimal | TypeId::Numeric | TypeId::DecimalN | TypeId::NumericN => {
560 if src.remaining() < 3 {
561 return Err(ProtocolError::UnexpectedEof);
562 }
563 let max_length = src.get_u8() as u32;
564 let precision = src.get_u8();
565 let scale = src.get_u8();
566 Ok(TypeInfo {
567 max_length: Some(max_length),
568 precision: Some(precision),
569 scale: Some(scale),
570 ..Default::default()
571 })
572 }
573
574 TypeId::Char | TypeId::VarChar | TypeId::Binary | TypeId::VarBinary => {
576 if src.remaining() < 1 {
577 return Err(ProtocolError::UnexpectedEof);
578 }
579 let max_length = src.get_u8() as u32;
580 Ok(TypeInfo {
581 max_length: Some(max_length),
582 ..Default::default()
583 })
584 }
585
586 TypeId::BigVarChar | TypeId::BigChar => {
588 if src.remaining() < 7 {
589 return Err(ProtocolError::UnexpectedEof);
591 }
592 let max_length = src.get_u16_le() as u32;
593 let collation = Self::decode_collation(src)?;
594 Ok(TypeInfo {
595 max_length: Some(max_length),
596 collation: Some(collation),
597 ..Default::default()
598 })
599 }
600
601 TypeId::BigVarBinary | TypeId::BigBinary => {
603 if src.remaining() < 2 {
604 return Err(ProtocolError::UnexpectedEof);
605 }
606 let max_length = src.get_u16_le() as u32;
607 Ok(TypeInfo {
608 max_length: Some(max_length),
609 ..Default::default()
610 })
611 }
612
613 TypeId::NChar | TypeId::NVarChar => {
615 if src.remaining() < 7 {
616 return Err(ProtocolError::UnexpectedEof);
618 }
619 let max_length = src.get_u16_le() as u32;
620 let collation = Self::decode_collation(src)?;
621 Ok(TypeInfo {
622 max_length: Some(max_length),
623 collation: Some(collation),
624 ..Default::default()
625 })
626 }
627
628 TypeId::Date => Ok(TypeInfo::default()),
630
631 TypeId::Time | TypeId::DateTime2 | TypeId::DateTimeOffset => {
633 if src.remaining() < 1 {
634 return Err(ProtocolError::UnexpectedEof);
635 }
636 let scale = src.get_u8();
637 Ok(TypeInfo {
638 scale: Some(scale),
639 ..Default::default()
640 })
641 }
642
643 TypeId::Text | TypeId::NText | TypeId::Image => {
645 if src.remaining() < 4 {
647 return Err(ProtocolError::UnexpectedEof);
648 }
649 let max_length = src.get_u32_le();
650
651 let collation = if type_id == TypeId::Text || type_id == TypeId::NText {
653 if src.remaining() < 5 {
654 return Err(ProtocolError::UnexpectedEof);
655 }
656 Some(Self::decode_collation(src)?)
657 } else {
658 None
659 };
660
661 if src.remaining() < 1 {
664 return Err(ProtocolError::UnexpectedEof);
665 }
666 let num_parts = src.get_u8();
667 for _ in 0..num_parts {
668 let _ = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
670 }
671
672 Ok(TypeInfo {
673 max_length: Some(max_length),
674 collation,
675 ..Default::default()
676 })
677 }
678
679 TypeId::Xml => {
681 if src.remaining() < 1 {
682 return Err(ProtocolError::UnexpectedEof);
683 }
684 let schema_present = src.get_u8();
685
686 if schema_present != 0 {
687 let _ = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?; let _ = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?; let _ = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?; }
692
693 Ok(TypeInfo::default())
694 }
695
696 TypeId::Udt => {
698 if src.remaining() < 2 {
700 return Err(ProtocolError::UnexpectedEof);
701 }
702 let max_length = src.get_u16_le() as u32;
703
704 let _ = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?; let _ = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?; let _ = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?; let _ = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?; Ok(TypeInfo {
711 max_length: Some(max_length),
712 ..Default::default()
713 })
714 }
715
716 TypeId::Tvp => {
718 Err(ProtocolError::InvalidTokenType(col_type))
721 }
722
723 TypeId::Variant => {
725 if src.remaining() < 4 {
726 return Err(ProtocolError::UnexpectedEof);
727 }
728 let max_length = src.get_u32_le();
729 Ok(TypeInfo {
730 max_length: Some(max_length),
731 ..Default::default()
732 })
733 }
734 }
735 }
736
737 fn decode_collation(src: &mut impl Buf) -> Result<Collation, ProtocolError> {
739 if src.remaining() < 5 {
740 return Err(ProtocolError::UnexpectedEof);
741 }
742 let lcid = src.get_u32_le();
744 let sort_id = src.get_u8();
745 Ok(Collation { lcid, sort_id })
746 }
747
748 #[must_use]
750 pub fn column_count(&self) -> usize {
751 self.columns.len()
752 }
753
754 #[must_use]
756 pub fn is_empty(&self) -> bool {
757 self.columns.is_empty()
758 }
759}
760
761impl ColumnData {
762 #[must_use]
764 pub fn is_nullable(&self) -> bool {
765 (self.flags & 0x0001) != 0
766 }
767
768 #[must_use]
772 pub fn fixed_size(&self) -> Option<usize> {
773 match self.type_id {
774 TypeId::Null => Some(0),
775 TypeId::Int1 | TypeId::Bit => Some(1),
776 TypeId::Int2 => Some(2),
777 TypeId::Int4 => Some(4),
778 TypeId::Int8 => Some(8),
779 TypeId::Float4 => Some(4),
780 TypeId::Float8 => Some(8),
781 TypeId::Money => Some(8),
782 TypeId::Money4 => Some(4),
783 TypeId::DateTime => Some(8),
784 TypeId::DateTime4 => Some(4),
785 TypeId::Date => Some(3),
786 _ => None,
787 }
788 }
789}
790
791impl RawRow {
796 pub fn decode(src: &mut impl Buf, metadata: &ColMetaData) -> Result<Self, ProtocolError> {
801 let mut data = bytes::BytesMut::new();
802
803 for col in &metadata.columns {
804 Self::decode_column_value(src, col, &mut data)?;
805 }
806
807 Ok(Self {
808 data: data.freeze(),
809 })
810 }
811
812 fn decode_column_value(
814 src: &mut impl Buf,
815 col: &ColumnData,
816 dst: &mut bytes::BytesMut,
817 ) -> Result<(), ProtocolError> {
818 match col.type_id {
819 TypeId::Null => {
821 }
823 TypeId::Int1 | TypeId::Bit => {
824 if src.remaining() < 1 {
825 return Err(ProtocolError::UnexpectedEof);
826 }
827 dst.extend_from_slice(&[src.get_u8()]);
828 }
829 TypeId::Int2 => {
830 if src.remaining() < 2 {
831 return Err(ProtocolError::UnexpectedEof);
832 }
833 dst.extend_from_slice(&src.get_u16_le().to_le_bytes());
834 }
835 TypeId::Int4 => {
836 if src.remaining() < 4 {
837 return Err(ProtocolError::UnexpectedEof);
838 }
839 dst.extend_from_slice(&src.get_u32_le().to_le_bytes());
840 }
841 TypeId::Int8 => {
842 if src.remaining() < 8 {
843 return Err(ProtocolError::UnexpectedEof);
844 }
845 dst.extend_from_slice(&src.get_u64_le().to_le_bytes());
846 }
847 TypeId::Float4 => {
848 if src.remaining() < 4 {
849 return Err(ProtocolError::UnexpectedEof);
850 }
851 dst.extend_from_slice(&src.get_u32_le().to_le_bytes());
852 }
853 TypeId::Float8 => {
854 if src.remaining() < 8 {
855 return Err(ProtocolError::UnexpectedEof);
856 }
857 dst.extend_from_slice(&src.get_u64_le().to_le_bytes());
858 }
859 TypeId::Money => {
860 if src.remaining() < 8 {
861 return Err(ProtocolError::UnexpectedEof);
862 }
863 let hi = src.get_u32_le();
864 let lo = src.get_u32_le();
865 dst.extend_from_slice(&hi.to_le_bytes());
866 dst.extend_from_slice(&lo.to_le_bytes());
867 }
868 TypeId::Money4 => {
869 if src.remaining() < 4 {
870 return Err(ProtocolError::UnexpectedEof);
871 }
872 dst.extend_from_slice(&src.get_u32_le().to_le_bytes());
873 }
874 TypeId::DateTime => {
875 if src.remaining() < 8 {
876 return Err(ProtocolError::UnexpectedEof);
877 }
878 let days = src.get_u32_le();
879 let time = src.get_u32_le();
880 dst.extend_from_slice(&days.to_le_bytes());
881 dst.extend_from_slice(&time.to_le_bytes());
882 }
883 TypeId::DateTime4 => {
884 if src.remaining() < 4 {
885 return Err(ProtocolError::UnexpectedEof);
886 }
887 dst.extend_from_slice(&src.get_u32_le().to_le_bytes());
888 }
889 TypeId::Date => {
890 if src.remaining() < 3 {
891 return Err(ProtocolError::UnexpectedEof);
892 }
893 let b1 = src.get_u8();
894 let b2 = src.get_u8();
895 let b3 = src.get_u8();
896 dst.extend_from_slice(&[b1, b2, b3]);
897 }
898
899 TypeId::IntN | TypeId::BitN | TypeId::FloatN | TypeId::MoneyN | TypeId::DateTimeN => {
901 Self::decode_bytelen_type(src, dst)?;
902 }
903
904 TypeId::Guid => {
905 Self::decode_bytelen_type(src, dst)?;
906 }
907
908 TypeId::Decimal | TypeId::Numeric | TypeId::DecimalN | TypeId::NumericN => {
909 Self::decode_bytelen_type(src, dst)?;
910 }
911
912 TypeId::Char | TypeId::VarChar | TypeId::Binary | TypeId::VarBinary => {
914 Self::decode_bytelen_type(src, dst)?;
915 }
916
917 TypeId::BigVarChar | TypeId::BigVarBinary => {
919 if col.type_info.max_length == Some(0xFFFF) {
921 Self::decode_plp_type(src, dst)?;
922 } else {
923 Self::decode_ushortlen_type(src, dst)?;
924 }
925 }
926
927 TypeId::BigChar | TypeId::BigBinary => {
929 Self::decode_ushortlen_type(src, dst)?;
930 }
931
932 TypeId::NVarChar => {
934 if col.type_info.max_length == Some(0xFFFF) {
936 Self::decode_plp_type(src, dst)?;
937 } else {
938 Self::decode_ushortlen_type(src, dst)?;
939 }
940 }
941
942 TypeId::NChar => {
944 Self::decode_ushortlen_type(src, dst)?;
945 }
946
947 TypeId::Time | TypeId::DateTime2 | TypeId::DateTimeOffset => {
949 Self::decode_bytelen_type(src, dst)?;
950 }
951
952 TypeId::Text | TypeId::NText | TypeId::Image | TypeId::Xml => {
954 Self::decode_plp_type(src, dst)?;
955 }
956
957 TypeId::Variant => {
959 Self::decode_intlen_type(src, dst)?;
960 }
961
962 TypeId::Udt => {
963 Self::decode_plp_type(src, dst)?;
965 }
966
967 TypeId::Tvp => {
968 return Err(ProtocolError::InvalidTokenType(col.col_type));
970 }
971 }
972
973 Ok(())
974 }
975
976 fn decode_bytelen_type(
978 src: &mut impl Buf,
979 dst: &mut bytes::BytesMut,
980 ) -> Result<(), ProtocolError> {
981 if src.remaining() < 1 {
982 return Err(ProtocolError::UnexpectedEof);
983 }
984 let len = src.get_u8() as usize;
985 if len == 0xFF {
986 dst.extend_from_slice(&[0xFF]);
988 } else if len == 0 {
989 dst.extend_from_slice(&[0x00]);
991 } else {
992 if src.remaining() < len {
993 return Err(ProtocolError::UnexpectedEof);
994 }
995 dst.extend_from_slice(&[len as u8]);
996 for _ in 0..len {
997 dst.extend_from_slice(&[src.get_u8()]);
998 }
999 }
1000 Ok(())
1001 }
1002
1003 fn decode_ushortlen_type(
1005 src: &mut impl Buf,
1006 dst: &mut bytes::BytesMut,
1007 ) -> Result<(), ProtocolError> {
1008 if src.remaining() < 2 {
1009 return Err(ProtocolError::UnexpectedEof);
1010 }
1011 let len = src.get_u16_le() as usize;
1012 if len == 0xFFFF {
1013 dst.extend_from_slice(&0xFFFFu16.to_le_bytes());
1015 } else if len == 0 {
1016 dst.extend_from_slice(&0u16.to_le_bytes());
1018 } else {
1019 if src.remaining() < len {
1020 return Err(ProtocolError::UnexpectedEof);
1021 }
1022 dst.extend_from_slice(&(len as u16).to_le_bytes());
1023 for _ in 0..len {
1024 dst.extend_from_slice(&[src.get_u8()]);
1025 }
1026 }
1027 Ok(())
1028 }
1029
1030 fn decode_intlen_type(
1032 src: &mut impl Buf,
1033 dst: &mut bytes::BytesMut,
1034 ) -> Result<(), ProtocolError> {
1035 if src.remaining() < 4 {
1036 return Err(ProtocolError::UnexpectedEof);
1037 }
1038 let len = src.get_u32_le() as usize;
1039 if len == 0xFFFFFFFF {
1040 dst.extend_from_slice(&0xFFFFFFFFu32.to_le_bytes());
1042 } else if len == 0 {
1043 dst.extend_from_slice(&0u32.to_le_bytes());
1045 } else {
1046 if src.remaining() < len {
1047 return Err(ProtocolError::UnexpectedEof);
1048 }
1049 dst.extend_from_slice(&(len as u32).to_le_bytes());
1050 for _ in 0..len {
1051 dst.extend_from_slice(&[src.get_u8()]);
1052 }
1053 }
1054 Ok(())
1055 }
1056
1057 fn decode_plp_type(src: &mut impl Buf, dst: &mut bytes::BytesMut) -> Result<(), ProtocolError> {
1063 if src.remaining() < 8 {
1064 return Err(ProtocolError::UnexpectedEof);
1065 }
1066
1067 let total_len = src.get_u64_le();
1068
1069 dst.extend_from_slice(&total_len.to_le_bytes());
1071
1072 if total_len == 0xFFFFFFFFFFFFFFFF {
1073 return Ok(());
1075 }
1076
1077 loop {
1079 if src.remaining() < 4 {
1080 return Err(ProtocolError::UnexpectedEof);
1081 }
1082 let chunk_len = src.get_u32_le() as usize;
1083 dst.extend_from_slice(&(chunk_len as u32).to_le_bytes());
1084
1085 if chunk_len == 0 {
1086 break;
1088 }
1089
1090 if src.remaining() < chunk_len {
1091 return Err(ProtocolError::UnexpectedEof);
1092 }
1093
1094 for _ in 0..chunk_len {
1095 dst.extend_from_slice(&[src.get_u8()]);
1096 }
1097 }
1098
1099 Ok(())
1100 }
1101}
1102
1103impl NbcRow {
1108 pub fn decode(src: &mut impl Buf, metadata: &ColMetaData) -> Result<Self, ProtocolError> {
1113 let col_count = metadata.columns.len();
1114 let bitmap_len = (col_count + 7) / 8;
1115
1116 if src.remaining() < bitmap_len {
1117 return Err(ProtocolError::UnexpectedEof);
1118 }
1119
1120 let mut null_bitmap = vec![0u8; bitmap_len];
1122 for byte in &mut null_bitmap {
1123 *byte = src.get_u8();
1124 }
1125
1126 let mut data = bytes::BytesMut::new();
1128
1129 for (i, col) in metadata.columns.iter().enumerate() {
1130 let byte_idx = i / 8;
1131 let bit_idx = i % 8;
1132 let is_null = (null_bitmap[byte_idx] & (1 << bit_idx)) != 0;
1133
1134 if !is_null {
1135 RawRow::decode_column_value(src, col, &mut data)?;
1138 }
1139 }
1140
1141 Ok(Self {
1142 null_bitmap,
1143 data: data.freeze(),
1144 })
1145 }
1146
1147 #[must_use]
1149 pub fn is_null(&self, column_index: usize) -> bool {
1150 let byte_idx = column_index / 8;
1151 let bit_idx = column_index % 8;
1152 if byte_idx < self.null_bitmap.len() {
1153 (self.null_bitmap[byte_idx] & (1 << bit_idx)) != 0
1154 } else {
1155 true }
1157 }
1158}
1159
1160impl ReturnValue {
1165 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1167 if src.remaining() < 2 {
1169 return Err(ProtocolError::UnexpectedEof);
1170 }
1171 let _length = src.get_u16_le();
1172
1173 if src.remaining() < 2 {
1175 return Err(ProtocolError::UnexpectedEof);
1176 }
1177 let param_ordinal = src.get_u16_le();
1178
1179 let param_name = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1181
1182 if src.remaining() < 1 {
1184 return Err(ProtocolError::UnexpectedEof);
1185 }
1186 let status = src.get_u8();
1187
1188 if src.remaining() < 7 {
1190 return Err(ProtocolError::UnexpectedEof);
1191 }
1192 let user_type = src.get_u32_le();
1193 let flags = src.get_u16_le();
1194 let col_type = src.get_u8();
1195
1196 let type_id = TypeId::from_u8(col_type).unwrap_or(TypeId::Null);
1197
1198 let type_info = ColMetaData::decode_type_info(src, type_id, col_type)?;
1200
1201 let mut value_buf = bytes::BytesMut::new();
1203
1204 let temp_col = ColumnData {
1206 name: String::new(),
1207 type_id,
1208 col_type,
1209 flags,
1210 user_type,
1211 type_info: type_info.clone(),
1212 };
1213
1214 RawRow::decode_column_value(src, &temp_col, &mut value_buf)?;
1215
1216 Ok(Self {
1217 param_ordinal,
1218 param_name,
1219 status,
1220 user_type,
1221 flags,
1222 type_info,
1223 value: value_buf.freeze(),
1224 })
1225 }
1226}
1227
1228impl SessionState {
1233 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1235 if src.remaining() < 4 {
1236 return Err(ProtocolError::UnexpectedEof);
1237 }
1238
1239 let length = src.get_u32_le() as usize;
1240
1241 if src.remaining() < length {
1242 return Err(ProtocolError::IncompletePacket {
1243 expected: length,
1244 actual: src.remaining(),
1245 });
1246 }
1247
1248 let data = src.copy_to_bytes(length);
1249
1250 Ok(Self { data })
1251 }
1252}
1253
1254mod done_status_bits {
1260 pub const DONE_MORE: u16 = 0x0001;
1261 pub const DONE_ERROR: u16 = 0x0002;
1262 pub const DONE_INXACT: u16 = 0x0004;
1263 pub const DONE_COUNT: u16 = 0x0010;
1264 pub const DONE_ATTN: u16 = 0x0020;
1265 pub const DONE_SRVERROR: u16 = 0x0100;
1266}
1267
1268impl DoneStatus {
1269 #[must_use]
1271 pub fn from_bits(bits: u16) -> Self {
1272 use done_status_bits::*;
1273 Self {
1274 more: (bits & DONE_MORE) != 0,
1275 error: (bits & DONE_ERROR) != 0,
1276 in_xact: (bits & DONE_INXACT) != 0,
1277 count: (bits & DONE_COUNT) != 0,
1278 attn: (bits & DONE_ATTN) != 0,
1279 srverror: (bits & DONE_SRVERROR) != 0,
1280 }
1281 }
1282
1283 #[must_use]
1285 pub fn to_bits(&self) -> u16 {
1286 use done_status_bits::*;
1287 let mut bits = 0u16;
1288 if self.more {
1289 bits |= DONE_MORE;
1290 }
1291 if self.error {
1292 bits |= DONE_ERROR;
1293 }
1294 if self.in_xact {
1295 bits |= DONE_INXACT;
1296 }
1297 if self.count {
1298 bits |= DONE_COUNT;
1299 }
1300 if self.attn {
1301 bits |= DONE_ATTN;
1302 }
1303 if self.srverror {
1304 bits |= DONE_SRVERROR;
1305 }
1306 bits
1307 }
1308}
1309
1310impl Done {
1311 pub const SIZE: usize = 12; pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1316 if src.remaining() < Self::SIZE {
1317 return Err(ProtocolError::IncompletePacket {
1318 expected: Self::SIZE,
1319 actual: src.remaining(),
1320 });
1321 }
1322
1323 let status = DoneStatus::from_bits(src.get_u16_le());
1324 let cur_cmd = src.get_u16_le();
1325 let row_count = src.get_u64_le();
1326
1327 Ok(Self {
1328 status,
1329 cur_cmd,
1330 row_count,
1331 })
1332 }
1333
1334 pub fn encode(&self, dst: &mut impl BufMut) {
1336 dst.put_u8(TokenType::Done as u8);
1337 dst.put_u16_le(self.status.to_bits());
1338 dst.put_u16_le(self.cur_cmd);
1339 dst.put_u64_le(self.row_count);
1340 }
1341
1342 #[must_use]
1344 pub const fn has_more(&self) -> bool {
1345 self.status.more
1346 }
1347
1348 #[must_use]
1350 pub const fn has_error(&self) -> bool {
1351 self.status.error
1352 }
1353
1354 #[must_use]
1356 pub const fn has_count(&self) -> bool {
1357 self.status.count
1358 }
1359}
1360
1361impl DoneProc {
1362 pub const SIZE: usize = 12;
1364
1365 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1367 if src.remaining() < Self::SIZE {
1368 return Err(ProtocolError::IncompletePacket {
1369 expected: Self::SIZE,
1370 actual: src.remaining(),
1371 });
1372 }
1373
1374 let status = DoneStatus::from_bits(src.get_u16_le());
1375 let cur_cmd = src.get_u16_le();
1376 let row_count = src.get_u64_le();
1377
1378 Ok(Self {
1379 status,
1380 cur_cmd,
1381 row_count,
1382 })
1383 }
1384
1385 pub fn encode(&self, dst: &mut impl BufMut) {
1387 dst.put_u8(TokenType::DoneProc as u8);
1388 dst.put_u16_le(self.status.to_bits());
1389 dst.put_u16_le(self.cur_cmd);
1390 dst.put_u64_le(self.row_count);
1391 }
1392}
1393
1394impl DoneInProc {
1395 pub const SIZE: usize = 12;
1397
1398 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1400 if src.remaining() < Self::SIZE {
1401 return Err(ProtocolError::IncompletePacket {
1402 expected: Self::SIZE,
1403 actual: src.remaining(),
1404 });
1405 }
1406
1407 let status = DoneStatus::from_bits(src.get_u16_le());
1408 let cur_cmd = src.get_u16_le();
1409 let row_count = src.get_u64_le();
1410
1411 Ok(Self {
1412 status,
1413 cur_cmd,
1414 row_count,
1415 })
1416 }
1417
1418 pub fn encode(&self, dst: &mut impl BufMut) {
1420 dst.put_u8(TokenType::DoneInProc as u8);
1421 dst.put_u16_le(self.status.to_bits());
1422 dst.put_u16_le(self.cur_cmd);
1423 dst.put_u64_le(self.row_count);
1424 }
1425}
1426
1427impl ServerError {
1428 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1430 if src.remaining() < 2 {
1433 return Err(ProtocolError::UnexpectedEof);
1434 }
1435
1436 let _length = src.get_u16_le();
1437
1438 if src.remaining() < 6 {
1439 return Err(ProtocolError::UnexpectedEof);
1440 }
1441
1442 let number = src.get_i32_le();
1443 let state = src.get_u8();
1444 let class = src.get_u8();
1445
1446 let message = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1447 let server = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1448 let procedure = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1449
1450 if src.remaining() < 4 {
1451 return Err(ProtocolError::UnexpectedEof);
1452 }
1453 let line = src.get_i32_le();
1454
1455 Ok(Self {
1456 number,
1457 state,
1458 class,
1459 message,
1460 server,
1461 procedure,
1462 line,
1463 })
1464 }
1465
1466 #[must_use]
1468 pub const fn is_fatal(&self) -> bool {
1469 self.class >= 20
1470 }
1471
1472 #[must_use]
1474 pub const fn is_batch_abort(&self) -> bool {
1475 self.class >= 16
1476 }
1477}
1478
1479impl ServerInfo {
1480 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1484 if src.remaining() < 2 {
1485 return Err(ProtocolError::UnexpectedEof);
1486 }
1487
1488 let _length = src.get_u16_le();
1489
1490 if src.remaining() < 6 {
1491 return Err(ProtocolError::UnexpectedEof);
1492 }
1493
1494 let number = src.get_i32_le();
1495 let state = src.get_u8();
1496 let class = src.get_u8();
1497
1498 let message = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1499 let server = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1500 let procedure = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1501
1502 if src.remaining() < 4 {
1503 return Err(ProtocolError::UnexpectedEof);
1504 }
1505 let line = src.get_i32_le();
1506
1507 Ok(Self {
1508 number,
1509 state,
1510 class,
1511 message,
1512 server,
1513 procedure,
1514 line,
1515 })
1516 }
1517}
1518
1519impl LoginAck {
1520 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1522 if src.remaining() < 2 {
1524 return Err(ProtocolError::UnexpectedEof);
1525 }
1526
1527 let _length = src.get_u16_le();
1528
1529 if src.remaining() < 5 {
1530 return Err(ProtocolError::UnexpectedEof);
1531 }
1532
1533 let interface = src.get_u8();
1534 let tds_version = src.get_u32_le();
1535 let prog_name = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1536
1537 if src.remaining() < 4 {
1538 return Err(ProtocolError::UnexpectedEof);
1539 }
1540 let prog_version = src.get_u32_le();
1541
1542 Ok(Self {
1543 interface,
1544 tds_version,
1545 prog_name,
1546 prog_version,
1547 })
1548 }
1549
1550 #[must_use]
1552 pub fn tds_version(&self) -> crate::version::TdsVersion {
1553 crate::version::TdsVersion::new(self.tds_version)
1554 }
1555}
1556
1557impl EnvChangeType {
1558 pub fn from_u8(value: u8) -> Option<Self> {
1560 match value {
1561 1 => Some(Self::Database),
1562 2 => Some(Self::Language),
1563 3 => Some(Self::CharacterSet),
1564 4 => Some(Self::PacketSize),
1565 5 => Some(Self::UnicodeSortingLocalId),
1566 6 => Some(Self::UnicodeComparisonFlags),
1567 7 => Some(Self::SqlCollation),
1568 8 => Some(Self::BeginTransaction),
1569 9 => Some(Self::CommitTransaction),
1570 10 => Some(Self::RollbackTransaction),
1571 11 => Some(Self::EnlistDtcTransaction),
1572 12 => Some(Self::DefectTransaction),
1573 13 => Some(Self::RealTimeLogShipping),
1574 15 => Some(Self::PromoteTransaction),
1575 16 => Some(Self::TransactionManagerAddress),
1576 17 => Some(Self::TransactionEnded),
1577 18 => Some(Self::ResetConnectionCompletionAck),
1578 19 => Some(Self::UserInstanceStarted),
1579 20 => Some(Self::Routing),
1580 _ => None,
1581 }
1582 }
1583}
1584
1585impl EnvChange {
1586 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1588 if src.remaining() < 3 {
1589 return Err(ProtocolError::UnexpectedEof);
1590 }
1591
1592 let length = src.get_u16_le() as usize;
1593 if src.remaining() < length {
1594 return Err(ProtocolError::IncompletePacket {
1595 expected: length,
1596 actual: src.remaining(),
1597 });
1598 }
1599
1600 let env_type_byte = src.get_u8();
1601 let env_type = EnvChangeType::from_u8(env_type_byte)
1602 .ok_or(ProtocolError::InvalidTokenType(env_type_byte))?;
1603
1604 let (new_value, old_value) = match env_type {
1605 EnvChangeType::Routing => {
1606 let new_value = Self::decode_routing_value(src)?;
1608 let old_value = EnvChangeValue::Binary(Bytes::new());
1609 (new_value, old_value)
1610 }
1611 EnvChangeType::BeginTransaction
1612 | EnvChangeType::CommitTransaction
1613 | EnvChangeType::RollbackTransaction
1614 | EnvChangeType::EnlistDtcTransaction
1615 | EnvChangeType::SqlCollation => {
1616 let new_len = src.get_u8() as usize;
1620 let new_value = if new_len > 0 && src.remaining() >= new_len {
1621 EnvChangeValue::Binary(src.copy_to_bytes(new_len))
1622 } else {
1623 EnvChangeValue::Binary(Bytes::new())
1624 };
1625
1626 let old_len = src.get_u8() as usize;
1627 let old_value = if old_len > 0 && src.remaining() >= old_len {
1628 EnvChangeValue::Binary(src.copy_to_bytes(old_len))
1629 } else {
1630 EnvChangeValue::Binary(Bytes::new())
1631 };
1632
1633 (new_value, old_value)
1634 }
1635 _ => {
1636 let new_value = read_b_varchar(src)
1638 .map(EnvChangeValue::String)
1639 .unwrap_or(EnvChangeValue::String(String::new()));
1640
1641 let old_value = read_b_varchar(src)
1642 .map(EnvChangeValue::String)
1643 .unwrap_or(EnvChangeValue::String(String::new()));
1644
1645 (new_value, old_value)
1646 }
1647 };
1648
1649 Ok(Self {
1650 env_type,
1651 new_value,
1652 old_value,
1653 })
1654 }
1655
1656 fn decode_routing_value(src: &mut impl Buf) -> Result<EnvChangeValue, ProtocolError> {
1657 if src.remaining() < 2 {
1659 return Err(ProtocolError::UnexpectedEof);
1660 }
1661
1662 let _routing_len = src.get_u16_le();
1663
1664 if src.remaining() < 5 {
1665 return Err(ProtocolError::UnexpectedEof);
1666 }
1667
1668 let _protocol = src.get_u8();
1669 let port = src.get_u16_le();
1670 let server_len = src.get_u16_le() as usize;
1671
1672 if src.remaining() < server_len * 2 {
1674 return Err(ProtocolError::UnexpectedEof);
1675 }
1676
1677 let mut chars = Vec::with_capacity(server_len);
1678 for _ in 0..server_len {
1679 chars.push(src.get_u16_le());
1680 }
1681
1682 let host = String::from_utf16(&chars).map_err(|_| {
1683 ProtocolError::StringEncoding(
1684 #[cfg(feature = "std")]
1685 "invalid UTF-16 in routing hostname".to_string(),
1686 #[cfg(not(feature = "std"))]
1687 "invalid UTF-16 in routing hostname",
1688 )
1689 })?;
1690
1691 Ok(EnvChangeValue::Routing { host, port })
1692 }
1693
1694 #[must_use]
1696 pub fn is_routing(&self) -> bool {
1697 self.env_type == EnvChangeType::Routing
1698 }
1699
1700 #[must_use]
1702 pub fn routing_info(&self) -> Option<(&str, u16)> {
1703 if let EnvChangeValue::Routing { host, port } = &self.new_value {
1704 Some((host, *port))
1705 } else {
1706 None
1707 }
1708 }
1709
1710 #[must_use]
1712 pub fn new_database(&self) -> Option<&str> {
1713 if self.env_type == EnvChangeType::Database {
1714 if let EnvChangeValue::String(s) = &self.new_value {
1715 return Some(s);
1716 }
1717 }
1718 None
1719 }
1720}
1721
1722impl Order {
1723 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1725 if src.remaining() < 2 {
1726 return Err(ProtocolError::UnexpectedEof);
1727 }
1728
1729 let length = src.get_u16_le() as usize;
1730 let column_count = length / 2;
1731
1732 if src.remaining() < length {
1733 return Err(ProtocolError::IncompletePacket {
1734 expected: length,
1735 actual: src.remaining(),
1736 });
1737 }
1738
1739 let mut columns = Vec::with_capacity(column_count);
1740 for _ in 0..column_count {
1741 columns.push(src.get_u16_le());
1742 }
1743
1744 Ok(Self { columns })
1745 }
1746}
1747
1748impl FeatureExtAck {
1749 pub const TERMINATOR: u8 = 0xFF;
1751
1752 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1754 let mut features = Vec::new();
1755
1756 loop {
1757 if !src.has_remaining() {
1758 return Err(ProtocolError::UnexpectedEof);
1759 }
1760
1761 let feature_id = src.get_u8();
1762 if feature_id == Self::TERMINATOR {
1763 break;
1764 }
1765
1766 if src.remaining() < 4 {
1767 return Err(ProtocolError::UnexpectedEof);
1768 }
1769
1770 let data_len = src.get_u32_le() as usize;
1771
1772 if src.remaining() < data_len {
1773 return Err(ProtocolError::IncompletePacket {
1774 expected: data_len,
1775 actual: src.remaining(),
1776 });
1777 }
1778
1779 let data = src.copy_to_bytes(data_len);
1780 features.push(FeatureAck { feature_id, data });
1781 }
1782
1783 Ok(Self { features })
1784 }
1785}
1786
1787impl SspiToken {
1788 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1790 if src.remaining() < 2 {
1791 return Err(ProtocolError::UnexpectedEof);
1792 }
1793
1794 let length = src.get_u16_le() as usize;
1795
1796 if src.remaining() < length {
1797 return Err(ProtocolError::IncompletePacket {
1798 expected: length,
1799 actual: src.remaining(),
1800 });
1801 }
1802
1803 let data = src.copy_to_bytes(length);
1804 Ok(Self { data })
1805 }
1806}
1807
1808impl FedAuthInfo {
1809 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1811 if src.remaining() < 4 {
1812 return Err(ProtocolError::UnexpectedEof);
1813 }
1814
1815 let _length = src.get_u32_le();
1816
1817 if src.remaining() < 5 {
1818 return Err(ProtocolError::UnexpectedEof);
1819 }
1820
1821 let _count = src.get_u8();
1822
1823 let mut sts_url = String::new();
1825 let mut spn = String::new();
1826
1827 while src.has_remaining() {
1829 if src.remaining() < 9 {
1830 break;
1831 }
1832
1833 let info_id = src.get_u8();
1834 let info_len = src.get_u32_le() as usize;
1835 let _info_offset = src.get_u32_le();
1836
1837 if src.remaining() < info_len {
1838 break;
1839 }
1840
1841 let char_count = info_len / 2;
1843 let mut chars = Vec::with_capacity(char_count);
1844 for _ in 0..char_count {
1845 chars.push(src.get_u16_le());
1846 }
1847
1848 if let Ok(value) = String::from_utf16(&chars) {
1849 match info_id {
1850 0x01 => spn = value,
1851 0x02 => sts_url = value,
1852 _ => {}
1853 }
1854 }
1855 }
1856
1857 Ok(Self { sts_url, spn })
1858 }
1859}
1860
1861pub struct TokenParser {
1902 data: Bytes,
1903 position: usize,
1904}
1905
1906impl TokenParser {
1907 #[must_use]
1909 pub fn new(data: Bytes) -> Self {
1910 Self { data, position: 0 }
1911 }
1912
1913 #[must_use]
1915 pub fn remaining(&self) -> usize {
1916 self.data.len().saturating_sub(self.position)
1917 }
1918
1919 #[must_use]
1921 pub fn has_remaining(&self) -> bool {
1922 self.position < self.data.len()
1923 }
1924
1925 #[must_use]
1927 pub fn peek_token_type(&self) -> Option<TokenType> {
1928 if self.position < self.data.len() {
1929 TokenType::from_u8(self.data[self.position])
1930 } else {
1931 None
1932 }
1933 }
1934
1935 pub fn next_token(&mut self) -> Result<Option<Token>, ProtocolError> {
1943 self.next_token_with_metadata(None)
1944 }
1945
1946 pub fn next_token_with_metadata(
1953 &mut self,
1954 metadata: Option<&ColMetaData>,
1955 ) -> Result<Option<Token>, ProtocolError> {
1956 if !self.has_remaining() {
1957 return Ok(None);
1958 }
1959
1960 let mut buf = &self.data[self.position..];
1961 let start_pos = self.position;
1962
1963 let token_type_byte = buf.get_u8();
1964 let token_type = TokenType::from_u8(token_type_byte);
1965
1966 let token = match token_type {
1967 Some(TokenType::Done) => {
1968 let done = Done::decode(&mut buf)?;
1969 Token::Done(done)
1970 }
1971 Some(TokenType::DoneProc) => {
1972 let done = DoneProc::decode(&mut buf)?;
1973 Token::DoneProc(done)
1974 }
1975 Some(TokenType::DoneInProc) => {
1976 let done = DoneInProc::decode(&mut buf)?;
1977 Token::DoneInProc(done)
1978 }
1979 Some(TokenType::Error) => {
1980 let error = ServerError::decode(&mut buf)?;
1981 Token::Error(error)
1982 }
1983 Some(TokenType::Info) => {
1984 let info = ServerInfo::decode(&mut buf)?;
1985 Token::Info(info)
1986 }
1987 Some(TokenType::LoginAck) => {
1988 let login_ack = LoginAck::decode(&mut buf)?;
1989 Token::LoginAck(login_ack)
1990 }
1991 Some(TokenType::EnvChange) => {
1992 let env_change = EnvChange::decode(&mut buf)?;
1993 Token::EnvChange(env_change)
1994 }
1995 Some(TokenType::Order) => {
1996 let order = Order::decode(&mut buf)?;
1997 Token::Order(order)
1998 }
1999 Some(TokenType::FeatureExtAck) => {
2000 let ack = FeatureExtAck::decode(&mut buf)?;
2001 Token::FeatureExtAck(ack)
2002 }
2003 Some(TokenType::Sspi) => {
2004 let sspi = SspiToken::decode(&mut buf)?;
2005 Token::Sspi(sspi)
2006 }
2007 Some(TokenType::FedAuthInfo) => {
2008 let info = FedAuthInfo::decode(&mut buf)?;
2009 Token::FedAuthInfo(info)
2010 }
2011 Some(TokenType::ReturnStatus) => {
2012 if buf.remaining() < 4 {
2013 return Err(ProtocolError::UnexpectedEof);
2014 }
2015 let status = buf.get_i32_le();
2016 Token::ReturnStatus(status)
2017 }
2018 Some(TokenType::ColMetaData) => {
2019 let col_meta = ColMetaData::decode(&mut buf)?;
2020 Token::ColMetaData(col_meta)
2021 }
2022 Some(TokenType::Row) => {
2023 let meta = metadata.ok_or_else(|| {
2024 ProtocolError::StringEncoding(
2025 #[cfg(feature = "std")]
2026 "Row token requires column metadata".to_string(),
2027 #[cfg(not(feature = "std"))]
2028 "Row token requires column metadata",
2029 )
2030 })?;
2031 let row = RawRow::decode(&mut buf, meta)?;
2032 Token::Row(row)
2033 }
2034 Some(TokenType::NbcRow) => {
2035 let meta = metadata.ok_or_else(|| {
2036 ProtocolError::StringEncoding(
2037 #[cfg(feature = "std")]
2038 "NbcRow token requires column metadata".to_string(),
2039 #[cfg(not(feature = "std"))]
2040 "NbcRow token requires column metadata",
2041 )
2042 })?;
2043 let row = NbcRow::decode(&mut buf, meta)?;
2044 Token::NbcRow(row)
2045 }
2046 Some(TokenType::ReturnValue) => {
2047 let ret_val = ReturnValue::decode(&mut buf)?;
2048 Token::ReturnValue(ret_val)
2049 }
2050 Some(TokenType::SessionState) => {
2051 let session = SessionState::decode(&mut buf)?;
2052 Token::SessionState(session)
2053 }
2054 Some(TokenType::ColInfo) | Some(TokenType::TabName) | Some(TokenType::Offset) => {
2055 if buf.remaining() < 2 {
2058 return Err(ProtocolError::UnexpectedEof);
2059 }
2060 let length = buf.get_u16_le() as usize;
2061 if buf.remaining() < length {
2062 return Err(ProtocolError::IncompletePacket {
2063 expected: length,
2064 actual: buf.remaining(),
2065 });
2066 }
2067 buf.advance(length);
2069 self.position = start_pos + (self.data.len() - start_pos - buf.remaining());
2071 return self.next_token_with_metadata(metadata);
2072 }
2073 None => {
2074 return Err(ProtocolError::InvalidTokenType(token_type_byte));
2075 }
2076 };
2077
2078 let consumed = self.data.len() - start_pos - buf.remaining();
2080 self.position = start_pos + consumed;
2081
2082 Ok(Some(token))
2083 }
2084
2085 pub fn skip_token(&mut self) -> Result<(), ProtocolError> {
2089 if !self.has_remaining() {
2090 return Ok(());
2091 }
2092
2093 let token_type_byte = self.data[self.position];
2094 let token_type = TokenType::from_u8(token_type_byte);
2095
2096 let skip_amount = match token_type {
2098 Some(TokenType::Done) | Some(TokenType::DoneProc) | Some(TokenType::DoneInProc) => {
2100 1 + Done::SIZE }
2102 Some(TokenType::ReturnStatus) => {
2103 1 + 4 }
2105 Some(TokenType::Error)
2107 | Some(TokenType::Info)
2108 | Some(TokenType::LoginAck)
2109 | Some(TokenType::EnvChange)
2110 | Some(TokenType::Order)
2111 | Some(TokenType::Sspi)
2112 | Some(TokenType::ColInfo)
2113 | Some(TokenType::TabName)
2114 | Some(TokenType::Offset)
2115 | Some(TokenType::ReturnValue) => {
2116 if self.remaining() < 3 {
2117 return Err(ProtocolError::UnexpectedEof);
2118 }
2119 let length = u16::from_le_bytes([
2120 self.data[self.position + 1],
2121 self.data[self.position + 2],
2122 ]) as usize;
2123 1 + 2 + length }
2125 Some(TokenType::SessionState) | Some(TokenType::FedAuthInfo) => {
2127 if self.remaining() < 5 {
2128 return Err(ProtocolError::UnexpectedEof);
2129 }
2130 let length = u32::from_le_bytes([
2131 self.data[self.position + 1],
2132 self.data[self.position + 2],
2133 self.data[self.position + 3],
2134 self.data[self.position + 4],
2135 ]) as usize;
2136 1 + 4 + length
2137 }
2138 Some(TokenType::FeatureExtAck) => {
2140 let mut buf = &self.data[self.position + 1..];
2142 let _ = FeatureExtAck::decode(&mut buf)?;
2143 self.data.len() - self.position - buf.remaining()
2144 }
2145 Some(TokenType::ColMetaData) | Some(TokenType::Row) | Some(TokenType::NbcRow) => {
2147 return Err(ProtocolError::InvalidTokenType(token_type_byte));
2148 }
2149 None => {
2150 return Err(ProtocolError::InvalidTokenType(token_type_byte));
2151 }
2152 };
2153
2154 if self.remaining() < skip_amount {
2155 return Err(ProtocolError::UnexpectedEof);
2156 }
2157
2158 self.position += skip_amount;
2159 Ok(())
2160 }
2161
2162 #[must_use]
2164 pub fn position(&self) -> usize {
2165 self.position
2166 }
2167
2168 pub fn reset(&mut self) {
2170 self.position = 0;
2171 }
2172}
2173
2174#[cfg(not(feature = "std"))]
2179use alloc::string::String;
2180#[cfg(not(feature = "std"))]
2181use alloc::vec::Vec;
2182
2183#[cfg(test)]
2188#[allow(clippy::unwrap_used, clippy::panic)]
2189mod tests {
2190 use super::*;
2191 use bytes::BytesMut;
2192
2193 #[test]
2194 fn test_done_roundtrip() {
2195 let done = Done {
2196 status: DoneStatus {
2197 more: false,
2198 error: false,
2199 in_xact: false,
2200 count: true,
2201 attn: false,
2202 srverror: false,
2203 },
2204 cur_cmd: 193, row_count: 42,
2206 };
2207
2208 let mut buf = BytesMut::new();
2209 done.encode(&mut buf);
2210
2211 let mut cursor = &buf[1..];
2213 let decoded = Done::decode(&mut cursor).unwrap();
2214
2215 assert_eq!(decoded.status.count, done.status.count);
2216 assert_eq!(decoded.cur_cmd, done.cur_cmd);
2217 assert_eq!(decoded.row_count, done.row_count);
2218 }
2219
2220 #[test]
2221 fn test_done_status_bits() {
2222 let status = DoneStatus {
2223 more: true,
2224 error: true,
2225 in_xact: true,
2226 count: true,
2227 attn: false,
2228 srverror: false,
2229 };
2230
2231 let bits = status.to_bits();
2232 let restored = DoneStatus::from_bits(bits);
2233
2234 assert_eq!(status.more, restored.more);
2235 assert_eq!(status.error, restored.error);
2236 assert_eq!(status.in_xact, restored.in_xact);
2237 assert_eq!(status.count, restored.count);
2238 }
2239
2240 #[test]
2241 fn test_token_parser_done() {
2242 let data = Bytes::from_static(&[
2244 0xFD, 0x10, 0x00, 0xC1, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]);
2249
2250 let mut parser = TokenParser::new(data);
2251 let token = parser.next_token().unwrap().unwrap();
2252
2253 match token {
2254 Token::Done(done) => {
2255 assert!(done.status.count);
2256 assert!(!done.status.more);
2257 assert_eq!(done.cur_cmd, 193);
2258 assert_eq!(done.row_count, 5);
2259 }
2260 _ => panic!("Expected Done token"),
2261 }
2262
2263 assert!(parser.next_token().unwrap().is_none());
2265 }
2266
2267 #[test]
2268 fn test_env_change_type_from_u8() {
2269 assert_eq!(EnvChangeType::from_u8(1), Some(EnvChangeType::Database));
2270 assert_eq!(EnvChangeType::from_u8(20), Some(EnvChangeType::Routing));
2271 assert_eq!(EnvChangeType::from_u8(100), None);
2272 }
2273
2274 #[test]
2275 fn test_colmetadata_no_columns() {
2276 let data = Bytes::from_static(&[0xFF, 0xFF]);
2278 let mut cursor: &[u8] = &data;
2279 let meta = ColMetaData::decode(&mut cursor).unwrap();
2280 assert!(meta.is_empty());
2281 assert_eq!(meta.column_count(), 0);
2282 }
2283
2284 #[test]
2285 fn test_colmetadata_single_int_column() {
2286 let mut data = BytesMut::new();
2289 data.extend_from_slice(&[0x01, 0x00]); data.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); data.extend_from_slice(&[0x01, 0x00]); data.extend_from_slice(&[0x38]); data.extend_from_slice(&[0x02]); data.extend_from_slice(&[b'i', 0x00, b'd', 0x00]); let mut cursor: &[u8] = &data;
2298 let meta = ColMetaData::decode(&mut cursor).unwrap();
2299
2300 assert_eq!(meta.column_count(), 1);
2301 assert_eq!(meta.columns[0].name, "id");
2302 assert_eq!(meta.columns[0].type_id, TypeId::Int4);
2303 assert!(meta.columns[0].is_nullable());
2304 }
2305
2306 #[test]
2307 fn test_colmetadata_nvarchar_column() {
2308 let mut data = BytesMut::new();
2310 data.extend_from_slice(&[0x01, 0x00]); data.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); data.extend_from_slice(&[0x01, 0x00]); data.extend_from_slice(&[0xE7]); data.extend_from_slice(&[0x64, 0x00]); data.extend_from_slice(&[0x09, 0x04, 0xD0, 0x00, 0x34]); data.extend_from_slice(&[0x04]); data.extend_from_slice(&[b'n', 0x00, b'a', 0x00, b'm', 0x00, b'e', 0x00]);
2320
2321 let mut cursor: &[u8] = &data;
2322 let meta = ColMetaData::decode(&mut cursor).unwrap();
2323
2324 assert_eq!(meta.column_count(), 1);
2325 assert_eq!(meta.columns[0].name, "name");
2326 assert_eq!(meta.columns[0].type_id, TypeId::NVarChar);
2327 assert_eq!(meta.columns[0].type_info.max_length, Some(100));
2328 assert!(meta.columns[0].type_info.collation.is_some());
2329 }
2330
2331 #[test]
2332 fn test_raw_row_decode_int() {
2333 let metadata = ColMetaData {
2335 columns: vec![ColumnData {
2336 name: "id".to_string(),
2337 type_id: TypeId::Int4,
2338 col_type: 0x38,
2339 flags: 0,
2340 user_type: 0,
2341 type_info: TypeInfo::default(),
2342 }],
2343 };
2344
2345 let data = Bytes::from_static(&[0x2A, 0x00, 0x00, 0x00]); let mut cursor: &[u8] = &data;
2348 let row = RawRow::decode(&mut cursor, &metadata).unwrap();
2349
2350 assert_eq!(row.data.len(), 4);
2352 assert_eq!(&row.data[..], &[0x2A, 0x00, 0x00, 0x00]);
2353 }
2354
2355 #[test]
2356 fn test_raw_row_decode_nullable_int() {
2357 let metadata = ColMetaData {
2359 columns: vec![ColumnData {
2360 name: "id".to_string(),
2361 type_id: TypeId::IntN,
2362 col_type: 0x26,
2363 flags: 0x01, user_type: 0,
2365 type_info: TypeInfo {
2366 max_length: Some(4),
2367 ..Default::default()
2368 },
2369 }],
2370 };
2371
2372 let data = Bytes::from_static(&[0x04, 0x2A, 0x00, 0x00, 0x00]); let mut cursor: &[u8] = &data;
2375 let row = RawRow::decode(&mut cursor, &metadata).unwrap();
2376
2377 assert_eq!(row.data.len(), 5);
2378 assert_eq!(row.data[0], 4); assert_eq!(&row.data[1..], &[0x2A, 0x00, 0x00, 0x00]);
2380 }
2381
2382 #[test]
2383 fn test_raw_row_decode_null_value() {
2384 let metadata = ColMetaData {
2386 columns: vec![ColumnData {
2387 name: "id".to_string(),
2388 type_id: TypeId::IntN,
2389 col_type: 0x26,
2390 flags: 0x01, user_type: 0,
2392 type_info: TypeInfo {
2393 max_length: Some(4),
2394 ..Default::default()
2395 },
2396 }],
2397 };
2398
2399 let data = Bytes::from_static(&[0xFF]);
2401 let mut cursor: &[u8] = &data;
2402 let row = RawRow::decode(&mut cursor, &metadata).unwrap();
2403
2404 assert_eq!(row.data.len(), 1);
2405 assert_eq!(row.data[0], 0xFF); }
2407
2408 #[test]
2409 fn test_nbcrow_null_bitmap() {
2410 let row = NbcRow {
2411 null_bitmap: vec![0b00000101], data: Bytes::new(),
2413 };
2414
2415 assert!(row.is_null(0));
2416 assert!(!row.is_null(1));
2417 assert!(row.is_null(2));
2418 assert!(!row.is_null(3));
2419 }
2420
2421 #[test]
2422 fn test_token_parser_colmetadata() {
2423 let mut data = BytesMut::new();
2425 data.extend_from_slice(&[0x81]); data.extend_from_slice(&[0x01, 0x00]); data.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); data.extend_from_slice(&[0x01, 0x00]); data.extend_from_slice(&[0x38]); data.extend_from_slice(&[0x02]); data.extend_from_slice(&[b'i', 0x00, b'd', 0x00]); let mut parser = TokenParser::new(data.freeze());
2434 let token = parser.next_token().unwrap().unwrap();
2435
2436 match token {
2437 Token::ColMetaData(meta) => {
2438 assert_eq!(meta.column_count(), 1);
2439 assert_eq!(meta.columns[0].name, "id");
2440 assert_eq!(meta.columns[0].type_id, TypeId::Int4);
2441 }
2442 _ => panic!("Expected ColMetaData token"),
2443 }
2444 }
2445
2446 #[test]
2447 fn test_token_parser_row_with_metadata() {
2448 let metadata = ColMetaData {
2450 columns: vec![ColumnData {
2451 name: "id".to_string(),
2452 type_id: TypeId::Int4,
2453 col_type: 0x38,
2454 flags: 0,
2455 user_type: 0,
2456 type_info: TypeInfo::default(),
2457 }],
2458 };
2459
2460 let mut data = BytesMut::new();
2462 data.extend_from_slice(&[0xD1]); data.extend_from_slice(&[0x2A, 0x00, 0x00, 0x00]); let mut parser = TokenParser::new(data.freeze());
2466 let token = parser
2467 .next_token_with_metadata(Some(&metadata))
2468 .unwrap()
2469 .unwrap();
2470
2471 match token {
2472 Token::Row(row) => {
2473 assert_eq!(row.data.len(), 4);
2474 }
2475 _ => panic!("Expected Row token"),
2476 }
2477 }
2478
2479 #[test]
2480 fn test_token_parser_row_without_metadata_fails() {
2481 let mut data = BytesMut::new();
2483 data.extend_from_slice(&[0xD1]); data.extend_from_slice(&[0x2A, 0x00, 0x00, 0x00]); let mut parser = TokenParser::new(data.freeze());
2487 let result = parser.next_token(); assert!(result.is_err());
2490 }
2491
2492 #[test]
2493 fn test_token_parser_peek() {
2494 let data = Bytes::from_static(&[
2495 0xFD, 0x10, 0x00, 0xC1, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]);
2500
2501 let parser = TokenParser::new(data);
2502 assert_eq!(parser.peek_token_type(), Some(TokenType::Done));
2503 }
2504
2505 #[test]
2506 fn test_column_data_fixed_size() {
2507 let col = ColumnData {
2508 name: String::new(),
2509 type_id: TypeId::Int4,
2510 col_type: 0x38,
2511 flags: 0,
2512 user_type: 0,
2513 type_info: TypeInfo::default(),
2514 };
2515 assert_eq!(col.fixed_size(), Some(4));
2516
2517 let col2 = ColumnData {
2518 name: String::new(),
2519 type_id: TypeId::NVarChar,
2520 col_type: 0xE7,
2521 flags: 0,
2522 user_type: 0,
2523 type_info: TypeInfo::default(),
2524 };
2525 assert_eq!(col2.fixed_size(), None);
2526 }
2527}