Created
May 28, 2014 16:21
-
-
Save timthelion/28d0a4d320910965422f to your computer and use it in GitHub Desktop.
Device JSON Marshalers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package jsonDevices | |
| import ( | |
| "encoding/json" | |
| "fmt" | |
| "os" | |
| ) | |
| type JSONDevice struct { | |
| Type string `json:"type"` | |
| Path string `json:"path"` // It is fine if this is an empty string in the case that you are using Wildcards | |
| MajorNumber int64 `json:"major_number"` // Use the wildcard constant for wildcards. | |
| MinorNumber int64 `json:"minor_number"` // Use the wildcard constant for wildcards. | |
| CgroupPermissions string `json:"cgroup_permissions"` // Typically just "rwm" | |
| FileMode string `json:"file_mode"` // The permission bits of the file's mode | |
| } | |
| func (device Device) MarshalJSON() ([]byte,error){ | |
| jsonDevice := new(JSONDevice) | |
| switch device.Type{ | |
| case 'c': | |
| jsonDevice.Type="character" | |
| case 'b': | |
| jsonDevice.Type="block" | |
| default: | |
| return nil,fmt.Errorf("Invalid device type %c",device.Type) | |
| } | |
| jsonDevice.Path = device.Path | |
| jsonDevice.MajorNumber = device.MajorNumber | |
| jsonDevice.MinorNumber = device.MinorNumber | |
| jsonDevice.CgroupPermissions = device.CgroupPermissions | |
| jsonDevice.FileMode = buildFileModeString(device.FileMode) | |
| return json.Marshal(jsonDevice) | |
| } | |
| func buildFileModeString(fileMode os.FileMode) string{ | |
| fileModeString := []byte("rwxrwxrwx") | |
| // we go through the string blanking out(with '-') the permissions that are denied. | |
| for i := uint(0); i < 9; i++{ | |
| if (fileMode & (1 << i)) == 0{ | |
| fileModeString[i] = '-' | |
| } | |
| } | |
| return string(fileModeString) | |
| } | |
| func (device Device) UnmarshalJSON(input []byte) error { | |
| jsonDevice := new(JSONDevice) | |
| err := json.Unmarshal(input,jsonDevice) | |
| if err != nil { | |
| return err | |
| } | |
| switch jsonDevice.Type{ | |
| case "character": | |
| device.Type = 'c' | |
| case "block": | |
| device.Type = 'b' | |
| default: | |
| return fmt.Errorf("Invalid device type: %s",jsonDevice.Type) | |
| } | |
| device.Path = jsonDevice.Path | |
| device.MajorNumber = jsonDevice.MajorNumber | |
| device.MinorNumber = jsonDevice.MinorNumber | |
| device.CgroupPermissions = jsonDevice.CgroupPermissions | |
| if len(jsonDevice.FileMode) != 9{ | |
| return fmt.Errorf("Invalid file mode for device: %s",jsonDevice.FileMode) | |
| } | |
| modeSegment,err := readModeSegment(jsonDevice.FileMode[0:]) | |
| if err != nil{ | |
| return fmt.Errorf("Unable to parse file mode %s: %s",jsonDevice.FileMode,err) | |
| } | |
| device.FileMode |= os.FileMode(modeSegment << 6) | |
| modeSegment,err = readModeSegment(jsonDevice.FileMode[3:]) | |
| if err != nil{ | |
| return fmt.Errorf("Unable to parse file mode %s: %s",jsonDevice.FileMode,err) | |
| } | |
| device.FileMode |= os.FileMode(modeSegment << 3) | |
| modeSegment,err = readModeSegment(jsonDevice.FileMode[6:]) | |
| if err != nil{ | |
| return fmt.Errorf("Unable to parse file mode %s: %s",jsonDevice.FileMode,err) | |
| } | |
| device.FileMode |= os.FileMode(modeSegment) | |
| return nil | |
| } | |
| func readModeSegment(segment string) (uint32, error){ | |
| modeSegment := uint32(0) | |
| set,err := readModeFlag(segment[0],'r') | |
| if err != nil{ | |
| return 0,err | |
| } | |
| if set{ | |
| modeSegment |= 1 | |
| } | |
| set,err = readModeFlag(segment[1],'w') | |
| if err != nil{ | |
| return 0,err | |
| } | |
| if set{ | |
| modeSegment |= 2 | |
| } | |
| set,err = readModeFlag(segment[2],'x') | |
| if err != nil{ | |
| return 0,err | |
| } | |
| if set{ | |
| modeSegment |= 4 | |
| } | |
| return modeSegment,nil | |
| } | |
| func readModeFlag(flag byte,normalSetValue byte) (bool,error){ | |
| switch flag{ | |
| case normalSetValue: | |
| return true,nil | |
| case '-': | |
| return false,nil | |
| default: | |
| return false, fmt.Errorf("Unexpected file permission %c, expected %c or '-'.", flag,normalSetValue) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment