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::BigChar | TypeId::BigVarBinary | TypeId::BigBinary => {
919 Self::decode_ushortlen_type(src, dst)?;
920 }
921
922 TypeId::NChar | TypeId::NVarChar => {
924 Self::decode_ushortlen_type(src, dst)?;
925 }
926
927 TypeId::Time | TypeId::DateTime2 | TypeId::DateTimeOffset => {
929 Self::decode_bytelen_type(src, dst)?;
930 }
931
932 TypeId::Text | TypeId::NText | TypeId::Image | TypeId::Xml => {
934 Self::decode_plp_type(src, dst)?;
935 }
936
937 TypeId::Variant => {
939 Self::decode_intlen_type(src, dst)?;
940 }
941
942 TypeId::Udt => {
943 Self::decode_plp_type(src, dst)?;
945 }
946
947 TypeId::Tvp => {
948 return Err(ProtocolError::InvalidTokenType(col.col_type));
950 }
951 }
952
953 Ok(())
954 }
955
956 fn decode_bytelen_type(
958 src: &mut impl Buf,
959 dst: &mut bytes::BytesMut,
960 ) -> Result<(), ProtocolError> {
961 if src.remaining() < 1 {
962 return Err(ProtocolError::UnexpectedEof);
963 }
964 let len = src.get_u8() as usize;
965 if len == 0xFF {
966 dst.extend_from_slice(&[0xFF]);
968 } else if len == 0 {
969 dst.extend_from_slice(&[0x00]);
971 } else {
972 if src.remaining() < len {
973 return Err(ProtocolError::UnexpectedEof);
974 }
975 dst.extend_from_slice(&[len as u8]);
976 for _ in 0..len {
977 dst.extend_from_slice(&[src.get_u8()]);
978 }
979 }
980 Ok(())
981 }
982
983 fn decode_ushortlen_type(
985 src: &mut impl Buf,
986 dst: &mut bytes::BytesMut,
987 ) -> Result<(), ProtocolError> {
988 if src.remaining() < 2 {
989 return Err(ProtocolError::UnexpectedEof);
990 }
991 let len = src.get_u16_le() as usize;
992 if len == 0xFFFF {
993 dst.extend_from_slice(&0xFFFFu16.to_le_bytes());
995 } else if len == 0 {
996 dst.extend_from_slice(&0u16.to_le_bytes());
998 } else {
999 if src.remaining() < len {
1000 return Err(ProtocolError::UnexpectedEof);
1001 }
1002 dst.extend_from_slice(&(len as u16).to_le_bytes());
1003 for _ in 0..len {
1004 dst.extend_from_slice(&[src.get_u8()]);
1005 }
1006 }
1007 Ok(())
1008 }
1009
1010 fn decode_intlen_type(
1012 src: &mut impl Buf,
1013 dst: &mut bytes::BytesMut,
1014 ) -> Result<(), ProtocolError> {
1015 if src.remaining() < 4 {
1016 return Err(ProtocolError::UnexpectedEof);
1017 }
1018 let len = src.get_u32_le() as usize;
1019 if len == 0xFFFFFFFF {
1020 dst.extend_from_slice(&0xFFFFFFFFu32.to_le_bytes());
1022 } else if len == 0 {
1023 dst.extend_from_slice(&0u32.to_le_bytes());
1025 } else {
1026 if src.remaining() < len {
1027 return Err(ProtocolError::UnexpectedEof);
1028 }
1029 dst.extend_from_slice(&(len as u32).to_le_bytes());
1030 for _ in 0..len {
1031 dst.extend_from_slice(&[src.get_u8()]);
1032 }
1033 }
1034 Ok(())
1035 }
1036
1037 fn decode_plp_type(src: &mut impl Buf, dst: &mut bytes::BytesMut) -> Result<(), ProtocolError> {
1043 if src.remaining() < 8 {
1044 return Err(ProtocolError::UnexpectedEof);
1045 }
1046
1047 let total_len = src.get_u64_le();
1048
1049 dst.extend_from_slice(&total_len.to_le_bytes());
1051
1052 if total_len == 0xFFFFFFFFFFFFFFFF {
1053 return Ok(());
1055 }
1056
1057 loop {
1059 if src.remaining() < 4 {
1060 return Err(ProtocolError::UnexpectedEof);
1061 }
1062 let chunk_len = src.get_u32_le() as usize;
1063 dst.extend_from_slice(&(chunk_len as u32).to_le_bytes());
1064
1065 if chunk_len == 0 {
1066 break;
1068 }
1069
1070 if src.remaining() < chunk_len {
1071 return Err(ProtocolError::UnexpectedEof);
1072 }
1073
1074 for _ in 0..chunk_len {
1075 dst.extend_from_slice(&[src.get_u8()]);
1076 }
1077 }
1078
1079 Ok(())
1080 }
1081}
1082
1083impl NbcRow {
1088 pub fn decode(src: &mut impl Buf, metadata: &ColMetaData) -> Result<Self, ProtocolError> {
1093 let col_count = metadata.columns.len();
1094 let bitmap_len = (col_count + 7) / 8;
1095
1096 if src.remaining() < bitmap_len {
1097 return Err(ProtocolError::UnexpectedEof);
1098 }
1099
1100 let mut null_bitmap = vec![0u8; bitmap_len];
1102 for byte in &mut null_bitmap {
1103 *byte = src.get_u8();
1104 }
1105
1106 let mut data = bytes::BytesMut::new();
1108
1109 for (i, col) in metadata.columns.iter().enumerate() {
1110 let byte_idx = i / 8;
1111 let bit_idx = i % 8;
1112 let is_null = (null_bitmap[byte_idx] & (1 << bit_idx)) != 0;
1113
1114 if !is_null {
1115 RawRow::decode_column_value(src, col, &mut data)?;
1118 }
1119 }
1120
1121 Ok(Self {
1122 null_bitmap,
1123 data: data.freeze(),
1124 })
1125 }
1126
1127 #[must_use]
1129 pub fn is_null(&self, column_index: usize) -> bool {
1130 let byte_idx = column_index / 8;
1131 let bit_idx = column_index % 8;
1132 if byte_idx < self.null_bitmap.len() {
1133 (self.null_bitmap[byte_idx] & (1 << bit_idx)) != 0
1134 } else {
1135 true }
1137 }
1138}
1139
1140impl ReturnValue {
1145 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1147 if src.remaining() < 2 {
1149 return Err(ProtocolError::UnexpectedEof);
1150 }
1151 let _length = src.get_u16_le();
1152
1153 if src.remaining() < 2 {
1155 return Err(ProtocolError::UnexpectedEof);
1156 }
1157 let param_ordinal = src.get_u16_le();
1158
1159 let param_name = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1161
1162 if src.remaining() < 1 {
1164 return Err(ProtocolError::UnexpectedEof);
1165 }
1166 let status = src.get_u8();
1167
1168 if src.remaining() < 7 {
1170 return Err(ProtocolError::UnexpectedEof);
1171 }
1172 let user_type = src.get_u32_le();
1173 let flags = src.get_u16_le();
1174 let col_type = src.get_u8();
1175
1176 let type_id = TypeId::from_u8(col_type).unwrap_or(TypeId::Null);
1177
1178 let type_info = ColMetaData::decode_type_info(src, type_id, col_type)?;
1180
1181 let mut value_buf = bytes::BytesMut::new();
1183
1184 let temp_col = ColumnData {
1186 name: String::new(),
1187 type_id,
1188 col_type,
1189 flags,
1190 user_type,
1191 type_info: type_info.clone(),
1192 };
1193
1194 RawRow::decode_column_value(src, &temp_col, &mut value_buf)?;
1195
1196 Ok(Self {
1197 param_ordinal,
1198 param_name,
1199 status,
1200 user_type,
1201 flags,
1202 type_info,
1203 value: value_buf.freeze(),
1204 })
1205 }
1206}
1207
1208impl SessionState {
1213 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1215 if src.remaining() < 4 {
1216 return Err(ProtocolError::UnexpectedEof);
1217 }
1218
1219 let length = src.get_u32_le() as usize;
1220
1221 if src.remaining() < length {
1222 return Err(ProtocolError::IncompletePacket {
1223 expected: length,
1224 actual: src.remaining(),
1225 });
1226 }
1227
1228 let data = src.copy_to_bytes(length);
1229
1230 Ok(Self { data })
1231 }
1232}
1233
1234mod done_status_bits {
1240 pub const DONE_MORE: u16 = 0x0001;
1241 pub const DONE_ERROR: u16 = 0x0002;
1242 pub const DONE_INXACT: u16 = 0x0004;
1243 pub const DONE_COUNT: u16 = 0x0010;
1244 pub const DONE_ATTN: u16 = 0x0020;
1245 pub const DONE_SRVERROR: u16 = 0x0100;
1246}
1247
1248impl DoneStatus {
1249 #[must_use]
1251 pub fn from_bits(bits: u16) -> Self {
1252 use done_status_bits::*;
1253 Self {
1254 more: (bits & DONE_MORE) != 0,
1255 error: (bits & DONE_ERROR) != 0,
1256 in_xact: (bits & DONE_INXACT) != 0,
1257 count: (bits & DONE_COUNT) != 0,
1258 attn: (bits & DONE_ATTN) != 0,
1259 srverror: (bits & DONE_SRVERROR) != 0,
1260 }
1261 }
1262
1263 #[must_use]
1265 pub fn to_bits(&self) -> u16 {
1266 use done_status_bits::*;
1267 let mut bits = 0u16;
1268 if self.more {
1269 bits |= DONE_MORE;
1270 }
1271 if self.error {
1272 bits |= DONE_ERROR;
1273 }
1274 if self.in_xact {
1275 bits |= DONE_INXACT;
1276 }
1277 if self.count {
1278 bits |= DONE_COUNT;
1279 }
1280 if self.attn {
1281 bits |= DONE_ATTN;
1282 }
1283 if self.srverror {
1284 bits |= DONE_SRVERROR;
1285 }
1286 bits
1287 }
1288}
1289
1290impl Done {
1291 pub const SIZE: usize = 12; pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1296 if src.remaining() < Self::SIZE {
1297 return Err(ProtocolError::IncompletePacket {
1298 expected: Self::SIZE,
1299 actual: src.remaining(),
1300 });
1301 }
1302
1303 let status = DoneStatus::from_bits(src.get_u16_le());
1304 let cur_cmd = src.get_u16_le();
1305 let row_count = src.get_u64_le();
1306
1307 Ok(Self {
1308 status,
1309 cur_cmd,
1310 row_count,
1311 })
1312 }
1313
1314 pub fn encode(&self, dst: &mut impl BufMut) {
1316 dst.put_u8(TokenType::Done as u8);
1317 dst.put_u16_le(self.status.to_bits());
1318 dst.put_u16_le(self.cur_cmd);
1319 dst.put_u64_le(self.row_count);
1320 }
1321
1322 #[must_use]
1324 pub const fn has_more(&self) -> bool {
1325 self.status.more
1326 }
1327
1328 #[must_use]
1330 pub const fn has_error(&self) -> bool {
1331 self.status.error
1332 }
1333
1334 #[must_use]
1336 pub const fn has_count(&self) -> bool {
1337 self.status.count
1338 }
1339}
1340
1341impl DoneProc {
1342 pub const SIZE: usize = 12;
1344
1345 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1347 if src.remaining() < Self::SIZE {
1348 return Err(ProtocolError::IncompletePacket {
1349 expected: Self::SIZE,
1350 actual: src.remaining(),
1351 });
1352 }
1353
1354 let status = DoneStatus::from_bits(src.get_u16_le());
1355 let cur_cmd = src.get_u16_le();
1356 let row_count = src.get_u64_le();
1357
1358 Ok(Self {
1359 status,
1360 cur_cmd,
1361 row_count,
1362 })
1363 }
1364
1365 pub fn encode(&self, dst: &mut impl BufMut) {
1367 dst.put_u8(TokenType::DoneProc as u8);
1368 dst.put_u16_le(self.status.to_bits());
1369 dst.put_u16_le(self.cur_cmd);
1370 dst.put_u64_le(self.row_count);
1371 }
1372}
1373
1374impl DoneInProc {
1375 pub const SIZE: usize = 12;
1377
1378 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1380 if src.remaining() < Self::SIZE {
1381 return Err(ProtocolError::IncompletePacket {
1382 expected: Self::SIZE,
1383 actual: src.remaining(),
1384 });
1385 }
1386
1387 let status = DoneStatus::from_bits(src.get_u16_le());
1388 let cur_cmd = src.get_u16_le();
1389 let row_count = src.get_u64_le();
1390
1391 Ok(Self {
1392 status,
1393 cur_cmd,
1394 row_count,
1395 })
1396 }
1397
1398 pub fn encode(&self, dst: &mut impl BufMut) {
1400 dst.put_u8(TokenType::DoneInProc as u8);
1401 dst.put_u16_le(self.status.to_bits());
1402 dst.put_u16_le(self.cur_cmd);
1403 dst.put_u64_le(self.row_count);
1404 }
1405}
1406
1407impl ServerError {
1408 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1410 if src.remaining() < 2 {
1413 return Err(ProtocolError::UnexpectedEof);
1414 }
1415
1416 let _length = src.get_u16_le();
1417
1418 if src.remaining() < 6 {
1419 return Err(ProtocolError::UnexpectedEof);
1420 }
1421
1422 let number = src.get_i32_le();
1423 let state = src.get_u8();
1424 let class = src.get_u8();
1425
1426 let message = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1427 let server = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1428 let procedure = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1429
1430 if src.remaining() < 4 {
1431 return Err(ProtocolError::UnexpectedEof);
1432 }
1433 let line = src.get_i32_le();
1434
1435 Ok(Self {
1436 number,
1437 state,
1438 class,
1439 message,
1440 server,
1441 procedure,
1442 line,
1443 })
1444 }
1445
1446 #[must_use]
1448 pub const fn is_fatal(&self) -> bool {
1449 self.class >= 20
1450 }
1451
1452 #[must_use]
1454 pub const fn is_batch_abort(&self) -> bool {
1455 self.class >= 16
1456 }
1457}
1458
1459impl ServerInfo {
1460 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1464 if src.remaining() < 2 {
1465 return Err(ProtocolError::UnexpectedEof);
1466 }
1467
1468 let _length = src.get_u16_le();
1469
1470 if src.remaining() < 6 {
1471 return Err(ProtocolError::UnexpectedEof);
1472 }
1473
1474 let number = src.get_i32_le();
1475 let state = src.get_u8();
1476 let class = src.get_u8();
1477
1478 let message = read_us_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1479 let server = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1480 let procedure = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1481
1482 if src.remaining() < 4 {
1483 return Err(ProtocolError::UnexpectedEof);
1484 }
1485 let line = src.get_i32_le();
1486
1487 Ok(Self {
1488 number,
1489 state,
1490 class,
1491 message,
1492 server,
1493 procedure,
1494 line,
1495 })
1496 }
1497}
1498
1499impl LoginAck {
1500 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1502 if src.remaining() < 2 {
1504 return Err(ProtocolError::UnexpectedEof);
1505 }
1506
1507 let _length = src.get_u16_le();
1508
1509 if src.remaining() < 5 {
1510 return Err(ProtocolError::UnexpectedEof);
1511 }
1512
1513 let interface = src.get_u8();
1514 let tds_version = src.get_u32_le();
1515 let prog_name = read_b_varchar(src).ok_or(ProtocolError::UnexpectedEof)?;
1516
1517 if src.remaining() < 4 {
1518 return Err(ProtocolError::UnexpectedEof);
1519 }
1520 let prog_version = src.get_u32_le();
1521
1522 Ok(Self {
1523 interface,
1524 tds_version,
1525 prog_name,
1526 prog_version,
1527 })
1528 }
1529
1530 #[must_use]
1532 pub fn tds_version(&self) -> crate::version::TdsVersion {
1533 crate::version::TdsVersion::new(self.tds_version)
1534 }
1535}
1536
1537impl EnvChangeType {
1538 pub fn from_u8(value: u8) -> Option<Self> {
1540 match value {
1541 1 => Some(Self::Database),
1542 2 => Some(Self::Language),
1543 3 => Some(Self::CharacterSet),
1544 4 => Some(Self::PacketSize),
1545 5 => Some(Self::UnicodeSortingLocalId),
1546 6 => Some(Self::UnicodeComparisonFlags),
1547 7 => Some(Self::SqlCollation),
1548 8 => Some(Self::BeginTransaction),
1549 9 => Some(Self::CommitTransaction),
1550 10 => Some(Self::RollbackTransaction),
1551 11 => Some(Self::EnlistDtcTransaction),
1552 12 => Some(Self::DefectTransaction),
1553 13 => Some(Self::RealTimeLogShipping),
1554 15 => Some(Self::PromoteTransaction),
1555 16 => Some(Self::TransactionManagerAddress),
1556 17 => Some(Self::TransactionEnded),
1557 18 => Some(Self::ResetConnectionCompletionAck),
1558 19 => Some(Self::UserInstanceStarted),
1559 20 => Some(Self::Routing),
1560 _ => None,
1561 }
1562 }
1563}
1564
1565impl EnvChange {
1566 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1568 if src.remaining() < 3 {
1569 return Err(ProtocolError::UnexpectedEof);
1570 }
1571
1572 let length = src.get_u16_le() as usize;
1573 if src.remaining() < length {
1574 return Err(ProtocolError::IncompletePacket {
1575 expected: length,
1576 actual: src.remaining(),
1577 });
1578 }
1579
1580 let env_type_byte = src.get_u8();
1581 let env_type = EnvChangeType::from_u8(env_type_byte)
1582 .ok_or(ProtocolError::InvalidTokenType(env_type_byte))?;
1583
1584 let (new_value, old_value) = match env_type {
1585 EnvChangeType::Routing => {
1586 let new_value = Self::decode_routing_value(src)?;
1588 let old_value = EnvChangeValue::Binary(Bytes::new());
1589 (new_value, old_value)
1590 }
1591 EnvChangeType::BeginTransaction
1592 | EnvChangeType::CommitTransaction
1593 | EnvChangeType::RollbackTransaction
1594 | EnvChangeType::EnlistDtcTransaction
1595 | EnvChangeType::SqlCollation => {
1596 let new_len = src.get_u8() as usize;
1600 let new_value = if new_len > 0 && src.remaining() >= new_len {
1601 EnvChangeValue::Binary(src.copy_to_bytes(new_len))
1602 } else {
1603 EnvChangeValue::Binary(Bytes::new())
1604 };
1605
1606 let old_len = src.get_u8() as usize;
1607 let old_value = if old_len > 0 && src.remaining() >= old_len {
1608 EnvChangeValue::Binary(src.copy_to_bytes(old_len))
1609 } else {
1610 EnvChangeValue::Binary(Bytes::new())
1611 };
1612
1613 (new_value, old_value)
1614 }
1615 _ => {
1616 let new_value = read_b_varchar(src)
1618 .map(EnvChangeValue::String)
1619 .unwrap_or(EnvChangeValue::String(String::new()));
1620
1621 let old_value = read_b_varchar(src)
1622 .map(EnvChangeValue::String)
1623 .unwrap_or(EnvChangeValue::String(String::new()));
1624
1625 (new_value, old_value)
1626 }
1627 };
1628
1629 Ok(Self {
1630 env_type,
1631 new_value,
1632 old_value,
1633 })
1634 }
1635
1636 fn decode_routing_value(src: &mut impl Buf) -> Result<EnvChangeValue, ProtocolError> {
1637 if src.remaining() < 2 {
1639 return Err(ProtocolError::UnexpectedEof);
1640 }
1641
1642 let _routing_len = src.get_u16_le();
1643
1644 if src.remaining() < 5 {
1645 return Err(ProtocolError::UnexpectedEof);
1646 }
1647
1648 let _protocol = src.get_u8();
1649 let port = src.get_u16_le();
1650 let server_len = src.get_u16_le() as usize;
1651
1652 if src.remaining() < server_len * 2 {
1654 return Err(ProtocolError::UnexpectedEof);
1655 }
1656
1657 let mut chars = Vec::with_capacity(server_len);
1658 for _ in 0..server_len {
1659 chars.push(src.get_u16_le());
1660 }
1661
1662 let host = String::from_utf16(&chars).map_err(|_| {
1663 ProtocolError::StringEncoding(
1664 #[cfg(feature = "std")]
1665 "invalid UTF-16 in routing hostname".to_string(),
1666 #[cfg(not(feature = "std"))]
1667 "invalid UTF-16 in routing hostname",
1668 )
1669 })?;
1670
1671 Ok(EnvChangeValue::Routing { host, port })
1672 }
1673
1674 #[must_use]
1676 pub fn is_routing(&self) -> bool {
1677 self.env_type == EnvChangeType::Routing
1678 }
1679
1680 #[must_use]
1682 pub fn routing_info(&self) -> Option<(&str, u16)> {
1683 if let EnvChangeValue::Routing { host, port } = &self.new_value {
1684 Some((host, *port))
1685 } else {
1686 None
1687 }
1688 }
1689
1690 #[must_use]
1692 pub fn new_database(&self) -> Option<&str> {
1693 if self.env_type == EnvChangeType::Database {
1694 if let EnvChangeValue::String(s) = &self.new_value {
1695 return Some(s);
1696 }
1697 }
1698 None
1699 }
1700}
1701
1702impl Order {
1703 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1705 if src.remaining() < 2 {
1706 return Err(ProtocolError::UnexpectedEof);
1707 }
1708
1709 let length = src.get_u16_le() as usize;
1710 let column_count = length / 2;
1711
1712 if src.remaining() < length {
1713 return Err(ProtocolError::IncompletePacket {
1714 expected: length,
1715 actual: src.remaining(),
1716 });
1717 }
1718
1719 let mut columns = Vec::with_capacity(column_count);
1720 for _ in 0..column_count {
1721 columns.push(src.get_u16_le());
1722 }
1723
1724 Ok(Self { columns })
1725 }
1726}
1727
1728impl FeatureExtAck {
1729 pub const TERMINATOR: u8 = 0xFF;
1731
1732 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1734 let mut features = Vec::new();
1735
1736 loop {
1737 if !src.has_remaining() {
1738 return Err(ProtocolError::UnexpectedEof);
1739 }
1740
1741 let feature_id = src.get_u8();
1742 if feature_id == Self::TERMINATOR {
1743 break;
1744 }
1745
1746 if src.remaining() < 4 {
1747 return Err(ProtocolError::UnexpectedEof);
1748 }
1749
1750 let data_len = src.get_u32_le() as usize;
1751
1752 if src.remaining() < data_len {
1753 return Err(ProtocolError::IncompletePacket {
1754 expected: data_len,
1755 actual: src.remaining(),
1756 });
1757 }
1758
1759 let data = src.copy_to_bytes(data_len);
1760 features.push(FeatureAck { feature_id, data });
1761 }
1762
1763 Ok(Self { features })
1764 }
1765}
1766
1767impl SspiToken {
1768 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1770 if src.remaining() < 2 {
1771 return Err(ProtocolError::UnexpectedEof);
1772 }
1773
1774 let length = src.get_u16_le() as usize;
1775
1776 if src.remaining() < length {
1777 return Err(ProtocolError::IncompletePacket {
1778 expected: length,
1779 actual: src.remaining(),
1780 });
1781 }
1782
1783 let data = src.copy_to_bytes(length);
1784 Ok(Self { data })
1785 }
1786}
1787
1788impl FedAuthInfo {
1789 pub fn decode(src: &mut impl Buf) -> Result<Self, ProtocolError> {
1791 if src.remaining() < 4 {
1792 return Err(ProtocolError::UnexpectedEof);
1793 }
1794
1795 let _length = src.get_u32_le();
1796
1797 if src.remaining() < 5 {
1798 return Err(ProtocolError::UnexpectedEof);
1799 }
1800
1801 let _count = src.get_u8();
1802
1803 let mut sts_url = String::new();
1805 let mut spn = String::new();
1806
1807 while src.has_remaining() {
1809 if src.remaining() < 9 {
1810 break;
1811 }
1812
1813 let info_id = src.get_u8();
1814 let info_len = src.get_u32_le() as usize;
1815 let _info_offset = src.get_u32_le();
1816
1817 if src.remaining() < info_len {
1818 break;
1819 }
1820
1821 let char_count = info_len / 2;
1823 let mut chars = Vec::with_capacity(char_count);
1824 for _ in 0..char_count {
1825 chars.push(src.get_u16_le());
1826 }
1827
1828 if let Ok(value) = String::from_utf16(&chars) {
1829 match info_id {
1830 0x01 => spn = value,
1831 0x02 => sts_url = value,
1832 _ => {}
1833 }
1834 }
1835 }
1836
1837 Ok(Self { sts_url, spn })
1838 }
1839}
1840
1841pub struct TokenParser {
1882 data: Bytes,
1883 position: usize,
1884}
1885
1886impl TokenParser {
1887 #[must_use]
1889 pub fn new(data: Bytes) -> Self {
1890 Self { data, position: 0 }
1891 }
1892
1893 #[must_use]
1895 pub fn remaining(&self) -> usize {
1896 self.data.len().saturating_sub(self.position)
1897 }
1898
1899 #[must_use]
1901 pub fn has_remaining(&self) -> bool {
1902 self.position < self.data.len()
1903 }
1904
1905 #[must_use]
1907 pub fn peek_token_type(&self) -> Option<TokenType> {
1908 if self.position < self.data.len() {
1909 TokenType::from_u8(self.data[self.position])
1910 } else {
1911 None
1912 }
1913 }
1914
1915 pub fn next_token(&mut self) -> Result<Option<Token>, ProtocolError> {
1923 self.next_token_with_metadata(None)
1924 }
1925
1926 pub fn next_token_with_metadata(
1933 &mut self,
1934 metadata: Option<&ColMetaData>,
1935 ) -> Result<Option<Token>, ProtocolError> {
1936 if !self.has_remaining() {
1937 return Ok(None);
1938 }
1939
1940 let mut buf = &self.data[self.position..];
1941 let start_pos = self.position;
1942
1943 let token_type_byte = buf.get_u8();
1944 let token_type = TokenType::from_u8(token_type_byte);
1945
1946 let token = match token_type {
1947 Some(TokenType::Done) => {
1948 let done = Done::decode(&mut buf)?;
1949 Token::Done(done)
1950 }
1951 Some(TokenType::DoneProc) => {
1952 let done = DoneProc::decode(&mut buf)?;
1953 Token::DoneProc(done)
1954 }
1955 Some(TokenType::DoneInProc) => {
1956 let done = DoneInProc::decode(&mut buf)?;
1957 Token::DoneInProc(done)
1958 }
1959 Some(TokenType::Error) => {
1960 let error = ServerError::decode(&mut buf)?;
1961 Token::Error(error)
1962 }
1963 Some(TokenType::Info) => {
1964 let info = ServerInfo::decode(&mut buf)?;
1965 Token::Info(info)
1966 }
1967 Some(TokenType::LoginAck) => {
1968 let login_ack = LoginAck::decode(&mut buf)?;
1969 Token::LoginAck(login_ack)
1970 }
1971 Some(TokenType::EnvChange) => {
1972 let env_change = EnvChange::decode(&mut buf)?;
1973 Token::EnvChange(env_change)
1974 }
1975 Some(TokenType::Order) => {
1976 let order = Order::decode(&mut buf)?;
1977 Token::Order(order)
1978 }
1979 Some(TokenType::FeatureExtAck) => {
1980 let ack = FeatureExtAck::decode(&mut buf)?;
1981 Token::FeatureExtAck(ack)
1982 }
1983 Some(TokenType::Sspi) => {
1984 let sspi = SspiToken::decode(&mut buf)?;
1985 Token::Sspi(sspi)
1986 }
1987 Some(TokenType::FedAuthInfo) => {
1988 let info = FedAuthInfo::decode(&mut buf)?;
1989 Token::FedAuthInfo(info)
1990 }
1991 Some(TokenType::ReturnStatus) => {
1992 if buf.remaining() < 4 {
1993 return Err(ProtocolError::UnexpectedEof);
1994 }
1995 let status = buf.get_i32_le();
1996 Token::ReturnStatus(status)
1997 }
1998 Some(TokenType::ColMetaData) => {
1999 let col_meta = ColMetaData::decode(&mut buf)?;
2000 Token::ColMetaData(col_meta)
2001 }
2002 Some(TokenType::Row) => {
2003 let meta = metadata.ok_or_else(|| {
2004 ProtocolError::StringEncoding(
2005 #[cfg(feature = "std")]
2006 "Row token requires column metadata".to_string(),
2007 #[cfg(not(feature = "std"))]
2008 "Row token requires column metadata",
2009 )
2010 })?;
2011 let row = RawRow::decode(&mut buf, meta)?;
2012 Token::Row(row)
2013 }
2014 Some(TokenType::NbcRow) => {
2015 let meta = metadata.ok_or_else(|| {
2016 ProtocolError::StringEncoding(
2017 #[cfg(feature = "std")]
2018 "NbcRow token requires column metadata".to_string(),
2019 #[cfg(not(feature = "std"))]
2020 "NbcRow token requires column metadata",
2021 )
2022 })?;
2023 let row = NbcRow::decode(&mut buf, meta)?;
2024 Token::NbcRow(row)
2025 }
2026 Some(TokenType::ReturnValue) => {
2027 let ret_val = ReturnValue::decode(&mut buf)?;
2028 Token::ReturnValue(ret_val)
2029 }
2030 Some(TokenType::SessionState) => {
2031 let session = SessionState::decode(&mut buf)?;
2032 Token::SessionState(session)
2033 }
2034 Some(TokenType::ColInfo) | Some(TokenType::TabName) | Some(TokenType::Offset) => {
2035 if buf.remaining() < 2 {
2038 return Err(ProtocolError::UnexpectedEof);
2039 }
2040 let length = buf.get_u16_le() as usize;
2041 if buf.remaining() < length {
2042 return Err(ProtocolError::IncompletePacket {
2043 expected: length,
2044 actual: buf.remaining(),
2045 });
2046 }
2047 buf.advance(length);
2049 self.position = start_pos + (self.data.len() - start_pos - buf.remaining());
2051 return self.next_token_with_metadata(metadata);
2052 }
2053 None => {
2054 return Err(ProtocolError::InvalidTokenType(token_type_byte));
2055 }
2056 };
2057
2058 let consumed = self.data.len() - start_pos - buf.remaining();
2060 self.position = start_pos + consumed;
2061
2062 Ok(Some(token))
2063 }
2064
2065 pub fn skip_token(&mut self) -> Result<(), ProtocolError> {
2069 if !self.has_remaining() {
2070 return Ok(());
2071 }
2072
2073 let token_type_byte = self.data[self.position];
2074 let token_type = TokenType::from_u8(token_type_byte);
2075
2076 let skip_amount = match token_type {
2078 Some(TokenType::Done) | Some(TokenType::DoneProc) | Some(TokenType::DoneInProc) => {
2080 1 + Done::SIZE }
2082 Some(TokenType::ReturnStatus) => {
2083 1 + 4 }
2085 Some(TokenType::Error)
2087 | Some(TokenType::Info)
2088 | Some(TokenType::LoginAck)
2089 | Some(TokenType::EnvChange)
2090 | Some(TokenType::Order)
2091 | Some(TokenType::Sspi)
2092 | Some(TokenType::ColInfo)
2093 | Some(TokenType::TabName)
2094 | Some(TokenType::Offset)
2095 | Some(TokenType::ReturnValue) => {
2096 if self.remaining() < 3 {
2097 return Err(ProtocolError::UnexpectedEof);
2098 }
2099 let length = u16::from_le_bytes([
2100 self.data[self.position + 1],
2101 self.data[self.position + 2],
2102 ]) as usize;
2103 1 + 2 + length }
2105 Some(TokenType::SessionState) | Some(TokenType::FedAuthInfo) => {
2107 if self.remaining() < 5 {
2108 return Err(ProtocolError::UnexpectedEof);
2109 }
2110 let length = u32::from_le_bytes([
2111 self.data[self.position + 1],
2112 self.data[self.position + 2],
2113 self.data[self.position + 3],
2114 self.data[self.position + 4],
2115 ]) as usize;
2116 1 + 4 + length
2117 }
2118 Some(TokenType::FeatureExtAck) => {
2120 let mut buf = &self.data[self.position + 1..];
2122 let _ = FeatureExtAck::decode(&mut buf)?;
2123 self.data.len() - self.position - buf.remaining()
2124 }
2125 Some(TokenType::ColMetaData) | Some(TokenType::Row) | Some(TokenType::NbcRow) => {
2127 return Err(ProtocolError::InvalidTokenType(token_type_byte));
2128 }
2129 None => {
2130 return Err(ProtocolError::InvalidTokenType(token_type_byte));
2131 }
2132 };
2133
2134 if self.remaining() < skip_amount {
2135 return Err(ProtocolError::UnexpectedEof);
2136 }
2137
2138 self.position += skip_amount;
2139 Ok(())
2140 }
2141
2142 #[must_use]
2144 pub fn position(&self) -> usize {
2145 self.position
2146 }
2147
2148 pub fn reset(&mut self) {
2150 self.position = 0;
2151 }
2152}
2153
2154#[cfg(not(feature = "std"))]
2159use alloc::string::String;
2160#[cfg(not(feature = "std"))]
2161use alloc::vec::Vec;
2162
2163#[cfg(test)]
2168#[allow(clippy::unwrap_used, clippy::panic)]
2169mod tests {
2170 use super::*;
2171 use bytes::BytesMut;
2172
2173 #[test]
2174 fn test_done_roundtrip() {
2175 let done = Done {
2176 status: DoneStatus {
2177 more: false,
2178 error: false,
2179 in_xact: false,
2180 count: true,
2181 attn: false,
2182 srverror: false,
2183 },
2184 cur_cmd: 193, row_count: 42,
2186 };
2187
2188 let mut buf = BytesMut::new();
2189 done.encode(&mut buf);
2190
2191 let mut cursor = &buf[1..];
2193 let decoded = Done::decode(&mut cursor).unwrap();
2194
2195 assert_eq!(decoded.status.count, done.status.count);
2196 assert_eq!(decoded.cur_cmd, done.cur_cmd);
2197 assert_eq!(decoded.row_count, done.row_count);
2198 }
2199
2200 #[test]
2201 fn test_done_status_bits() {
2202 let status = DoneStatus {
2203 more: true,
2204 error: true,
2205 in_xact: true,
2206 count: true,
2207 attn: false,
2208 srverror: false,
2209 };
2210
2211 let bits = status.to_bits();
2212 let restored = DoneStatus::from_bits(bits);
2213
2214 assert_eq!(status.more, restored.more);
2215 assert_eq!(status.error, restored.error);
2216 assert_eq!(status.in_xact, restored.in_xact);
2217 assert_eq!(status.count, restored.count);
2218 }
2219
2220 #[test]
2221 fn test_token_parser_done() {
2222 let data = Bytes::from_static(&[
2224 0xFD, 0x10, 0x00, 0xC1, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]);
2229
2230 let mut parser = TokenParser::new(data);
2231 let token = parser.next_token().unwrap().unwrap();
2232
2233 match token {
2234 Token::Done(done) => {
2235 assert!(done.status.count);
2236 assert!(!done.status.more);
2237 assert_eq!(done.cur_cmd, 193);
2238 assert_eq!(done.row_count, 5);
2239 }
2240 _ => panic!("Expected Done token"),
2241 }
2242
2243 assert!(parser.next_token().unwrap().is_none());
2245 }
2246
2247 #[test]
2248 fn test_env_change_type_from_u8() {
2249 assert_eq!(EnvChangeType::from_u8(1), Some(EnvChangeType::Database));
2250 assert_eq!(EnvChangeType::from_u8(20), Some(EnvChangeType::Routing));
2251 assert_eq!(EnvChangeType::from_u8(100), None);
2252 }
2253
2254 #[test]
2255 fn test_colmetadata_no_columns() {
2256 let data = Bytes::from_static(&[0xFF, 0xFF]);
2258 let mut cursor: &[u8] = &data;
2259 let meta = ColMetaData::decode(&mut cursor).unwrap();
2260 assert!(meta.is_empty());
2261 assert_eq!(meta.column_count(), 0);
2262 }
2263
2264 #[test]
2265 fn test_colmetadata_single_int_column() {
2266 let mut data = BytesMut::new();
2269 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;
2278 let meta = ColMetaData::decode(&mut cursor).unwrap();
2279
2280 assert_eq!(meta.column_count(), 1);
2281 assert_eq!(meta.columns[0].name, "id");
2282 assert_eq!(meta.columns[0].type_id, TypeId::Int4);
2283 assert!(meta.columns[0].is_nullable());
2284 }
2285
2286 #[test]
2287 fn test_colmetadata_nvarchar_column() {
2288 let mut data = BytesMut::new();
2290 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]);
2300
2301 let mut cursor: &[u8] = &data;
2302 let meta = ColMetaData::decode(&mut cursor).unwrap();
2303
2304 assert_eq!(meta.column_count(), 1);
2305 assert_eq!(meta.columns[0].name, "name");
2306 assert_eq!(meta.columns[0].type_id, TypeId::NVarChar);
2307 assert_eq!(meta.columns[0].type_info.max_length, Some(100));
2308 assert!(meta.columns[0].type_info.collation.is_some());
2309 }
2310
2311 #[test]
2312 fn test_raw_row_decode_int() {
2313 let metadata = ColMetaData {
2315 columns: vec![ColumnData {
2316 name: "id".to_string(),
2317 type_id: TypeId::Int4,
2318 col_type: 0x38,
2319 flags: 0,
2320 user_type: 0,
2321 type_info: TypeInfo::default(),
2322 }],
2323 };
2324
2325 let data = Bytes::from_static(&[0x2A, 0x00, 0x00, 0x00]); let mut cursor: &[u8] = &data;
2328 let row = RawRow::decode(&mut cursor, &metadata).unwrap();
2329
2330 assert_eq!(row.data.len(), 4);
2332 assert_eq!(&row.data[..], &[0x2A, 0x00, 0x00, 0x00]);
2333 }
2334
2335 #[test]
2336 fn test_raw_row_decode_nullable_int() {
2337 let metadata = ColMetaData {
2339 columns: vec![ColumnData {
2340 name: "id".to_string(),
2341 type_id: TypeId::IntN,
2342 col_type: 0x26,
2343 flags: 0x01, user_type: 0,
2345 type_info: TypeInfo {
2346 max_length: Some(4),
2347 ..Default::default()
2348 },
2349 }],
2350 };
2351
2352 let data = Bytes::from_static(&[0x04, 0x2A, 0x00, 0x00, 0x00]); let mut cursor: &[u8] = &data;
2355 let row = RawRow::decode(&mut cursor, &metadata).unwrap();
2356
2357 assert_eq!(row.data.len(), 5);
2358 assert_eq!(row.data[0], 4); assert_eq!(&row.data[1..], &[0x2A, 0x00, 0x00, 0x00]);
2360 }
2361
2362 #[test]
2363 fn test_raw_row_decode_null_value() {
2364 let metadata = ColMetaData {
2366 columns: vec![ColumnData {
2367 name: "id".to_string(),
2368 type_id: TypeId::IntN,
2369 col_type: 0x26,
2370 flags: 0x01, user_type: 0,
2372 type_info: TypeInfo {
2373 max_length: Some(4),
2374 ..Default::default()
2375 },
2376 }],
2377 };
2378
2379 let data = Bytes::from_static(&[0xFF]);
2381 let mut cursor: &[u8] = &data;
2382 let row = RawRow::decode(&mut cursor, &metadata).unwrap();
2383
2384 assert_eq!(row.data.len(), 1);
2385 assert_eq!(row.data[0], 0xFF); }
2387
2388 #[test]
2389 fn test_nbcrow_null_bitmap() {
2390 let row = NbcRow {
2391 null_bitmap: vec![0b00000101], data: Bytes::new(),
2393 };
2394
2395 assert!(row.is_null(0));
2396 assert!(!row.is_null(1));
2397 assert!(row.is_null(2));
2398 assert!(!row.is_null(3));
2399 }
2400
2401 #[test]
2402 fn test_token_parser_colmetadata() {
2403 let mut data = BytesMut::new();
2405 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());
2414 let token = parser.next_token().unwrap().unwrap();
2415
2416 match token {
2417 Token::ColMetaData(meta) => {
2418 assert_eq!(meta.column_count(), 1);
2419 assert_eq!(meta.columns[0].name, "id");
2420 assert_eq!(meta.columns[0].type_id, TypeId::Int4);
2421 }
2422 _ => panic!("Expected ColMetaData token"),
2423 }
2424 }
2425
2426 #[test]
2427 fn test_token_parser_row_with_metadata() {
2428 let metadata = ColMetaData {
2430 columns: vec![ColumnData {
2431 name: "id".to_string(),
2432 type_id: TypeId::Int4,
2433 col_type: 0x38,
2434 flags: 0,
2435 user_type: 0,
2436 type_info: TypeInfo::default(),
2437 }],
2438 };
2439
2440 let mut data = BytesMut::new();
2442 data.extend_from_slice(&[0xD1]); data.extend_from_slice(&[0x2A, 0x00, 0x00, 0x00]); let mut parser = TokenParser::new(data.freeze());
2446 let token = parser
2447 .next_token_with_metadata(Some(&metadata))
2448 .unwrap()
2449 .unwrap();
2450
2451 match token {
2452 Token::Row(row) => {
2453 assert_eq!(row.data.len(), 4);
2454 }
2455 _ => panic!("Expected Row token"),
2456 }
2457 }
2458
2459 #[test]
2460 fn test_token_parser_row_without_metadata_fails() {
2461 let mut data = BytesMut::new();
2463 data.extend_from_slice(&[0xD1]); data.extend_from_slice(&[0x2A, 0x00, 0x00, 0x00]); let mut parser = TokenParser::new(data.freeze());
2467 let result = parser.next_token(); assert!(result.is_err());
2470 }
2471
2472 #[test]
2473 fn test_token_parser_peek() {
2474 let data = Bytes::from_static(&[
2475 0xFD, 0x10, 0x00, 0xC1, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]);
2480
2481 let parser = TokenParser::new(data);
2482 assert_eq!(parser.peek_token_type(), Some(TokenType::Done));
2483 }
2484
2485 #[test]
2486 fn test_column_data_fixed_size() {
2487 let col = ColumnData {
2488 name: String::new(),
2489 type_id: TypeId::Int4,
2490 col_type: 0x38,
2491 flags: 0,
2492 user_type: 0,
2493 type_info: TypeInfo::default(),
2494 };
2495 assert_eq!(col.fixed_size(), Some(4));
2496
2497 let col2 = ColumnData {
2498 name: String::new(),
2499 type_id: TypeId::NVarChar,
2500 col_type: 0xE7,
2501 flags: 0,
2502 user_type: 0,
2503 type_info: TypeInfo::default(),
2504 };
2505 assert_eq!(col2.fixed_size(), None);
2506 }
2507}