writeHeader prepares and writes collection metadata including: - Collection size - Type consistency flags - Element type information (if homogeneous and not declared from schema)
(ctx *WriteContext, buf *ByteBuffer, keys []reflect.Value, hasGenerics bool)
| 133 | // - Type consistency flags |
| 134 | // - Element type information (if homogeneous and not declared from schema) |
| 135 | func (s setSerializer) writeHeader(ctx *WriteContext, buf *ByteBuffer, keys []reflect.Value, hasGenerics bool) (byte, *TypeInfo) { |
| 136 | // Initialize collection flags and type tracking variables |
| 137 | collectFlag := CollectionDefaultFlag |
| 138 | var elemTypeInfo *TypeInfo |
| 139 | hasNull := false |
| 140 | hasSameType := true |
| 141 | declaredGenerics := hasGenerics && s.elemSerializer != nil |
| 142 | |
| 143 | // Check elements to detect types |
| 144 | // Initialize element type information from first non-null element |
| 145 | if len(keys) > 0 { |
| 146 | firstElem := UnwrapReflectValue(keys[0]) |
| 147 | if isNull(firstElem) { |
| 148 | hasNull = true |
| 149 | } else { |
| 150 | // Get type info for first element to use as reference |
| 151 | elemTypeInfo, _ = ctx.TypeResolver().getTypeInfo(firstElem, true) |
| 152 | if declaredGenerics && elemTypeInfo != nil && !needsElemTypeInfo(TypeId(elemTypeInfo.TypeID)) { |
| 153 | elemTypeInfo = &TypeInfo{Type: firstElem.Type(), Serializer: s.elemSerializer} |
| 154 | } |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | // Iterate through elements to check for nulls and type consistency |
| 159 | for _, key := range keys { |
| 160 | key = UnwrapReflectValue(key) |
| 161 | if isNull(key) { |
| 162 | hasNull = true |
| 163 | continue |
| 164 | } |
| 165 | |
| 166 | // Compare each element's type with the reference type |
| 167 | if declaredGenerics { |
| 168 | continue |
| 169 | } |
| 170 | currentTypeInfo, _ := ctx.TypeResolver().getTypeInfo(key, true) |
| 171 | var elemTypeID, currentTypeID uint32 |
| 172 | if elemTypeInfo != nil { |
| 173 | elemTypeID = elemTypeInfo.TypeID |
| 174 | } |
| 175 | if currentTypeInfo != nil { |
| 176 | currentTypeID = currentTypeInfo.TypeID |
| 177 | } |
| 178 | if currentTypeID != elemTypeID { |
| 179 | hasSameType = false |
| 180 | } |
| 181 | } |
| 182 | |
| 183 | // Set collection flags based on findings |
| 184 | if hasNull { |
| 185 | collectFlag |= CollectionHasNull // Mark if collection contains null values |
| 186 | } |
| 187 | if hasSameType { |
| 188 | collectFlag |= CollectionIsSameType // Mark if elements have same type |
| 189 | } |
| 190 | // When hasGenerics is true, element type is declared from schema (known at compile time) |
| 191 | // so we don't need to write the element type ID |
| 192 | if declaredGenerics && elemTypeInfo != nil && needsElemTypeInfo(TypeId(elemTypeInfo.TypeID)) { |
no test coverage detected