github.com/cnotch/ipchub@v1.1.0/av/format/amf/object.go (about) 1 // Copyright (c) 2019,CAOHONGJU All rights reserved. 2 // Use of this source code is governed by a MIT-style 3 // license that can be found in the LICENSE file. 4 5 package amf 6 7 import ( 8 "encoding/binary" 9 "fmt" 10 "io" 11 ) 12 13 // ObjectProperty amf 对象属性 14 type ObjectProperty struct { 15 Name string 16 Value interface{} 17 } 18 19 // PropertyValue 获取属性数组中指定属性名的值 20 func PropertyValue(properties []ObjectProperty, name string) (value interface{}, ok bool) { 21 for _, prop := range properties { 22 if name == prop.Name { 23 return prop.Value, true 24 } 25 } 26 return nil, false 27 } 28 29 // EcmaArray 表示 TypeEcmaArray 类型存储的值 30 type EcmaArray []ObjectProperty 31 32 // ReadEcmaArray . 33 func ReadEcmaArray(r io.Reader) (value EcmaArray, err error) { 34 var buff [1]byte 35 if _, err = io.ReadFull(r, buff[:]); err != nil { 36 return 37 } 38 39 if TypeEcmaArray != buff[0] { 40 err = fmt.Errorf("Amf0ReadEcmaArray: TypeEcmaArray != marker") 41 return 42 } 43 return readEcmaArray(r) 44 } 45 46 func readEcmaArray(r io.Reader) (value EcmaArray, err error) { 47 var buff [4]byte 48 if _, err = io.ReadFull(r, buff[:]); err != nil { 49 return 50 } 51 52 count := int(binary.BigEndian.Uint32(buff[:])) 53 value = make(EcmaArray, 0, count) 54 for { 55 var elem ObjectProperty 56 if elem.Name, err = readUtf8(r, 2); err != nil { 57 return 58 } 59 60 if elem.Value, err = ReadAny(r); err != nil { 61 return 62 } 63 64 // 判断是否是 ObjectEnd 65 if _, ok := elem.Value.(objectEndValue); ok && len(elem.Name) == 0 { 66 break 67 } 68 69 value = append(value, elem) 70 } 71 72 if len(value) != count { 73 err = fmt.Errorf("Does not match the expected length of the array and the actual; expected = %d ,actual = %d", count, len(value)) 74 } 75 return 76 } 77 78 // WriteEcmaArray . 79 func WriteEcmaArray(w io.Writer, arr EcmaArray) (err error) { 80 var buff [5]byte 81 82 buff[0] = TypeEcmaArray 83 binary.BigEndian.PutUint32(buff[1:], uint32(len(arr))) 84 if _, err = w.Write(buff[:]); err != nil { 85 return 86 } 87 88 for _, elem := range arr { 89 if err = writeUtf8(w, elem.Name, 2); err != nil { 90 return 91 } 92 if err = WriteAny(w, elem.Value); err != nil { 93 return 94 } 95 } 96 97 //eof 98 if _, err = w.Write([]byte{0x00, 0x00, TypeObjectEnd}); err != nil { 99 return 100 } 101 return 102 } 103 104 // Object 表示 TypeObject 类型存储的值 105 type Object []ObjectProperty 106 107 // ReadObject . 108 func ReadObject(r io.Reader) (value Object, err error) { 109 var data [1]byte 110 if _, err = io.ReadFull(r, data[:]); err != nil { 111 return 112 } 113 114 if TypeObject != data[0] { 115 err = fmt.Errorf("Amf0ReadObject: TypeObject != marker") 116 return 117 } 118 return readObject(r) 119 } 120 121 func readObject(r io.Reader) (value Object, err error) { 122 for { 123 var prop ObjectProperty 124 if prop.Name, err = readUtf8(r, 2); err != nil { 125 return 126 } 127 128 if prop.Value, err = ReadAny(r); err != nil { 129 return 130 } 131 132 // 判断是否是 ObjectEnd 133 if _, ok := prop.Value.(objectEndValue); ok && len(prop.Name) == 0 { 134 break 135 } 136 value = append(value, prop) 137 } 138 139 return 140 } 141 142 // WriteObject . 143 func WriteObject(w io.Writer, obj Object) (err error) { 144 buff := [1]byte{TypeObject} 145 if _, err = w.Write(buff[:]); err != nil { 146 return 147 } 148 149 for _, prop := range obj { 150 if err = writeUtf8(w, prop.Name, 2); err != nil { 151 return 152 } 153 if err = WriteAny(w, prop.Value); err != nil { 154 return 155 } 156 } 157 158 //eof 159 if _, err = w.Write([]byte{0x00, 0x00, TypeObjectEnd}); err != nil { 160 return 161 } 162 163 return 164 } 165 166 // StrictArray 表示 TypeStrictArray 类型存储的值 167 type StrictArray []interface{} 168 169 // ReadStrictArray . 170 func ReadStrictArray(r io.Reader) (value StrictArray, err error) { 171 var buff [1]byte 172 if _, err = io.ReadFull(r, buff[:]); err != nil { 173 return 174 } 175 176 if TypeStrictArray != buff[0] { 177 err = fmt.Errorf("Amf0ReadStrictArray: TypeStrictArray != marker") 178 return 179 } 180 return readStrictArray(r) 181 } 182 183 func readStrictArray(r io.Reader) (value StrictArray, err error) { 184 var buff [4]byte 185 if _, err = io.ReadFull(r, buff[:]); err != nil { 186 return 187 } 188 189 count := int(binary.BigEndian.Uint32(buff[:])) 190 191 for i := 0; i < count; i++ { 192 var elem interface{} 193 elem, err = ReadAny(r) 194 value = append(value, elem) 195 } 196 197 return 198 } 199 200 // WriteStrictArray . 201 func WriteStrictArray(w io.Writer, arr StrictArray) (err error) { 202 var buff [5]byte 203 204 buff[0] = TypeStrictArray 205 binary.BigEndian.PutUint32(buff[1:], uint32(len(arr))) 206 207 for _, elem := range arr { 208 if err = WriteAny(w, elem); err != nil { 209 return 210 } 211 } 212 return 213 }