mirror of
https://github.com/blacktop/ipsw.git
synced 2026-05-08 12:22:26 +00:00
128 lines
4.4 KiB
Go
128 lines
4.4 KiB
Go
package xcode
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/gzip"
|
|
_ "embed"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/blacktop/ipsw/internal/utils"
|
|
)
|
|
|
|
//go:embed device_traits.gz
|
|
var traitsData []byte
|
|
|
|
// Device object
|
|
type Device struct {
|
|
Target string `gorm:"column:Target;primary_key" json:"target,omitempty"`
|
|
TargetType string `gorm:"column:TargetType" json:"target_type,omitempty"`
|
|
TargetVariant string `gorm:"column:TargetVariant" json:"target_variant,omitempty"`
|
|
Platform string `gorm:"column:Platform" json:"platform,omitempty"`
|
|
ProductType string `gorm:"column:ProductType" json:"product_type,omitempty"`
|
|
ProductDescription string `gorm:"column:ProductDescription" json:"product_description,omitempty"`
|
|
CompatibleDeviceFallback string `gorm:"column:CompatibleDeviceFallback" json:"compatible_device_fallback,omitempty"`
|
|
DeviceTrait DeviceTrait `gorm:"foreignkey:DeviceTraitSet" json:"traits,omitempty"`
|
|
DeviceTraitSet int `gorm:"column:DeviceTraitSet" json:"-"`
|
|
}
|
|
|
|
// TableName returns the table name for the Device object
|
|
func (Device) TableName() string {
|
|
return "Devices"
|
|
}
|
|
|
|
type Devices []Device
|
|
|
|
func (d Devices) Len() int { return len(d) }
|
|
func (d Devices) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
|
|
|
|
type ByProductType struct{ Devices }
|
|
|
|
func (s ByProductType) Less(i, j int) bool {
|
|
devI := utils.DeconstructDevice(s.Devices[i].ProductType)
|
|
devJ := utils.DeconstructDevice(s.Devices[j].ProductType)
|
|
return fmt.Sprintf("%s%02d%02d", devI.Family, devI.Major, devI.Minor) < fmt.Sprintf("%s%02d%02d", devJ.Family, devJ.Major, devJ.Minor)
|
|
}
|
|
|
|
// DeviceTrait object
|
|
type DeviceTrait struct {
|
|
DeviceTraitSetID int `gorm:"column:DeviceTraitSetID;primary_key" json:"-"`
|
|
PreferredArchitecture string `gorm:"column:PreferredArchitecture" json:"preferred_architecture,omitempty"`
|
|
ArtworkDeviceIdiom string `gorm:"column:ArtworkDeviceIdiom" json:"artwork_device_idiom,omitempty"`
|
|
ArtworkHostedIdioms string `gorm:"column:ArtworkHostedIdioms" json:"artwork_hosted_idioms,omitempty"`
|
|
ArtworkScaleFactor int `gorm:"column:ArtworkScaleFactor" json:"artwork_scale_factor,omitempty"`
|
|
ArtworkDeviceSubtype int `gorm:"column:ArtworkDeviceSubtype" json:"artwork_device_subtype,omitempty"`
|
|
ArtworkDisplayGamut string `gorm:"column:ArtworkDisplayGamut" json:"artwork_display_gamut,omitempty"`
|
|
ArtworkDynamicDisplayMode string `gorm:"column:ArtworkDynamicDisplayMode" json:"artwork_dynamic_display_mode,omitempty"`
|
|
DevicePerformanceMemoryClass int `gorm:"column:DevicePerformanceMemoryClass" json:"device_performance_memory_class,omitempty"`
|
|
GraphicsFeatureSetClass string `gorm:"column:GraphicsFeatureSetClass" json:"graphics_feature_set_class,omitempty"`
|
|
GraphicsFeatureSetFallbacks string `gorm:"column:GraphicsFeatureSetFallbacks" json:"graphics_feature_set_fallbacks,omitempty"`
|
|
}
|
|
|
|
// TableName returns the table name for the DeviceTrait object
|
|
func (DeviceTrait) TableName() string {
|
|
return "DeviceTraits"
|
|
}
|
|
|
|
// WriteToJSON writes the data to JSON
|
|
func WriteToJSON(devices []Device, dest string) error {
|
|
dJSON, err := json.Marshal(devices)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(filepath.Clean(dest), dJSON, 0660)
|
|
}
|
|
|
|
// GetDevices reads the devices from embedded JSON
|
|
func GetDevices() ([]Device, error) {
|
|
var devices []Device
|
|
|
|
zr, err := gzip.NewReader(bytes.NewReader(traitsData))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer zr.Close()
|
|
|
|
if err := json.NewDecoder(zr).Decode(&devices); err != nil {
|
|
return nil, fmt.Errorf("failed unmarshaling device_traits.gz data: %w", err)
|
|
}
|
|
|
|
return devices, nil
|
|
}
|
|
|
|
// GetDeviceForProd returns the device matching a given product type
|
|
func GetDeviceForProd(prod string) (*Device, error) {
|
|
|
|
devices, err := GetDevices()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, device := range devices {
|
|
if device.ProductType == prod {
|
|
return &device, nil
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("device not found")
|
|
}
|
|
|
|
// GetDeviceForModel returns the device matching a given model
|
|
func GetDeviceForModel(model string) (*Device, error) {
|
|
|
|
devices, err := GetDevices()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, device := range devices {
|
|
if device.Target == model {
|
|
return &device, nil
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("device not found")
|
|
}
|