Parse a string table data blob, returning a list of item updates.
(buf []byte, numUpdates int32, name string, userDataFixed bool, userDataSizeBits int32, flags int32, varintBitCounts bool)
| 184 | |
| 185 | // Parse a string table data blob, returning a list of item updates. |
| 186 | func parseStringTable(buf []byte, numUpdates int32, name string, userDataFixed bool, userDataSizeBits int32, flags int32, varintBitCounts bool) (items []*stringTableItem, err error) { |
| 187 | // Surface a decode failure instead of silently returning a partially |
| 188 | // populated table, matching clarity's fail-loud behaviour. On healthy |
| 189 | // replays this never fires. |
| 190 | defer func() { |
| 191 | if r := recover(); r != nil { |
| 192 | err = _errorf("unable to parse string table %s: %v", name, r) |
| 193 | } |
| 194 | }() |
| 195 | |
| 196 | items = make([]*stringTableItem, 0) |
| 197 | |
| 198 | // Create a reader for the buffer |
| 199 | r := newReader(buf) |
| 200 | |
| 201 | // Start with an index of -1. |
| 202 | // If the first item is at index 0 it will use a incr operation. |
| 203 | index := int32(-1) |
| 204 | |
| 205 | // Maintain a list of key history |
| 206 | keys := make([]string, 0, stringtableKeyHistorySize) |
| 207 | |
| 208 | // Some tables have no data |
| 209 | if len(buf) == 0 { |
| 210 | return items, nil |
| 211 | } |
| 212 | |
| 213 | // Loop through entries in the data structure |
| 214 | // |
| 215 | // Each entry is a tuple consisting of {index, key, value} |
| 216 | // |
| 217 | // Index can either be incremented from the previous position or |
| 218 | // overwritten with a given entry. |
| 219 | // |
| 220 | // Key may be omitted (will be represented here as "") |
| 221 | // |
| 222 | // Value may be omitted |
| 223 | for i := 0; i < int(numUpdates); i++ { |
| 224 | key := "" |
| 225 | value := []byte{} |
| 226 | |
| 227 | // Read a boolean to determine whether the operation is an increment or |
| 228 | // has a fixed index position. A fixed index position of zero should be |
| 229 | // the last data in the buffer, and indicates that all data has been read. |
| 230 | incr := r.readBoolean() |
| 231 | if incr { |
| 232 | index++ |
| 233 | } else { |
| 234 | // The non-increment delta is additive (relative to the running |
| 235 | // index), matching the S2 entity decoder (see entity.go) and |
| 236 | // clarity's S2StringTableEmitter. The previous absolute form |
| 237 | // (= varuint+1) produced wrong, non-monotonic indices for |
| 238 | // delta-updated tables such as ActiveModifiers. |
| 239 | index += int32(r.readVarUint32()) + 2 |
| 240 | } |
| 241 | |
| 242 | // Some values have keys, some don't. |
| 243 | hasKey := r.readBoolean() |