parserSnapFile.go 19 KB

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