all repos — nds-converter @ c49ad1e5149c8ebc9941e186f50cbcef737a4732

A lightweight save converter for NDS and DeSmuME.

backend.go (view raw)

 1package main
 2
 3import (
 4	"io"
 5	"net/http"
 6	"path/filepath"
 7	"strconv"
 8)
 9
10type ConverterFunction func([]byte) []byte
11
12const (
13	MB                 = 1 << 20
14	DefaultMaxFileSize = 2
15	TrimBytes          = 122
16	AdditionalBytesHex = "7C3C2D2D536E69702061626F7665206865726520746F2063726561746520612072617720736176206279206578636C7564696E672074686973204465536D754D4520736176656461746120666F6F7465723A0000010000000100030000000200000000000100000000007C2D4445534D554D4520534156452D7C"
17)
18
19var (
20	MaxFileSize        int64
21	AdditionalBytes    []byte
22	ConverterFunctions = map[string]ConverterFunction{
23		".dsv": DsvToSav,
24		".sav": SavToDsv,
25	}
26)
27
28func DsvToSav(input []byte) []byte {
29	return input[:len(input)-TrimBytes]
30}
31
32func SavToDsv(input []byte) []byte {
33	return append(input, AdditionalBytes...)
34}
35
36func postHandler(w http.ResponseWriter, r *http.Request) {
37	// Parse the multipart form data
38	err := r.ParseMultipartForm(MaxFileSize)
39	if err != nil {
40		http.Error(w, "Error parsing form", http.StatusBadRequest)
41		return
42	}
43
44	r.Body = http.MaxBytesReader(w, r.Body, MaxFileSize)
45
46	// Get the file from the request
47	file, h, err := r.FormFile("file")
48	if err != nil {
49		http.Error(w, "Error retrieving file from form data", http.StatusBadRequest)
50		return
51	}
52	defer file.Close()
53
54	// Check file size
55	if h.Size > MaxFileSize {
56		http.Error(w, "File size exceeds 1MB", http.StatusBadRequest)
57		return
58	}
59
60	var outputContent []byte
61
62	// Check file extension
63	fileExt := filepath.Ext(h.Filename)
64	converterFunction, exists := ConverterFunctions[fileExt]
65	if !exists {
66		http.Error(w, "Invalid file format, only .dsv and .sav files are allowed", http.StatusBadRequest)
67		return
68	}
69
70	content, err := io.ReadAll(file)
71	if err != nil {
72		http.Error(w, "Error reading file content", http.StatusInternalServerError)
73		return
74	}
75	outputContent = converterFunction(content)
76
77	w.Header().Set("Content-Length", strconv.Itoa(len(outputContent)))
78	w.Header().Set("Content-Type", "application/octet-stream")
79	w.WriteHeader(http.StatusOK)
80	w.Write(outputContent)
81}