checkpoint 1

This commit is contained in:
2025-08-24 18:16:04 -07:00
parent c550f7d0df
commit 91493446b7
20 changed files with 4439 additions and 758 deletions

View File

@@ -1,55 +1,31 @@
// internal/parser/detector.go
package parser
import (
"bytes"
"os"
"bytes"
"errors"
)
type FileType string
const (
FileTypeFIT FileType = "fit"
FileTypeTCX FileType = "tcx"
FileTypeGPX FileType = "gpx"
FileTypeUnknown FileType = "unknown"
var (
// FIT file signature
fitSignature = []byte{0x0E, 0x10} // .FIT files start with 0x0E 0x10
)
func DetectFileType(filepath string) (FileType, error) {
file, err := os.Open(filepath)
if err != nil {
return FileTypeUnknown, err
}
defer file.Close()
// Read first 512 bytes for detection
header := make([]byte, 512)
n, err := file.Read(header)
if err != nil && n == 0 {
return FileTypeUnknown, err
}
header = header[:n]
return DetectFileTypeFromData(header), nil
}
// DetectFileType detects the file type based on its content
func DetectFileType(data []byte) (string, error) {
// Check FIT file signature
if len(data) >= 2 && bytes.Equal(data[:2], fitSignature) {
return ".fit", nil
}
func DetectFileTypeFromData(data []byte) FileType {
// Check for FIT file signature
if len(data) >= 8 && bytes.Equal(data[8:12], []byte(".FIT")) {
return FileTypeFIT
}
// Check for XML-based formats
if bytes.HasPrefix(data, []byte("<?xml")) {
if bytes.Contains(data[:200], []byte("<gpx")) ||
bytes.Contains(data[:200], []byte("topografix.com/GPX")) {
return FileTypeGPX
}
if bytes.Contains(data[:500], []byte("TrainingCenterDatabase")) {
return FileTypeTCX
}
}
return FileTypeUnknown
// Check TCX file signature (XML with TrainingCenterDatabase root)
if bytes.Contains(data, []byte("<TrainingCenterDatabase")) {
return ".tcx", nil
}
// Check GPX file signature (XML with <gpx> root)
if bytes.Contains(data, []byte("<gpx")) {
return ".gpx", nil
}
return "", errors.New("unrecognized file format")
}