archive.go
func (v *volume) nextVolName() {
	if v.num == 0 {
		// check file extensions
		i := strings.LastIndex(v.file, ".")
		if i < 0 {
			// no file extension, add one
			i = len(v.file)
			v.file += ".rar"
		} else {
			ext := strings.ToLower(v.file[i+1:])
			// replace with .rar for empty extensions & self extracting archives
			if ext == "" || ext == "exe" || ext == "sfx" {
				v.file = v.file[:i+1] + "rar"
			}
		}
		if a, ok := v.fileBlockReader.(*archive15); ok {
			v.old = a.old
		}
		// new naming scheme must have volume number in filename
		if !v.old && reDigits.FindStringIndex(v.file) == nil {
			v.old = true
		}
		// For old style naming if 2nd and 3rd character of file extension is not a digit replace
		// with "00" and ignore any trailing characters.
		if v.old && (len(v.file) < i+4 || v.file[i+2] < '0' || v.file[i+2] > '9' || v.file[i+3] < '0' || v.file[i+3] > '9') {
			v.file = v.file[:i+2] + "00"
			return
		}
	}
	// new style volume naming
	if !v.old {
		// find all numbers in volume name
		m := reDigits.FindAllStringIndex(v.file, -1)
		if l := len(m); l > 1 {
			// More than 1 match so assume name.part###of###.rar style.
			// Take the last 2 matches where the first is the volume number.
			m = m[l-2 : l]
			if strings.Contains(v.file[m[0][1]:m[1][0]], ".") || !strings.Contains(v.file[:m[0][0]], ".") {
				// Didn't match above style as volume had '.' between the two numbers or didnt have a '.'
				// before the first match. Use the second number as volume number.
				m = m[1:]
			}
		}
		// extract and increment volume number
		lo, hi := m[0][0], m[0][1]
		n, err := strconv.Atoi(v.file[lo:hi])
		if err != nil {
			n = 0
		} else {
			n++
		}
		// volume number must use at least the same number of characters as previous volume
		vol := fmt.Sprintf("%0"+fmt.Sprint(hi-lo)+"d", n)
		v.file = v.file[:lo] + vol + v.file[hi:]
		return
	}
	// old style volume naming
	i := strings.LastIndex(v.file, ".")
	// get file extension
	b := []byte(v.file[i+1:])
	// start incrementing volume number digits from rightmost
	for j := 2; j >= 0; j-- {
		if b[j] != '9' {
			b[j]++
			break
		}
		// digit overflow
		if j == 0 {
			// last character before '.'
			b[j] = 'A'
		} else {
			// set to '0' and loop to next character
			b[j] = '0'
		}
	}
	v.file = v.file[:i+1] + string(b)
}
func (v *volume) nextVolName() {
	if v.num == 0 {
		// check file extensions
		i := strings.LastIndex(v.file, ".")
		if i < 0 {
			// no file extension, add one
			i = len(v.file)
			v.file += ".rar"
		} else {
			ext := strings.ToLower(v.file[i+1:])
			// replace with .rar for empty extensions & self extracting archives
			if ext == "" || ext == "exe" || ext == "sfx" {
				v.file = v.file[:i+1] + "rar"
			}
		}
		if a, ok := v.fileBlockReader.(*archive15); ok {
			v.old = a.old
		}
		// new naming scheme must have volume number in filename
		if !v.old && reDigits.FindStringIndex(v.file) == nil {
			v.old = true
		}
		// For old style naming if 2nd and 3rd character of file extension is not a digit replace
		// with "00" and ignore any trailing characters.
		if v.old && (len(v.file) < i+4 || v.file[i+2] < '0' || v.file[i+2] > '9' || v.file[i+3] < '0' || v.file[i+3] > '9') {
			v.file = v.file[:i+2] + "00"
			return
		}
	}
	// new style volume naming
	if !v.old {
		// find all numbers in volume name
		m := reDigits.FindAllStringIndex(v.file, -1)
		if l := len(m); l > 1 {
			// More than 1 match so assume name.part###of###.rar style.
			// Take the last 2 matches where the first is the volume number.
			m = m[l-2 : l]
			if strings.Contains(v.file[m[0][1]:m[1][0]], ".") || !strings.Contains(v.file[:m[0][0]], ".") {
				// Didn't match above style as volume had '.' between the two numbers or didnt have a '.'
				// before the first match. Use the second number as volume number.
				m = m[1:]
			}
		}
		// extract and increment volume number
		lo, hi := m[0][0], m[0][1]
		n, err := strconv.Atoi(v.file[lo:hi])
		if err != nil {
			n = 0
		} else {
			n++
		}
		// volume number must use at least the same number of characters as previous volume
		vol := fmt.Sprintf("%0"+fmt.Sprint(hi-lo)+"d", n)
		v.file = v.file[:lo] + vol + v.file[hi:]
		return
	}
	// old style volume naming
	i := strings.LastIndex(v.file, ".")
	// get file extension
	b := []byte(v.file[i+1:])
	// start incrementing volume number digits from rightmost
	for j := 2; j >= 0; j-- {
		if b[j] != '9' {
			b[j]++
			break
		}
		// digit overflow
		if j == 0 {
			// last character before '.'
			b[j] = 'A'
		} else {
			// set to '0' and loop to next character
			b[j] = '0'
		}
	}
	v.file = v.file[:i+1] + string(b)
}
// nextVolName updates name to the next filename in the archive.