main
c49a4ab · 23 days ago 6 commits
 1package internal
 2
 3import (
 4	"archive/zip"
 5	"encoding/xml"
 6	"fmt"
 7	"io"
 8)
 9
10func LoadFile(path string) (*Circuit, error) {
11	circuit, err := loadXML(path)
12	if err != nil {
13		return nil, err
14	}
15	cleanupCircuit(circuit)
16	return documentFromXML(circuit), nil
17}
18
19func loadXML(path string) (*xmlCircuit, error) {
20	r, err := zip.OpenReader(path)
21	if err != nil {
22		return nil, fmt.Errorf("failed to open .cddx as a zip archive: %w", err)
23	}
24	defer r.Close()
25
26	const docPath = "circuitdiagram/Document.xml"
27
28	var docFile *zip.File
29	for _, f := range r.File {
30		if f.Name == docPath {
31			docFile = f
32			break
33		}
34	}
35	if docFile == nil {
36		return nil, fmt.Errorf("'%s' not found inside archive — not a valid .cddx file", docPath)
37	}
38
39	rc, err := docFile.Open()
40	if err != nil {
41		return nil, fmt.Errorf("failed to open '%s' inside archive: %w", docPath, err)
42	}
43	defer rc.Close()
44
45	data, err := io.ReadAll(rc)
46	if err != nil {
47		return nil, fmt.Errorf("failed to read '%s': %w", docPath, err)
48	}
49
50	var circuit xmlCircuit
51	if err := xml.Unmarshal(data, &circuit); err != nil {
52		return nil, fmt.Errorf("failed to parse '%s': %w", docPath, err)
53	}
54	return &circuit, nil
55}