-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy patherrors.go
More file actions
119 lines (109 loc) · 3.48 KB
/
errors.go
File metadata and controls
119 lines (109 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Package squall provides a high-performance Go library for reading GRIB2
// (GRIdded Binary 2nd edition) meteorological data files.
//
// squall offers:
// - Pure Go implementation (no CGo)
// - 9.4x faster parallel decoding
// - Streaming API with io.ReadSeeker
// - 99.9% exact match with wgrib2 reference
// - Flexible filtering options
// - Comprehensive test coverage (157 tests)
//
// Basic usage:
//
// f, err := os.Open("forecast.grib2")
// if err != nil {
// log.Fatal(err)
// }
// defer f.Close()
//
// messages, err := squall.Read(f)
// if err != nil {
// log.Fatal(err)
// }
//
// for _, msg := range messages {
// fmt.Printf("%s at %s: %d points\n",
// msg.Parameter, msg.Level, len(msg.Values))
// }
//
// Filtering by parameter:
//
// messages, err := squall.ReadWithOptions(f,
// squall.WithParameterFilter("Temperature", "Relative Humidity"))
//
// Filtering by level:
//
// messages, err := squall.ReadWithOptions(f,
// squall.WithLevelFilter("500 mb", "Surface"))
//
// Context support:
//
// ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
// defer cancel()
//
// messages, err := squall.ReadWithOptions(f, squall.WithContext(ctx))
//
// Performance:
//
// squall processes GRIB2 messages in parallel using goroutines, achieving
// 9.4x speedup on large files with 708 messages. The parallel processing is
// optimized to use 2×NumCPU workers to balance speed and memory usage.
package squall
import "fmt"
// ParseError represents an error during GRIB2 parsing.
// It includes context about where in the file the error occurred.
type ParseError struct {
Section int // Which section (0-7), or -1 if file-level
Offset int // Byte offset in file where error occurred
Message string // Description of the error
Underlying error // Wrapped error, if any
}
// Error implements the error interface.
func (e *ParseError) Error() string {
if e.Section == -1 {
if e.Underlying != nil {
return fmt.Sprintf("at offset %d: %s: %v", e.Offset, e.Message, e.Underlying)
}
return fmt.Sprintf("at offset %d: %s", e.Offset, e.Message)
}
if e.Underlying != nil {
return fmt.Sprintf("section %d at offset %d: %s: %v",
e.Section, e.Offset, e.Message, e.Underlying)
}
return fmt.Sprintf("section %d at offset %d: %s",
e.Section, e.Offset, e.Message)
}
// Unwrap returns the underlying error, if any.
// This allows errors.Is and errors.As to work correctly.
func (e *ParseError) Unwrap() error {
return e.Underlying
}
// UnsupportedTemplateError indicates a template number that isn't implemented yet.
type UnsupportedTemplateError struct {
Section int // Which section (3=grid, 4=product, 5=data)
TemplateNumber int // The unsupported template number
}
// Error implements the error interface.
func (e *UnsupportedTemplateError) Error() string {
sectionName := "unknown"
switch e.Section {
case 3:
sectionName = "grid definition"
case 4:
sectionName = "product definition"
case 5:
sectionName = "data representation"
}
return fmt.Sprintf("unsupported %s template %d in section %d",
sectionName, e.TemplateNumber, e.Section)
}
// InvalidFormatError indicates that the data is not a valid GRIB2 file.
type InvalidFormatError struct {
Message string // Description of what's invalid
Offset int // Byte offset where the invalid data was found
}
// Error implements the error interface.
func (e *InvalidFormatError) Error() string {
return fmt.Sprintf("invalid GRIB2 format at offset %d: %s", e.Offset, e.Message)
}