package web import ( "errors" "fmt" "net/url" "sort" ) type fileMap map[string]string var errInvalidPasteForm = errors.New("invalid map of filenames to filenames") type indexFileMapping struct { indices []int filenames []string } func (m *indexFileMapping) insert(index int, filename string) { m.indices = append(m.indices, index) m.filenames = append(m.filenames, filename) } func (m *indexFileMapping) Len() int { if len(m.indices) != len(m.filenames) { panic("indices and filenames do not map one to one") } return len(m.indices) } func (m *indexFileMapping) Less(i, j int) bool { return m.indices[i] < m.indices[j] } func (m *indexFileMapping) Swap(i, j int) { m.indices[i], m.indices[j] = m.indices[j], m.indices[i] m.filenames[i], m.filenames[j] = m.filenames[j], m.filenames[i] } // Returns a map of the files and an ordered list of the files func makeFileMap(formData url.Values) (fileMap, []string, error) { fileMap := make(fileMap) filenames, err := makeOrderedFilenameList(formData) if err != nil { return nil, nil, err } for formKey, formValue := range formData { if len(formValue) != 1 { fmt.Println("here") return nil, nil, errInvalidPasteForm } var fileIndex int n, err := fmt.Sscanf(formKey, fileNameFormKey+"%d", &fileIndex) if n == 0 || err != nil { // We aren't looking at a file name key in this case continue } filename := formValue[0] bodyKey := fmt.Sprintf("%s%d", bodyFormKey, fileIndex) fmt.Println(bodyKey) bodyEntry, haveBody := formData[bodyKey] if !haveBody || len(bodyEntry) != 1 { fmt.Println("here2") return nil, nil, errInvalidPasteForm } fileMap[filename] = bodyEntry[0] } return fileMap, filenames, nil } func makeOrderedFilenameList(formData url.Values) ([]string, error) { indicesToFiles := indexFileMapping{ indices: make([]int, 0), filenames: make([]string, 0), } for formKey, formValue := range formData { if len(formValue) != 1 { fmt.Println("here3") return nil, errInvalidPasteForm } var fileIndex int n, err := fmt.Sscanf(formKey, fileNameFormKey+"%d", &fileIndex) if n == 0 || err != nil { // We aren't looking at a file name key in this case continue } indicesToFiles.insert(fileIndex, formValue[0]) } sort.Sort(&indicesToFiles) return indicesToFiles.filenames, nil }