From 7a7d377af69af22599879a4ad2d446beff1d92c4 Mon Sep 17 00:00:00 2001 From: Vaibhav Kaushal Date: Wed, 26 Mar 2025 18:50:03 +0530 Subject: [PATCH 1/2] updated error messages and removed dependency on library for tests --- .idea/.gitignore | 8 ++++++ .idea/atc2json.iml | 9 +++++++ .idea/modules.xml | 8 ++++++ .idea/vcs.xml | 6 +++++ atc2json/atc2json.go | 57 +++++++++++++++++++++++---------------- atc2json/atc2json_test.go | 21 ++++++++++++--- go.mod | 3 +++ main.go | 6 ++--- 8 files changed, 88 insertions(+), 30 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/atc2json.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 go.mod diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/atc2json.iml b/.idea/atc2json.iml new file mode 100644 index 0000000..5e764c4 --- /dev/null +++ b/.idea/atc2json.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..db3fdaa --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/atc2json/atc2json.go b/atc2json/atc2json.go index 37905ad..eae250f 100644 --- a/atc2json/atc2json.go +++ b/atc2json/atc2json.go @@ -66,10 +66,13 @@ func Parse(atcData []byte) (*EcgData, error) { reader := bytes.NewReader(atcData) header := AtcFileHeader{} - binary.Read(reader, binary.LittleEndian, &header) + err := binary.Read(reader, binary.LittleEndian, &header) + if err != nil { + return nil, fmt.Errorf("E#2D4V51: Failed to read data. Error: %v\n", err) + } if header.FileSignature != AtcFileSignature { - return nil, fmt.Errorf("Wrong file signature") + return nil, fmt.Errorf("E#2D4V67: Wrong file signature") } blockHeader := BlockHeader{} @@ -92,7 +95,7 @@ func Parse(atcData []byte) (*EcgData, error) { if err == io.EOF { break } - return nil, fmt.Errorf("Error reading file: %s", err.Error()) + return nil, fmt.Errorf("E#2D4V6H: Error reading file: %s", err.Error()) } blockType := string(blockHeader.BlockId[:]) @@ -103,22 +106,22 @@ func Parse(atcData []byte) (*EcgData, error) { fmtBlock = &FmtBlock{} err = binary.Read(reader, binary.LittleEndian, fmtBlock) if err != nil { - return nil, fmt.Errorf("Error reading buffer: %s", err.Error()) + return nil, fmt.Errorf("E#2D4V6P: Error reading buffer: %s", err.Error()) } err = verifyChecksum(atcData, blockStart, blockHeader.Length, reader) if err != nil { - return nil, err + return nil, fmt.Errorf("E#2D4V75: Checksum verification failed for 'fmt' block. Error: %v\n", err) } case "info": infoBlock = &InfoBlock{} err = binary.Read(reader, binary.LittleEndian, infoBlock) if err != nil { - return nil, fmt.Errorf("Error reading buffer: %s", err.Error()) + return nil, fmt.Errorf("E#2D4V6P: Error reading buffer: %s", err.Error()) } err = verifyChecksum(atcData, blockStart, blockHeader.Length, reader) if err != nil { - return nil, err + return nil, fmt.Errorf("E#2D4VHM: Checksum verification failed for 'info' block. Error: %v\n", err) } // Space after word is intended, per spec - cp 2019-2-19 @@ -126,84 +129,89 @@ func Parse(atcData []byte) (*EcgData, error) { leadISamples = make([]int16, blockHeader.Length/2) err = binary.Read(reader, binary.LittleEndian, &leadISamples) if err != nil { - return nil, fmt.Errorf("Error reading buffer: %s", err.Error()) + return nil, fmt.Errorf("E#2D4V6P: Error reading buffer: %s", err.Error()) } err = verifyChecksum(atcData, blockStart, blockHeader.Length, reader) if err != nil { - return nil, err + return nil, fmt.Errorf("E#2D4VHZ: Checksum verification failed for 'ecg' block. Error: %v\n", err) } case "ecg2": leadIISamples = make([]int16, blockHeader.Length/2) err = binary.Read(reader, binary.LittleEndian, &leadIISamples) if err != nil { - return nil, fmt.Errorf("Error reading buffer: %s", err.Error()) + return nil, fmt.Errorf("E#2D4VFZ: Error reading buffer: %s", err.Error()) } err = verifyChecksum(atcData, blockStart, blockHeader.Length, reader) if err != nil { - return nil, err + return nil, fmt.Errorf("E#2D4VIN: Checksum verification failed for 'ecg2' block. Error: %v\n", err) } case "ecg3": leadIIISamples = make([]int16, blockHeader.Length/2) err = binary.Read(reader, binary.LittleEndian, &leadIIISamples) if err != nil { - return nil, fmt.Errorf("Error reading buffer: %s", err.Error()) + return nil, fmt.Errorf("E#2D4VFP: Error reading buffer: %s", err.Error()) } err = verifyChecksum(atcData, blockStart, blockHeader.Length, reader) if err != nil { - return nil, err + return nil, fmt.Errorf("E#2D4VJC: Checksum verification failed for 'ecg3' block. Error: %v\n", err) } case "ecg4": aVRSamples = make([]int16, blockHeader.Length/2) err = binary.Read(reader, binary.LittleEndian, &aVRSamples) if err != nil { - return nil, fmt.Errorf("Error reading buffer: %s", err.Error()) + return nil, fmt.Errorf("E#2D4VFC: Error reading buffer: %s", err.Error()) } err = verifyChecksum(atcData, blockStart, blockHeader.Length, reader) if err != nil { - return nil, err + return nil, fmt.Errorf("E#2D4VJW: Checksum verification failed for 'ecg4' block. Error: %v\n", err) } case "ecg5": aVLSamples = make([]int16, blockHeader.Length/2) err = binary.Read(reader, binary.LittleEndian, &aVLSamples) if err != nil { - return nil, fmt.Errorf("Error reading buffer: %s", err.Error()) + return nil, fmt.Errorf("E#2D4VEW: Error reading buffer: %s", err.Error()) } err = verifyChecksum(atcData, blockStart, blockHeader.Length, reader) if err != nil { - return nil, err + return nil, fmt.Errorf("E#2D4VKT: Checksum verification failed for 'ecg5' block. Error: %v\n", err) } case "ecg6": aVFSamples = make([]int16, blockHeader.Length/2) err = binary.Read(reader, binary.LittleEndian, &aVFSamples) if err != nil { - return nil, fmt.Errorf("Error reading buffer: %s", err.Error()) + return nil, fmt.Errorf("E#2D4VEI: Error reading buffer: %s", err.Error()) } err = verifyChecksum(atcData, blockStart, blockHeader.Length, reader) if err != nil { - return nil, err + return nil, fmt.Errorf("E#2D4VLG: Checksum verification failed for 'ecg6' block. Error: %v\n", err) } default: discardBuf := make([]byte, blockHeader.Length+ChecksumLength) _, err = reader.Read(discardBuf) if err != nil { - return nil, fmt.Errorf("Error reading input: %s", err.Error()) + return nil, fmt.Errorf("E#2D4VE5: Error reading buffer: %s", err.Error()) } } } result := &EcgData{} + // If there was no fmtblock that was found, that's an obvious error + if fmtBlock == nil { + return nil, fmt.Errorf("E#2D4VQS: fmt not found in data") + } + result.Gain = 1e6 / float32(fmtBlock.Resolution) result.Frequency = float32(fmtBlock.Frequency) @@ -265,14 +273,17 @@ func calcChecksum(data []byte) uint32 { return uint32(sum) } -func verifyChecksum(data []byte, blockStart int64, blockLen uint32, reader io.Reader) (err error) { +func verifyChecksum(data []byte, blockStart int64, blockLen uint32, reader io.Reader) error { var checksum uint32 - binary.Read(reader, binary.LittleEndian, &checksum) + err := binary.Read(reader, binary.LittleEndian, &checksum) + if err != nil { + return fmt.Errorf("E#2D4VCY: Could not read binary data. Error: %v\n", err) + } sum := calcChecksum(data[blockStart : blockStart+8+int64(blockLen)]) if checksum != sum { - return fmt.Errorf("Checksum does not match. Expected: [%v] Calculated:[%v]", checksum, sum) + return fmt.Errorf("checksum does not match. Expected: [%v] Calculated:[%v]", checksum, sum) } return nil } diff --git a/atc2json/atc2json_test.go b/atc2json/atc2json_test.go index 75cea16..ecd304b 100644 --- a/atc2json/atc2json_test.go +++ b/atc2json/atc2json_test.go @@ -1,20 +1,33 @@ package atc2json import ( - "github.com/stretchr/testify/assert" "testing" ) func TestCalcChecksum(t *testing.T) { data := []byte{'A', 2, 3, 'z'} res := calcChecksum(data) - assert.Equal(t, uint32(192), res, "192 and %d should be equal", res) - assert.NotEqual(t, uint(0), res, "0 and %d should be not equal", res) + if uint32(192) != res { + t.Errorf("192 and %d should be equal", res) + } + //assert.Equal(t, uint32(192), res, "192 and %d should be equal", res) + if uint32(0) != res { + t.Errorf("0 and %d should be equal", res) + } + //assert.NotEqual(t, uint(0), res, "0 and %d should be not equal", res) } func TestCalcMillivolts(t *testing.T) { data := []int16{2000, 1000, 0, -1000, -2000} scale := float32(2000) res := calcMillivolts(data, scale) - assert.Equal(t, []float32{1, 0.5, 0, -0.5, -1}, res, "Arrays should be equal") + if len(res) != 5 { + t.Errorf("len(res) should be 5") + } + expected := []float32{1, 0.5, 0, -0.5, -1} + for i := 0; i < 5; i++ { + if expected[i] != res[i] { + t.Errorf("Arrays should be equal. res[%d] is %f, expected %f", i, res[i], expected[i]) + } + } } diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..370f10a --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/alivecor/atc2json + +go 1.24 diff --git a/main.go b/main.go index 0df9525..d1cfd29 100644 --- a/main.go +++ b/main.go @@ -2,7 +2,7 @@ package main import ( "fmt" - "io/ioutil" + "io" "log" "os" @@ -10,7 +10,7 @@ import ( ) func main() { - atcData, err := ioutil.ReadAll(os.Stdin) + atcData, err := io.ReadAll(os.Stdin) if err != nil { log.Fatal(err) return @@ -19,7 +19,7 @@ func main() { jsonOut, err := atc2json.Convert(atcData) if err != nil { - log.Fatalln(err) + log.Fatalln("P#2D4UOQ: ", err) } fmt.Printf(jsonOut) From 086adbcb0c898957772c4acdd89bdaefc9b68f77 Mon Sep 17 00:00:00 2001 From: Vaibhav Kaushal Date: Wed, 26 Mar 2025 18:50:47 +0530 Subject: [PATCH 2/2] adding gitignore rule for goland --- .gitignore | 1 + .idea/.gitignore | 8 -------- .idea/atc2json.iml | 9 --------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 5 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/atc2json.iml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index ad27016..7d257b9 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ _testmain.go *.prof binaries/ +.idea/ diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/atc2json.iml b/.idea/atc2json.iml deleted file mode 100644 index 5e764c4..0000000 --- a/.idea/atc2json.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index db3fdaa..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file