parserSnapFile.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582
  1. package function
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. "os"
  7. "strconv"
  8. "strings"
  9. "github.com/sigurn/crc16"
  10. "go.uber.org/zap"
  11. )
  12. var (
  13. gCrc16Table = crc16.MakeTable(crc16.CRC16_MODBUS) // 选择 Modbus
  14. )
  15. /************** 快照文件结构体 **************/
  16. type SegmentOfCIBuffer struct {
  17. Len uint16 `json:"len"`
  18. Crc16 uint16 `json:"crc16"`
  19. TimeStamp uint32 `json:"timeStamp"`
  20. }
  21. type EquipmentSn struct {
  22. Len int32 `json:"len"`
  23. Data string `json:"data"`
  24. }
  25. type HwfAlarmDataItem struct {
  26. AlarmCode uint16 `json:"alarmCode"` //故障编码
  27. Level uint8 `json:"level"` //故障等级
  28. NeedSave uint8 `json:"needSave"` //该故障是否需要保存
  29. TimeStart uint32 `json:"timeStart"` //该故障的开始时间
  30. }
  31. type AlarmList struct {
  32. Count int32 `json:"count"`
  33. DataItem []HwfAlarmDataItem `json:"dataItem"`
  34. }
  35. type SnapXid struct {
  36. IdType uint8 `json:"idType"` // PID : 1, VID : 0
  37. DataType uint8 `json:"dataType"` // 0-UINT32 1-INT32 2-FLOAT 3-PCHAR
  38. ID uint16 `json:"id"` // 在PID和VID配置表中对应的id, 可基于此找到对应的PID/VID
  39. }
  40. type XidDataType interface {
  41. uint32 | int32 | float32 | string
  42. }
  43. type XidSegmentHeader struct {
  44. Xid SnapXid `json:"xid"`
  45. Len int32 `json:"len"` // DATA 的长度
  46. }
  47. type XidSegment[T XidDataType] struct {
  48. Header XidSegmentHeader `json:"header"`
  49. Data T `json:"data"` // DATA 取决于 SnapXid.DataType
  50. }
  51. type XidSegmentType interface {
  52. XidSegment[uint32] | XidSegment[int32] | XidSegment[float32] | XidSegment[string]
  53. }
  54. type XidSegmentIf interface {
  55. GetXid() any
  56. CreateXid(v any) error
  57. }
  58. func (x *XidSegment[T]) GetXid() any {
  59. return x
  60. }
  61. func (x *XidSegment[T]) CreateXid(v any) error {
  62. val, ok := v.(XidSegment[T])
  63. if !ok {
  64. return fmt.Errorf("invalid type: expected %T", x.Data)
  65. }
  66. *x = val
  67. return nil
  68. }
  69. type InfoSegmentPackage struct {
  70. Header SegmentOfCIBuffer `json:"header"`
  71. HeadStr [4]byte `json:"headerStr"` // "HEAD"
  72. GateSn EquipmentSn `json:"aGateSn"`
  73. PowerSn EquipmentSn `json:"aPowerSn"`
  74. Alarm AlarmList `json:"alarm"`
  75. }
  76. type XidSegmentPackage struct {
  77. Header SegmentOfCIBuffer `json:"header"`
  78. XidList []XidSegmentIf `json:"xidList"`
  79. }
  80. type SnapFilePackage struct {
  81. Info InfoSegmentPackage `json:"info"`
  82. Xid XidSegmentPackage `json:"xid"`
  83. }
  84. /************** 快照JSON数据结构体 **************/
  85. type AlarmCodeInfo struct {
  86. AlarmCode uint16 `json:"alarmCode"` //故障编码
  87. Level uint8 `json:"level"` //故障等级
  88. TimeStart uint32 `json:"timeStart"` //该故障的开始时间
  89. }
  90. type AlarmInfoJson struct {
  91. Total int32 `json:"total"`
  92. AlarmList []AlarmCodeInfo `json:"alarmList"`
  93. }
  94. type XID[T XidDataType] struct {
  95. ID uint16 `json:"id"`
  96. Type string `json:"type"` // "PID" or "VID"
  97. // Macro string `json:"macro"` // 代码中的宏名称
  98. // Brief string `json:"brief"` // 简介
  99. Data T `json:"data"`
  100. }
  101. type XidIf interface {
  102. GetXid() any
  103. CreateXid(v any) error
  104. }
  105. func (x *XID[T]) GetXid() any {
  106. return x
  107. }
  108. func (x *XID[T]) CreateXid(v any) error {
  109. val, ok := v.(XID[T])
  110. if !ok {
  111. return fmt.Errorf("invalid type: expected %T", x.Data)
  112. }
  113. *x = val
  114. return nil
  115. }
  116. type SnapInfoJson struct {
  117. XidList []XidIf `json:"xidList"`
  118. }
  119. type SnapJson struct {
  120. TimeStamp uint32 `json:"timeStamp"`
  121. SiteSn string `json:"aGateSn"`
  122. PowerSn []string `json:"aPowerSn"`
  123. AlarmInfo AlarmInfoJson `json:"alarmInfo"`
  124. SnapInfo SnapInfoJson `json:"snapInfo"`
  125. }
  126. /************** 解析数据结构体 **************/
  127. type ParserAlarmSnapshot struct {
  128. FilePath string `json:"filePath"`
  129. FilePackage []SnapFilePackage `json:"filePackage"`
  130. SnapJson []SnapJson `json:"snapJson"`
  131. }
  132. type SegmentDataType struct {
  133. Header SegmentOfCIBuffer
  134. Data []byte
  135. }
  136. type SegmentType struct {
  137. InfoSegment SegmentDataType
  138. XidSegment SegmentDataType
  139. BinData []byte
  140. }
  141. // 创建ParserAlarmSnapshot结果体必须使用函数NewParserAlarmSnapshot
  142. func NewParserAlarmSnapshot(filePath string) *ParserAlarmSnapshot {
  143. return &ParserAlarmSnapshot{
  144. FilePath: filePath,
  145. }
  146. }
  147. func (parser *ParserAlarmSnapshot) ParserSnapFile() error {
  148. binData, err := os.ReadFile(parser.FilePath)
  149. if err != nil {
  150. zap.L().Error("snap文件读取失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  151. return err
  152. }
  153. var newBinData []byte
  154. // 寻找第一个有效 "HEAD" 的位置,生成新的连续数据段
  155. pRemainingData := binData
  156. startIdx := int(0)
  157. for {
  158. idx := bytes.Index(pRemainingData, []byte("HEAD"))
  159. if idx == -1 {
  160. fmt.Println("未找到 HEAD 结束")
  161. break
  162. } else if idx < 8 {
  163. // 数据开头不完整,跳到下一个数据
  164. pRemainingData = pRemainingData[idx+4:]
  165. startIdx = startIdx + idx + 4
  166. continue
  167. }
  168. // 计算前8个字节的开始位置
  169. start := idx - 8
  170. startIdx = startIdx + start
  171. // 检查有效性
  172. _, err := parser.checkSnapData(pRemainingData[start:])
  173. if err != nil {
  174. fmt.Println("第一个数据段无效")
  175. continue
  176. }
  177. pHeaderData := binData[:startIdx]
  178. pRemainingData = pRemainingData[start:]
  179. // 重新拼接循环数据
  180. newBinData = make([]byte, len(binData))
  181. copy(newBinData, pRemainingData)
  182. copy(newBinData[len(pRemainingData):], pHeaderData)
  183. break
  184. }
  185. // 声明一个切片,用来存放多个 Segment
  186. var segmentList []*SegmentType
  187. pNewBinData := newBinData
  188. pBinIdx := startIdx
  189. // 生成数据段列表
  190. for {
  191. // 检查 HEAD 头
  192. if !bytes.Equal(pNewBinData[8:8+4], []byte("HEAD")) {
  193. // 往下寻找新的 HEAD 头
  194. idx := bytes.Index(pNewBinData, []byte("HEAD"))
  195. if idx == -1 {
  196. fmt.Println("未找到 HEAD 结束")
  197. break
  198. } else if idx < 8 {
  199. // 数据开头不完整,跳到下一个数据
  200. pNewBinData = pNewBinData[idx+4:]
  201. pBinIdx = pBinIdx + idx + 4
  202. continue
  203. }
  204. pNewBinData = pNewBinData[idx-8:]
  205. pBinIdx = pBinIdx + idx - 8
  206. }
  207. // 检查有效性
  208. segData, err := parser.checkSnapData(pNewBinData)
  209. if err != nil {
  210. fmt.Printf("数据段格式错误 index: %d\n", pBinIdx)
  211. // 数据开头不完整,跳到下一个数据
  212. pNewBinData = pNewBinData[8+4:]
  213. pBinIdx = pBinIdx + 8 + 4
  214. continue
  215. }
  216. segmentList = append(segmentList, segData)
  217. pNewBinData = pNewBinData[len(segData.BinData):]
  218. pBinIdx = pBinIdx + len(segData.BinData)
  219. if len(pNewBinData) == 0 {
  220. // 数据刚好处理完,无剩余无效数据
  221. break
  222. }
  223. }
  224. // 处理每个数据段
  225. for _, pData := range segmentList {
  226. var filePackage SnapFilePackage
  227. var snapJson SnapJson
  228. if err := parser.parserInfoSegment(&filePackage, &snapJson, pData.InfoSegment); err != nil {
  229. return err
  230. }
  231. if err := parser.parserXidSegment(&filePackage, &snapJson, pData.XidSegment); err != nil {
  232. return err
  233. }
  234. parser.FilePackage = append(parser.FilePackage, filePackage)
  235. parser.SnapJson = append(parser.SnapJson, snapJson)
  236. }
  237. return nil
  238. }
  239. // 检验数据的正确性和完整性
  240. // 1、校验两段SegmentOfCIBuffer的CRC
  241. // 2、同时检查数据长度是否完整
  242. func (parser *ParserAlarmSnapshot) checkSnapData(binData []byte) (*SegmentType, error) {
  243. // 处理数据段一
  244. var infoHeader SegmentOfCIBuffer
  245. headerSize := binary.Size(infoHeader)
  246. if len(binData) < headerSize {
  247. zap.L().Error("snap文件长度异常", zap.String("FilePath", parser.FilePath))
  248. return nil, fmt.Errorf("snap文件长度异常")
  249. }
  250. headerRaw := binData[:headerSize] // 头部数据
  251. headerReader := bytes.NewReader(headerRaw)
  252. if err := binary.Read(headerReader, binary.LittleEndian, &infoHeader); err != nil {
  253. zap.L().Error("snap文件读取转换失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  254. return nil, err
  255. }
  256. // 获取数据长度
  257. infoBufferLen := int(infoHeader.Len)
  258. if len(binData[headerSize:]) < infoBufferLen {
  259. zap.L().Error("snap文件长度异常", zap.String("FilePath", parser.FilePath))
  260. return nil, fmt.Errorf("snap文件长度异常")
  261. }
  262. // Info Buffer
  263. pInfoBufferRaw := binData[headerSize:]
  264. pInfoBufferRaw = pInfoBufferRaw[:infoBufferLen]
  265. // 校验CRC
  266. bufferCrc := infoHeader.Crc16
  267. calcCrc := crc16.Checksum(pInfoBufferRaw, gCrc16Table)
  268. if bufferCrc != calcCrc {
  269. zap.L().Error("snap文件CRC校验失败", zap.String("FilePath", parser.FilePath))
  270. return nil, fmt.Errorf("snap文件CRC校验失败")
  271. }
  272. pInfoBufferRaw = pInfoBufferRaw[4:] // 排除 “HEAD” 头
  273. // 处理数据段二
  274. var xidHeader SegmentOfCIBuffer
  275. headerSize = binary.Size(xidHeader)
  276. secBinData := binData[headerSize+infoBufferLen:]
  277. if len(secBinData) < headerSize {
  278. zap.L().Error("snap文件长度异常", zap.String("FilePath", parser.FilePath))
  279. return nil, fmt.Errorf("snap文件长度异常")
  280. }
  281. headerRaw = secBinData[:headerSize] // 头部数据
  282. headerReader = bytes.NewReader(headerRaw)
  283. if err := binary.Read(headerReader, binary.LittleEndian, &xidHeader); err != nil {
  284. zap.L().Error("snap文件读取转换失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  285. return nil, err
  286. }
  287. // 获取数据长度
  288. xidBufferLen := int(xidHeader.Len)
  289. if len(secBinData[headerSize:]) < xidBufferLen {
  290. zap.L().Error("snap文件长度异常", zap.String("FilePath", parser.FilePath))
  291. return nil, fmt.Errorf("snap文件长度异常")
  292. }
  293. // Xid Buffer
  294. pXidBufferRaw := secBinData[headerSize:]
  295. pXidBufferRaw = pXidBufferRaw[:xidBufferLen]
  296. // 校验CRC
  297. bufferCrc = xidHeader.Crc16
  298. calcCrc = crc16.Checksum(pXidBufferRaw, gCrc16Table)
  299. if bufferCrc != calcCrc {
  300. zap.L().Error("snap文件CRC校验失败", zap.String("FilePath", parser.FilePath))
  301. return nil, fmt.Errorf("snap文件CRC校验失败")
  302. }
  303. // 计算数据总长度
  304. dataLen := headerSize + infoBufferLen + headerSize + xidBufferLen
  305. return &SegmentType{
  306. InfoSegment: SegmentDataType{
  307. Header: infoHeader,
  308. Data: pInfoBufferRaw,
  309. },
  310. XidSegment: SegmentDataType{
  311. Header: xidHeader,
  312. Data: pXidBufferRaw,
  313. },
  314. BinData: binData[:dataLen],
  315. }, nil
  316. }
  317. func (parser *ParserAlarmSnapshot) parserInfoSegment(pkg *SnapFilePackage, snapJson *SnapJson, segData SegmentDataType) error {
  318. header := segData.Header
  319. pkg.Info.Header = header
  320. // 填充JSON数据
  321. snapJson.TimeStamp = header.TimeStamp
  322. pInfoBufferRaw := segData.Data // Info Buffer
  323. // 写入数据头标签 HEAD
  324. copy(pkg.Info.HeadStr[:], "HEAD")
  325. equipmentSnLenReader := bytes.NewReader(pInfoBufferRaw[:binary.Size(pkg.Info.GateSn.Len)])
  326. if err := binary.Read(equipmentSnLenReader, binary.LittleEndian, &pkg.Info.GateSn.Len); err != nil {
  327. zap.L().Error("snap文件读取设备aGate SN长度失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  328. return err
  329. }
  330. if pkg.Info.GateSn.Len < 0 {
  331. zap.L().Error("snap文件读取设备aGate SN长度小于0", zap.String("len", strconv.Itoa(int(pkg.Info.GateSn.Len))), zap.String("FilePath", parser.FilePath))
  332. return fmt.Errorf("snap文件读取设备aGate SN长度小于0")
  333. }
  334. pInfoBufferRaw = pInfoBufferRaw[binary.Size(pkg.Info.GateSn.Len):]
  335. // 提取aGate SN
  336. equipmentSnDataRaw := pInfoBufferRaw[:pkg.Info.GateSn.Len]
  337. pkg.Info.GateSn.Data = string(equipmentSnDataRaw)
  338. snapJson.SiteSn = string(equipmentSnDataRaw)
  339. pInfoBufferRaw = pInfoBufferRaw[pkg.Info.GateSn.Len:]
  340. equipmentSnLenReader = bytes.NewReader(pInfoBufferRaw[:binary.Size(pkg.Info.PowerSn.Len)])
  341. if err := binary.Read(equipmentSnLenReader, binary.LittleEndian, &pkg.Info.PowerSn.Len); err != nil {
  342. zap.L().Error("snap文件读取设备aPower SN长度失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  343. return err
  344. }
  345. if pkg.Info.PowerSn.Len < 0 {
  346. zap.L().Error("snap文件读取设备aPower SN长度小于0", zap.String("len", strconv.Itoa(int(pkg.Info.PowerSn.Len))), zap.String("FilePath", parser.FilePath))
  347. return fmt.Errorf("snap文件读取设备aPower SN长度小于0")
  348. }
  349. pInfoBufferRaw = pInfoBufferRaw[binary.Size(pkg.Info.PowerSn.Len):]
  350. // 提取aPower SN
  351. equipmentSnDataRaw = pInfoBufferRaw[:pkg.Info.PowerSn.Len]
  352. pkg.Info.PowerSn.Data = string(equipmentSnDataRaw)
  353. snapJson.PowerSn = strings.Split(string(equipmentSnDataRaw), ",")
  354. pInfoBufferRaw = pInfoBufferRaw[pkg.Info.PowerSn.Len:]
  355. alarmCountReader := bytes.NewReader(pInfoBufferRaw[:binary.Size(pkg.Info.Alarm.Count)])
  356. if err := binary.Read(alarmCountReader, binary.LittleEndian, &pkg.Info.Alarm.Count); err != nil {
  357. zap.L().Error("snap文件读取告警数量失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  358. return err
  359. }
  360. snapJson.AlarmInfo.Total = pkg.Info.Alarm.Count
  361. pInfoBufferRaw = pInfoBufferRaw[binary.Size(pkg.Info.Alarm.Count):]
  362. for i := 0; i < int(pkg.Info.Alarm.Count); i++ {
  363. var alarmDataItem HwfAlarmDataItem
  364. alarmDataItemReader := bytes.NewBuffer(pInfoBufferRaw[:binary.Size(alarmDataItem)])
  365. if err := binary.Read(alarmDataItemReader, binary.LittleEndian, &alarmDataItem); err != nil {
  366. zap.L().Error("snap文件读取告警项失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  367. return err
  368. }
  369. pkg.Info.Alarm.DataItem = append(pkg.Info.Alarm.DataItem, alarmDataItem)
  370. snapJson.AlarmInfo.AlarmList = append(snapJson.AlarmInfo.AlarmList, AlarmCodeInfo{
  371. AlarmCode: alarmDataItem.AlarmCode,
  372. Level: alarmDataItem.Level,
  373. TimeStart: alarmDataItem.TimeStart,
  374. })
  375. pInfoBufferRaw = pInfoBufferRaw[binary.Size(alarmDataItem):]
  376. }
  377. return nil
  378. }
  379. func (parser *ParserAlarmSnapshot) parserXidSegment(pkg *SnapFilePackage, snapJson *SnapJson, segData SegmentDataType) error {
  380. header := segData.Header
  381. pkg.Xid.Header = header
  382. pXidBufferRaw := segData.Data // Xid Buffer
  383. for len(pXidBufferRaw) > 0 {
  384. var xidHeader XidSegmentHeader
  385. snapXidHeaderReader := bytes.NewReader(pXidBufferRaw[:binary.Size(xidHeader)])
  386. if err := binary.Read(snapXidHeaderReader, binary.LittleEndian, &xidHeader); err != nil {
  387. zap.L().Error("snap文件读取XID数据头失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  388. return err
  389. }
  390. pXidBufferRaw = pXidBufferRaw[binary.Size(xidHeader):]
  391. var IdTypeStr string
  392. switch xidHeader.Xid.IdType {
  393. case 0:
  394. IdTypeStr = "VID"
  395. case 1:
  396. IdTypeStr = "PID"
  397. default:
  398. zap.L().Error("snap文件读取XID数据ID类型错误", zap.String("id_type", strconv.Itoa(int(xidHeader.Xid.IdType))), zap.String("FilePath", parser.FilePath))
  399. return fmt.Errorf("snap文件读取XID数据ID类型错误")
  400. }
  401. switch xidHeader.Xid.DataType {
  402. case 0:
  403. var xid XidSegment[uint32]
  404. xid.Header = xidHeader
  405. var data uint32
  406. if xidHeader.Len != int32(binary.Size(data)) {
  407. zap.L().Error("snap文件读取XID数据长度错误", zap.String("type", strconv.Itoa(int(xidHeader.Xid.DataType))), zap.String("len", strconv.Itoa(int(xidHeader.Len))), zap.String("FilePath", parser.FilePath))
  408. return fmt.Errorf("snap文件读取XID数据长度错误")
  409. }
  410. dataReader := bytes.NewReader(pXidBufferRaw[:binary.Size(data)])
  411. if err := binary.Read(dataReader, binary.LittleEndian, &data); err != nil {
  412. zap.L().Error("snap文件读取XID数据失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  413. return err
  414. }
  415. xid.Data = data
  416. pkg.Xid.XidList = append(pkg.Xid.XidList, &xid)
  417. // 赋值到JSON数据
  418. snapJson.SnapInfo.XidList = append(snapJson.SnapInfo.XidList, &XID[uint32]{
  419. ID: xidHeader.Xid.ID,
  420. Type: IdTypeStr,
  421. Data: data,
  422. })
  423. case 1:
  424. var xid XidSegment[int32]
  425. xid.Header = xidHeader
  426. var data int32
  427. if xidHeader.Len != int32(binary.Size(data)) {
  428. zap.L().Error("snap文件读取XID数据长度错误", zap.String("type", strconv.Itoa(int(xidHeader.Xid.DataType))), zap.String("len", strconv.Itoa(int(xidHeader.Len))), zap.String("FilePath", parser.FilePath))
  429. return fmt.Errorf("snap文件读取XID数据长度错误")
  430. }
  431. dataReader := bytes.NewReader(pXidBufferRaw[:binary.Size(data)])
  432. if err := binary.Read(dataReader, binary.LittleEndian, &data); err != nil {
  433. zap.L().Error("snap文件读取XID数据失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  434. return err
  435. }
  436. xid.Data = data
  437. pkg.Xid.XidList = append(pkg.Xid.XidList, &xid)
  438. // 赋值到JSON数据
  439. snapJson.SnapInfo.XidList = append(snapJson.SnapInfo.XidList, &XID[int32]{
  440. ID: xidHeader.Xid.ID,
  441. Type: IdTypeStr,
  442. Data: data,
  443. })
  444. case 2:
  445. var xid XidSegment[float32]
  446. xid.Header = xidHeader
  447. var data float32
  448. if xidHeader.Len != int32(binary.Size(data)) {
  449. zap.L().Error("snap文件读取XID数据长度错误", zap.String("type", strconv.Itoa(int(xidHeader.Xid.DataType))), zap.String("len", strconv.Itoa(int(xidHeader.Len))), zap.String("FilePath", parser.FilePath))
  450. return fmt.Errorf("snap文件读取XID数据长度错误")
  451. }
  452. dataReader := bytes.NewReader(pXidBufferRaw[:binary.Size(data)])
  453. if err := binary.Read(dataReader, binary.LittleEndian, &data); err != nil {
  454. zap.L().Error("snap文件读取XID数据失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  455. return err
  456. }
  457. xid.Data = data
  458. pkg.Xid.XidList = append(pkg.Xid.XidList, &xid)
  459. // 赋值到JSON数据
  460. snapJson.SnapInfo.XidList = append(snapJson.SnapInfo.XidList, &XID[float32]{
  461. ID: xidHeader.Xid.ID,
  462. Type: IdTypeStr,
  463. Data: data,
  464. })
  465. case 3:
  466. var xid XidSegment[string]
  467. xid.Header = xidHeader
  468. strBytes := make([]byte, xidHeader.Len)
  469. dataReader := bytes.NewReader(pXidBufferRaw[:xidHeader.Len])
  470. if err := binary.Read(dataReader, binary.LittleEndian, &strBytes); err != nil {
  471. zap.L().Error("snap文件读取XID数据失败", zap.String("err", err.Error()), zap.String("FilePath", parser.FilePath))
  472. return err
  473. }
  474. xid.Data = string(strBytes)
  475. pkg.Xid.XidList = append(pkg.Xid.XidList, &xid)
  476. // 赋值到JSON数据
  477. snapJson.SnapInfo.XidList = append(snapJson.SnapInfo.XidList, &XID[string]{
  478. ID: xidHeader.Xid.ID,
  479. Type: IdTypeStr,
  480. Data: xid.Data,
  481. })
  482. default:
  483. zap.L().Error("snap文件读取XID类型错误", zap.String("type", strconv.Itoa(int(xidHeader.Xid.DataType))), zap.String("FilePath", parser.FilePath))
  484. return fmt.Errorf("snap文件读取XID类型错误")
  485. }
  486. pXidBufferRaw = pXidBufferRaw[xidHeader.Len:]
  487. }
  488. return nil
  489. }