|
| 1 | +package fixedlength |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + |
| 6 | + "github.com/jf-tech/go-corelib/caches" |
| 7 | +) |
| 8 | + |
| 9 | +type byHeaderFooterDecl struct { |
| 10 | + Header string `json:"header"` |
| 11 | + Footer string `json:"footer"` |
| 12 | +} |
| 13 | + |
| 14 | +type columnDecl struct { |
| 15 | + Name string `json:"name"` |
| 16 | + StartPos int `json:"start_pos"` // 1-based. and rune-based. |
| 17 | + Length int `json:"length"` // rune-based length. |
| 18 | + Line *string `json:"line"` |
| 19 | +} |
| 20 | + |
| 21 | +type envelopeDecl struct { |
| 22 | + Name *string `json:"name"` |
| 23 | + ByHeaderFooter *byHeaderFooterDecl `json:"by_header_footer"` |
| 24 | + ByRows *int `json:"by_rows"` |
| 25 | + NotTarget bool `json:"not_target"` |
| 26 | + Columns []*columnDecl `json:"columns"` |
| 27 | +} |
| 28 | + |
| 29 | +type fileDecl struct { |
| 30 | + Envelopes []*envelopeDecl `json:"envelopes"` |
| 31 | +} |
| 32 | + |
| 33 | +func (c *columnDecl) lineMatch(line []byte) bool { |
| 34 | + if c.Line == nil { |
| 35 | + return true |
| 36 | + } |
| 37 | + // validated in validation code. |
| 38 | + r, _ := caches.GetRegex(*c.Line) |
| 39 | + return r.Match(line) |
| 40 | +} |
| 41 | + |
| 42 | +func (c *columnDecl) lineToColumn(line []rune) []rune { |
| 43 | + // StartPos is 1-based and its value >= 1 guaranteed by json schema validation done earlier. |
| 44 | + startPosZeroBased := c.StartPos - 1 |
| 45 | + // If [startPosZeroBased, c.Length] is partially out of range, we'll return whatever is |
| 46 | + // in range; if [startPosZeroBased, c.Length] is fully out of range, we'll return "". |
| 47 | + switch { |
| 48 | + case startPosZeroBased+c.Length <= len(line): |
| 49 | + return line[startPosZeroBased : startPosZeroBased+c.Length] |
| 50 | + case startPosZeroBased < len(line): |
| 51 | + return line[startPosZeroBased:] |
| 52 | + } |
| 53 | + return nil |
| 54 | +} |
| 55 | + |
| 56 | +func (e *envelopeDecl) byRows() int { |
| 57 | + if e.ByHeaderFooter != nil { |
| 58 | + panic(fmt.Sprintf("envelope '%s' type is not 'by_rows'", *e.Name)) |
| 59 | + } |
| 60 | + if e.ByRows == nil { |
| 61 | + return 1 |
| 62 | + } |
| 63 | + return *e.ByRows |
| 64 | +} |
0 commit comments