frameset.go
func (s *FrameSet) handleMatch(match []string) error {
	switch len(match) {

	// Single frame match
	case 1:
		f, err := parseInt(match[0])
		if err != nil {
			return err
		}
		s.rangePtr.AppendUnique(f, f, 1)

	// Simple frame range
	case 2:
		start, err := parseInt(match[0])
		if err != nil {
			return err
		}
		end, err := parseInt(match[1])
		if err != nil {
			return err
		}

		// Handle descending frame ranges, like 10-1
		var inc int
		if start > end {
			inc = -1
		} else {
			inc = 1
		}

		s.rangePtr.AppendUnique(start, end, inc)

	// Complex frame range
	case 4:
		var (
			err               error
			mod               string
			start, end, chunk int
		)
		chunk, err = parseInt(match[3])
		if err != nil {
			return err
		}
		if chunk == 0 {
			return fmt.Errorf("Failed to parse part of range %v. "+
				"Encountered invalid 0 value", match[3])
		}
		if start, err = parseInt(match[0]); err != nil {
			return err
		}
		if end, err = parseInt(match[1]); err != nil {
			return err
		}
		if mod = match[2]; !isModifier(mod) {
			return fmt.Errorf("%q is not one of the valid modifier 'xy:'", mod)
		}

		switch mod {
		case `x`:
			s.rangePtr.AppendUnique(start, end, chunk)

		case `y`:
			// TODO: Add proper support for adding inverse of range.
			// This approach will add excessive amounts of singe
			// range elements. They could be compressed into chunks
			skip := start
			aRange := ranges.NewInclusiveRange(start, end, 1)
			var val int
			for it := aRange.IterValues(); !it.IsDone(); {
				val = it.Next()
				if val == skip {
					skip += chunk
					continue
				}
				s.rangePtr.AppendUnique(val, val, 1)
			}

		case `:`:
			for ; chunk > 0; chunk-- {
				s.rangePtr.AppendUnique(start, end, chunk)
			}
		}

	default:
		return fmt.Errorf("Unexpected match []string size: %v", match)
	}

	return nil
}
func (s *FrameSet) handleMatch(match []string) error {
	switch len(match) {

	// Single frame match
	case 1:
		f, err := parseInt(match[0])
		if err != nil {
			return err
		}
		s.rangePtr.AppendUnique(f, f, 1)

	// Simple frame range
	case 2:
		start, err := parseInt(match[0])
		if err != nil {
			return err
		}
		end, err := parseInt(match[1])
		if err != nil {
			return err
		}

		// Handle descending frame ranges, like 10-1
		var inc int
		if start > end {
			inc = -1
		} else {
			inc = 1
		}

		s.rangePtr.AppendUnique(start, end, inc)

	// Complex frame range
	case 4:
		var (
			err               error
			mod               string
			start, end, chunk int
		)
		chunk, err = parseInt(match[3])
		if err != nil {
			return err
		}
		if chunk == 0 {
			return fmt.Errorf("Failed to parse part of range %v. "+
				"Encountered invalid 0 value", match[3])
		}
		if start, err = parseInt(match[0]); err != nil {
			return err
		}
		if end, err = parseInt(match[1]); err != nil {
			return err
		}
		if mod = match[2]; !isModifier(mod) {
			return fmt.Errorf("%q is not one of the valid modifier 'xy:'", mod)
		}

		switch mod {
		case `x`:
			s.rangePtr.AppendUnique(start, end, chunk)

		case `y`:
			// TODO: Add proper support for adding inverse of range.
			// This approach will add excessive amounts of singe
			// range elements. They could be compressed into chunks
			skip := start
			aRange := ranges.NewInclusiveRange(start, end, 1)
			var val int
			for it := aRange.IterValues(); !it.IsDone(); {
				val = it.Next()
				if val == skip {
					skip += chunk
					continue
				}
				s.rangePtr.AppendUnique(val, val, 1)
			}

		case `:`:
			for ; chunk > 0; chunk-- {
				s.rangePtr.AppendUnique(start, end, chunk)
			}
		}

	default:
		return fmt.Errorf("Unexpected match []string size: %v", match)
	}

	return nil
}
// Process a rangePattern match group