@@ -1068,6 +1068,160 @@ impl Record {
10681068 }
10691069 }
10701070
1071+ /// Update or add auxiliary data.
1072+ pub fn update_aux ( & mut self , tag : & [ u8 ] , value : Aux < ' _ > ) -> Result < ( ) > {
1073+ // Update existing aux data for the given tag if already present in the record
1074+ // without changing the ordering of tags in the record or append aux data at
1075+ // the end of the existing aux records if it is a new tag.
1076+
1077+ let ctag = tag. as_ptr ( ) as * mut c_char ;
1078+ let ret = unsafe {
1079+ match value {
1080+ Aux :: Char ( v) => return Err ( Error :: BamAuxTagUpdatingNotSupported ) ,
1081+ Aux :: I8 ( v) => htslib:: bam_aux_update_int ( self . inner_ptr_mut ( ) , ctag, v as i64 ) ,
1082+ Aux :: U8 ( v) => htslib:: bam_aux_update_int ( self . inner_ptr_mut ( ) , ctag, v as i64 ) ,
1083+ Aux :: I16 ( v) => htslib:: bam_aux_update_int ( self . inner_ptr_mut ( ) , ctag, v as i64 ) ,
1084+ Aux :: U16 ( v) => htslib:: bam_aux_update_int ( self . inner_ptr_mut ( ) , ctag, v as i64 ) ,
1085+ Aux :: I32 ( v) => htslib:: bam_aux_update_int ( self . inner_ptr_mut ( ) , ctag, v as i64 ) ,
1086+ Aux :: U32 ( v) => htslib:: bam_aux_update_int ( self . inner_ptr_mut ( ) , ctag, v as i64 ) ,
1087+ Aux :: Float ( v) => htslib:: bam_aux_update_float ( self . inner_ptr_mut ( ) , ctag, v) ,
1088+ // Not part of specs but implemented in `htslib`:
1089+ Aux :: Double ( v) => {
1090+ htslib:: bam_aux_update_float ( self . inner_ptr_mut ( ) , ctag, v as f32 )
1091+ }
1092+ Aux :: String ( v) => {
1093+ let c_str = ffi:: CString :: new ( v) . map_err ( |_| Error :: BamAuxStringError ) ?;
1094+ htslib:: bam_aux_update_str (
1095+ self . inner_ptr_mut ( ) ,
1096+ ctag,
1097+ ( v. len ( ) + 1 ) as i32 ,
1098+ c_str. as_ptr ( ) as * const c_char ,
1099+ )
1100+ }
1101+ Aux :: HexByteArray ( v) => return Err ( Error :: BamAuxTagUpdatingNotSupported ) ,
1102+ // Not sure it's safe to cast an immutable slice to a mutable pointer in the following branches
1103+ Aux :: ArrayI8 ( aux_array) => match aux_array {
1104+ AuxArray :: TargetType ( inner) => htslib:: bam_aux_update_array (
1105+ self . inner_ptr_mut ( ) ,
1106+ ctag,
1107+ b'c' ,
1108+ inner. len ( ) as u32 ,
1109+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1110+ ) ,
1111+ AuxArray :: RawLeBytes ( inner) => htslib:: bam_aux_update_array (
1112+ self . inner_ptr_mut ( ) ,
1113+ ctag,
1114+ b'c' ,
1115+ inner. len ( ) as u32 ,
1116+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1117+ ) ,
1118+ } ,
1119+ Aux :: ArrayU8 ( aux_array) => match aux_array {
1120+ AuxArray :: TargetType ( inner) => htslib:: bam_aux_update_array (
1121+ self . inner_ptr_mut ( ) ,
1122+ ctag,
1123+ b'C' ,
1124+ inner. len ( ) as u32 ,
1125+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1126+ ) ,
1127+ AuxArray :: RawLeBytes ( inner) => htslib:: bam_aux_update_array (
1128+ self . inner_ptr_mut ( ) ,
1129+ ctag,
1130+ b'C' ,
1131+ inner. len ( ) as u32 ,
1132+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1133+ ) ,
1134+ } ,
1135+ Aux :: ArrayI16 ( aux_array) => match aux_array {
1136+ AuxArray :: TargetType ( inner) => htslib:: bam_aux_update_array (
1137+ self . inner_ptr_mut ( ) ,
1138+ ctag,
1139+ b's' ,
1140+ inner. len ( ) as u32 ,
1141+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1142+ ) ,
1143+ AuxArray :: RawLeBytes ( inner) => htslib:: bam_aux_update_array (
1144+ self . inner_ptr_mut ( ) ,
1145+ ctag,
1146+ b's' ,
1147+ inner. len ( ) as u32 ,
1148+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1149+ ) ,
1150+ } ,
1151+ Aux :: ArrayU16 ( aux_array) => match aux_array {
1152+ AuxArray :: TargetType ( inner) => htslib:: bam_aux_update_array (
1153+ self . inner_ptr_mut ( ) ,
1154+ ctag,
1155+ b'S' ,
1156+ inner. len ( ) as u32 ,
1157+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1158+ ) ,
1159+ AuxArray :: RawLeBytes ( inner) => htslib:: bam_aux_update_array (
1160+ self . inner_ptr_mut ( ) ,
1161+ ctag,
1162+ b'S' ,
1163+ inner. len ( ) as u32 ,
1164+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1165+ ) ,
1166+ } ,
1167+ Aux :: ArrayI32 ( aux_array) => match aux_array {
1168+ AuxArray :: TargetType ( inner) => htslib:: bam_aux_update_array (
1169+ self . inner_ptr_mut ( ) ,
1170+ ctag,
1171+ b'i' ,
1172+ inner. len ( ) as u32 ,
1173+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1174+ ) ,
1175+ AuxArray :: RawLeBytes ( inner) => htslib:: bam_aux_update_array (
1176+ self . inner_ptr_mut ( ) ,
1177+ ctag,
1178+ b'i' ,
1179+ inner. len ( ) as u32 ,
1180+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1181+ ) ,
1182+ } ,
1183+ Aux :: ArrayU32 ( aux_array) => match aux_array {
1184+ AuxArray :: TargetType ( inner) => htslib:: bam_aux_update_array (
1185+ self . inner_ptr_mut ( ) ,
1186+ ctag,
1187+ b'I' ,
1188+ inner. len ( ) as u32 ,
1189+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1190+ ) ,
1191+ AuxArray :: RawLeBytes ( inner) => htslib:: bam_aux_update_array (
1192+ self . inner_ptr_mut ( ) ,
1193+ ctag,
1194+ b'I' ,
1195+ inner. len ( ) as u32 ,
1196+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1197+ ) ,
1198+ } ,
1199+ Aux :: ArrayFloat ( aux_array) => match aux_array {
1200+ AuxArray :: TargetType ( inner) => htslib:: bam_aux_update_array (
1201+ self . inner_ptr_mut ( ) ,
1202+ ctag,
1203+ b'f' ,
1204+ inner. len ( ) as u32 ,
1205+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1206+ ) ,
1207+ AuxArray :: RawLeBytes ( inner) => htslib:: bam_aux_update_array (
1208+ self . inner_ptr_mut ( ) ,
1209+ ctag,
1210+ b'f' ,
1211+ inner. len ( ) as u32 ,
1212+ inner. slice . as_ptr ( ) as * mut :: libc:: c_void ,
1213+ ) ,
1214+ } ,
1215+ }
1216+ } ;
1217+
1218+ if ret < 0 {
1219+ Err ( Error :: BamAux )
1220+ } else {
1221+ Ok ( ( ) )
1222+ }
1223+ }
1224+
10711225 // Delete auxiliary tag.
10721226 pub fn remove_aux ( & mut self , tag : & [ u8 ] ) -> Result < ( ) > {
10731227 let c_str = ffi:: CString :: new ( tag) . map_err ( |_| Error :: BamAuxStringError ) ?;
0 commit comments