github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/packages/rubygems/marshal.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package rubygems 7 8 import ( 9 "bufio" 10 "bytes" 11 "errors" 12 "io" 13 "reflect" 14 ) 15 16 const ( 17 majorVersion = 4 18 minorVersion = 8 19 20 typeNil = '0' 21 typeTrue = 'T' 22 typeFalse = 'F' 23 typeFixnum = 'i' 24 typeString = '"' 25 typeSymbol = ':' 26 typeSymbolLink = ';' 27 typeArray = '[' 28 typeIVar = 'I' 29 typeUserMarshal = 'U' 30 typeUserDef = 'u' 31 typeObject = 'o' 32 ) 33 34 var ( 35 // ErrUnsupportedType indicates an unsupported type 36 ErrUnsupportedType = errors.New("Type is unsupported") 37 // ErrInvalidIntRange indicates an invalid number range 38 ErrInvalidIntRange = errors.New("Number is not in valid range") 39 ) 40 41 // RubyUserMarshal is a Ruby object that has a marshal_load function. 42 type RubyUserMarshal struct { 43 Name string 44 Value interface{} 45 } 46 47 // RubyUserDef is a Ruby object that has a _load function. 48 type RubyUserDef struct { 49 Name string 50 Value interface{} 51 } 52 53 // RubyObject is a default Ruby object. 54 type RubyObject struct { 55 Name string 56 Member map[string]interface{} 57 } 58 59 // MarshalEncoder mimics Rubys Marshal class. 60 // Note: Only supports types used by the RubyGems package registry. 61 type MarshalEncoder struct { 62 w *bufio.Writer 63 symbols map[string]int 64 } 65 66 // NewMarshalEncoder creates a new MarshalEncoder 67 func NewMarshalEncoder(w io.Writer) *MarshalEncoder { 68 return &MarshalEncoder{ 69 w: bufio.NewWriter(w), 70 symbols: map[string]int{}, 71 } 72 } 73 74 // Encode encodes the given type 75 func (e *MarshalEncoder) Encode(v interface{}) error { 76 if _, err := e.w.Write([]byte{majorVersion, minorVersion}); err != nil { 77 return err 78 } 79 80 if err := e.marshal(v); err != nil { 81 return err 82 } 83 84 return e.w.Flush() 85 } 86 87 func (e *MarshalEncoder) marshal(v interface{}) error { 88 if v == nil { 89 return e.marshalNil() 90 } 91 92 val := reflect.ValueOf(v) 93 typ := reflect.TypeOf(v) 94 95 if typ.Kind() == reflect.Ptr { 96 val = val.Elem() 97 typ = typ.Elem() 98 } 99 100 switch typ.Kind() { 101 case reflect.Bool: 102 return e.marshalBool(val.Bool()) 103 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32: 104 return e.marshalInt(val.Int()) 105 case reflect.String: 106 return e.marshalString(val.String()) 107 case reflect.Slice, reflect.Array: 108 return e.marshalArray(val) 109 } 110 111 switch typ.Name() { 112 case "RubyUserMarshal": 113 return e.marshalUserMarshal(val.Interface().(RubyUserMarshal)) 114 case "RubyUserDef": 115 return e.marshalUserDef(val.Interface().(RubyUserDef)) 116 case "RubyObject": 117 return e.marshalObject(val.Interface().(RubyObject)) 118 } 119 120 return ErrUnsupportedType 121 } 122 123 func (e *MarshalEncoder) marshalNil() error { 124 return e.w.WriteByte(typeNil) 125 } 126 127 func (e *MarshalEncoder) marshalBool(b bool) error { 128 if b { 129 return e.w.WriteByte(typeTrue) 130 } 131 return e.w.WriteByte(typeFalse) 132 } 133 134 func (e *MarshalEncoder) marshalInt(i int64) error { 135 if err := e.w.WriteByte(typeFixnum); err != nil { 136 return err 137 } 138 139 return e.marshalIntInternal(i) 140 } 141 142 func (e *MarshalEncoder) marshalIntInternal(i int64) error { 143 if i == 0 { 144 return e.w.WriteByte(0) 145 } else if 0 < i && i < 123 { 146 return e.w.WriteByte(byte(i + 5)) 147 } else if -124 < i && i <= -1 { 148 return e.w.WriteByte(byte(i - 5)) 149 } 150 151 var len int 152 if 122 < i && i <= 0xff { 153 len = 1 154 } else if 0xff < i && i <= 0xffff { 155 len = 2 156 } else if 0xffff < i && i <= 0xffffff { 157 len = 3 158 } else if 0xffffff < i && i <= 0x3fffffff { 159 len = 4 160 } else if -0x100 <= i && i < -123 { 161 len = -1 162 } else if -0x10000 <= i && i < -0x100 { 163 len = -2 164 } else if -0x1000000 <= i && i < -0x100000 { 165 len = -3 166 } else if -0x40000000 <= i && i < -0x1000000 { 167 len = -4 168 } else { 169 return ErrInvalidIntRange 170 } 171 172 if err := e.w.WriteByte(byte(len)); err != nil { 173 return err 174 } 175 if len < 0 { 176 len = -len 177 } 178 179 for c := 0; c < len; c++ { 180 if err := e.w.WriteByte(byte(i >> uint(8*c) & 0xff)); err != nil { 181 return err 182 } 183 } 184 185 return nil 186 } 187 188 func (e *MarshalEncoder) marshalString(str string) error { 189 if err := e.w.WriteByte(typeIVar); err != nil { 190 return err 191 } 192 193 if err := e.marshalRawString(str); err != nil { 194 return err 195 } 196 197 if err := e.marshalIntInternal(1); err != nil { 198 return err 199 } 200 201 if err := e.marshalSymbol("E"); err != nil { 202 return err 203 } 204 205 return e.marshalBool(true) 206 } 207 208 func (e *MarshalEncoder) marshalRawString(str string) error { 209 if err := e.w.WriteByte(typeString); err != nil { 210 return err 211 } 212 213 if err := e.marshalIntInternal(int64(len(str))); err != nil { 214 return err 215 } 216 217 _, err := e.w.WriteString(str) 218 return err 219 } 220 221 func (e *MarshalEncoder) marshalSymbol(str string) error { 222 if index, ok := e.symbols[str]; ok { 223 if err := e.w.WriteByte(typeSymbolLink); err != nil { 224 return err 225 } 226 return e.marshalIntInternal(int64(index)) 227 } 228 229 e.symbols[str] = len(e.symbols) 230 231 if err := e.w.WriteByte(typeSymbol); err != nil { 232 return err 233 } 234 235 if err := e.marshalIntInternal(int64(len(str))); err != nil { 236 return err 237 } 238 239 _, err := e.w.WriteString(str) 240 return err 241 } 242 243 func (e *MarshalEncoder) marshalArray(arr reflect.Value) error { 244 if err := e.w.WriteByte(typeArray); err != nil { 245 return err 246 } 247 248 len := arr.Len() 249 250 if err := e.marshalIntInternal(int64(len)); err != nil { 251 return err 252 } 253 254 for i := 0; i < len; i++ { 255 if err := e.marshal(arr.Index(i).Interface()); err != nil { 256 return err 257 } 258 } 259 return nil 260 } 261 262 func (e *MarshalEncoder) marshalUserMarshal(userMarshal RubyUserMarshal) error { 263 if err := e.w.WriteByte(typeUserMarshal); err != nil { 264 return err 265 } 266 267 if err := e.marshalSymbol(userMarshal.Name); err != nil { 268 return err 269 } 270 271 return e.marshal(userMarshal.Value) 272 } 273 274 func (e *MarshalEncoder) marshalUserDef(userDef RubyUserDef) error { 275 var buf bytes.Buffer 276 if err := NewMarshalEncoder(&buf).Encode(userDef.Value); err != nil { 277 return err 278 } 279 280 if err := e.w.WriteByte(typeUserDef); err != nil { 281 return err 282 } 283 if err := e.marshalSymbol(userDef.Name); err != nil { 284 return err 285 } 286 if err := e.marshalIntInternal(int64(buf.Len())); err != nil { 287 return err 288 } 289 _, err := e.w.Write(buf.Bytes()) 290 return err 291 } 292 293 func (e *MarshalEncoder) marshalObject(obj RubyObject) error { 294 if err := e.w.WriteByte(typeObject); err != nil { 295 return err 296 } 297 if err := e.marshalSymbol(obj.Name); err != nil { 298 return err 299 } 300 if err := e.marshalIntInternal(int64(len(obj.Member))); err != nil { 301 return err 302 } 303 for k, v := range obj.Member { 304 if err := e.marshalSymbol(k); err != nil { 305 return err 306 } 307 if err := e.marshal(v); err != nil { 308 return err 309 } 310 } 311 return nil 312 }