UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
syms_msf_parser.c
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#ifndef SYMS_MSF_PARSER_C
4#define SYMS_MSF_PARSER_C
5
7//~ allen: MSF Reader Fundamentals Without Accelerator
8
11 void *base = data.str;
12 SYMS_U64Range range = syms_make_u64_range(0, data.size);
13
14 // determine msf type
15 SYMS_U32 index_size = 0;
19 index_size = 2;
20 }
21 else if (syms_based_range_read(base, range, 0, SYMS_MSF70_MAGIC_SIZE, magic_buffer) &&
23 index_size = 4;
24 }
25
26 // grab parts of header we will use in syms
27 SYMS_MsfHeaderInfo result = {0};
28
29 if (index_size == 2){
30 SYMS_MsfHeader20 header = {0};
31 if (syms_based_range_read_struct(base, range, SYMS_MSF20_MAGIC_SIZE, &header)){
32 result.index_size = index_size;
33 result.block_size = header.block_size;
34 result.block_count = header.block_count;
35 result.directory_size = header.directory_size;
36 }
37 }
38 else if (index_size == 4){
39 SYMS_MsfHeader70 header = {0};
40 if (syms_based_range_read_struct(base, range, SYMS_MSF70_MAGIC_SIZE, &header)){
41 result.index_size = index_size;
42 result.block_size = header.block_size;
43 result.block_count = header.block_count;
44 result.directory_size = header.directory_size;
46 }
47 }
48
49 return(result);
50}
51
53//~ allen: MSF Reader Accelerator Constructor
54
57 // NOTE(allen): Layout of directory
58 //
59 // PDB20:
60 // struct Pdb20StreamSize{
61 // U32 size;
62 // U32 unknown; // looks like kind codes or revision counters or something
63 // }
64 // struct{
65 // U32 stream_count;
66 // Pdb20StreamSize stream_sizes[stream_count];
67 // U16 stream_indices[stream_count][...];
68 // }
69 //
70 // PDB70:
71 // struct{
72 // U32 stream_count;
73 // U32 stream_sizes[stream_count];
74 // U32 stream_indices[stream_count][...];
75 // }
76
77 //- setup result
78 SYMS_MsfAccel *result = 0;
79
80 //- header
82 if (header.index_size > 0){
83
84 //- directory
86 SYMS_U8 *directory = 0;
87 {
88 SYMS_U32 directory_size = header.directory_size;
89 directory = syms_push_array(arena, SYMS_U8, directory_size);
90
91 // setup important sizes and counts
93
94 SYMS_U64 file_size = data.size;
95 SYMS_U32 block_size = SYMS_ClampTop(header.block_size, file_size);
96
97 SYMS_U32 block_count_in_directory = SYMS_CeilIntegerDiv(directory_size, block_size);
99
101
104
105 // setup the index blocks
107 SYMS_U32 *directory_super_map = 0;
109
110 if (size_of_block_index == 2){
111 directory_super_map = &directory_super_map_dummy;
113 }
114 else{
116 directory_super_map = (SYMS_U32*)(data.str + super_map_off);
117 }
118
120
121 // super map: [s1, s2, s3, ...]
122 // map: s1 -> [i1, i2, i3, ...]; s2 -> [...]; s3 -> [...]; ...
123 // directory: i1 -> [data]; i2 -> [data]; i3 -> [data]; ... i1 -> [data]; ...
124
125 // for each index in super map ...
127 SYMS_U32 *super_map_ptr = directory_super_map;
128 for (SYMS_U32 i = 0;
130 i += 1, super_map_ptr += 1){
133 // TODO(allen): File Defect: (Block Index, In Super Directory, Too Large)
136 }
137
140
141 // clamp index count by end of directory
143 {
145 SYMS_U32 remaining_size = directory_size - directory_pos;
148 }
149
150 // for each index in map ...
152 for (SYMS_U32 j = 0;
153 j < index_count;
154 j += 1, map_ptr += size_of_block_index){
158 // TODO(allen): File Defect: (Block Index, In Directory, Too Large)
161 }
162
165
166 // clamp copy size by end of directory
168 {
170 SYMS_U32 remaining_size = directory_size - directory_pos;
172 }
173
174 // copy block data
177 }
178 }
179
181 }
183
184 //- stream info
185 SYMS_U32 stream_count = 0;
186 SYMS_MsfAccelStreamInfo *stream_info = 0;
187 {
188 // read count
189 syms_based_range_read(directory, directory_range, 0, 4, &stream_count);
190
191 // allocate info array
192 stream_info = syms_push_array_zero(arena, SYMS_MsfAccelStreamInfo, stream_count);
193
194 // setup counts, sizes, and offsets for the directory data
195 SYMS_U32 block_size = header.block_size;
198 if (size_of_block_index == 2){
200 }
203
204 // iterate sizes and indices in lock step
208 for (SYMS_U32 i = 0; i < stream_count; i += 1){
209 // read stream size
212 if (stream_size == 0xffffffff){
213 stream_size = 0;
214 }
215
216 // compute block count
218
219 // save stream info
220 stream_info_ptr->stream_indices = directory + index_cursor;
222
223 // advance cursors
226 stream_info_ptr += 1;
227 }
228 }
229
230 // fill result
231 result = syms_push_array(arena, SYMS_MsfAccel, 1);
232 result->header = header;
233 result->stream_count = stream_count;
234 result->stream_info = stream_info;
235 }
236
237 return(result);
238}
239
242 SYMS_ProfBegin("syms_msf_deep_copy");
243 SYMS_MsfAccel *result = syms_push_array(arena, SYMS_MsfAccel, 1);
244 syms_memmove(result, msf, sizeof(*result));
247 SYMS_ProfEnd();
248 return(result);
249}
250
253 // setup header data
254 SYMS_MsfHeaderInfo header = {0};
255 header.index_size = 4;
256 header.block_size = data.size;
257 header.block_count = 1;
258 header.directory_size = 0;
259 header.directory_super_map = 0;
260
261 // setup stream info
263 stream_info->stream_indices = syms_push_array_zero(arena, SYMS_U8, 4);
264 stream_info->size = data.size;
265
266 // fill result
267 SYMS_MsfAccel *result = syms_push_array(arena, SYMS_MsfAccel, 1);
268 result->header = header;
269 result->stream_count = 1;
270 result->stream_info = stream_info;
271
272 return(result);
273}
274
275
277//~ allen: MSF Reader Fundamentals With Accelerator
278
283
288
291 // scan for stream in directory
292 SYMS_MsfStreamInfo result = {0};
293 if (sn < msf->stream_count){
295 result.sn = sn;
296 result.stream_indices = accel_stream_info->stream_indices;
297 result.size = accel_stream_info->size;
298 }
299 return(result);
300}
301
304 SYMS_B32 result = syms_false;
306 if (off <= stream_info.size){
307 result = syms_true;
308 }
309 return(result);
310}
311
314 SYMS_MsfStreamNumber sn, SYMS_U32 off, SYMS_U32 size, void *out){
315 SYMS_B32 result = syms_false;
316
317 // stream info
319 if (size > 0 && off + size <= stream_info.size){
320 // copy block-by-block
321 SYMS_U64 file_size = data.size;
322 SYMS_U32 block_size = msf->header.block_size;
327
329 for (;;){
330 // offset-in-stream -> part-index
334
335 // part-index -> block-index
340 // TODO(allen): File Defect: (Block Index, In Stream, Too Large)
341 break;
342 }
343
344 // block-index -> range-in-file
350
351 // copy & advance
354 if (completed_amount >= size){
355 result = syms_true;
356 break;
357 }
358 }
359 }
360
361 return(result);
362}
363
366 SYMS_MsfRange result = {sn, off, len};
367 return(result);
368}
369
373 SYMS_MsfRange result = {0};
374 if (info.size != 0){
375 result.sn = info.sn;
376 result.size = info.size;
377 }
378 return(result);
379}
380
383 SYMS_MsfRange result = {0};
384 if (off + size <= range.size){
385 result.sn = range.sn;
386 result.off = range.off + off;
387 result.size = size;
388 }
389 return(result);
390}
391
397
399//~ allen: MSF Reader Range Helper Functions
400
403 SYMS_B32 result = (off <= range.size);
404 return(result);
405}
406
409 SYMS_U32 off, SYMS_U32 size, void *out){
410 SYMS_B32 result = syms_false;
411 if (off + size <= range.size){
412 result = syms_msf_read(data, msf, range.sn, range.off + off, size, out);
413 }
414 return(result);
415}
416
419 SYMS_String8 result = {0};
420 result.str = syms_push_array(arena, SYMS_U8, range.size);
421 result.size = range.size;
422 syms_msf_read(data, msf, range.sn, range.off, range.size, result.str);
423 return(result);
424}
425
430
431 // build a list of string chunks on scratch
433
434 SYMS_U32 off = range.off + r_off;
435 SYMS_U32 max_off = range.off + range.size;
436
437 SYMS_MsfStreamInfo stream_info = syms_msf_stream_info_from_sn(msf, range.sn);
438 if (off < stream_info.size && off < max_off){
439 // scan block-by-block
440 SYMS_U64 file_size = data.size;
441 SYMS_U32 block_size = msf->header.block_size;
445 SYMS_U32 block_count_in_stream = SYMS_CeilIntegerDiv(stream_info.size, block_size);
446
449 for (;;){
450 // offset-in-stream -> part-index
454 break;
455 }
456
457 // part-index -> block-index
462 // TODO(allen): File Defect: (Block Index, In Stream, Too Large)
463 break;
464 }
466 // TODO(allen): Detected defect in the file data.
467 // (Block Index, In Stream, Too Large)
468 break;
469 }
470
471 // block-index -> range-in-file
476 SYMS_ASSERT(src_block_base + block_size <= file_size);
477
478 // scan
479 SYMS_U8 *start = data.str + src_block_base + relative_off;
480 SYMS_U8 *opl = start + relative_opl - relative_off;
481 SYMS_U8 *ptr = start;
482 for (;ptr < opl && *ptr != 0; ptr += 1);
483 scanned_amount += (SYMS_U64)(ptr - start);
484
485 // emit chunk
486 if (start < ptr){
489 }
490
491 // check end of scan conditions
492 if (ptr < opl){
493 break;
494 }
496 break;
497 }
498 }
499 }
500
501
502 // join into single string
503 SYMS_String8 result = syms_string_list_join(arena, &list, 0);
505 return(result);
506}
507
508#endif //SYMS_MSF_PARSER_C
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Definition syms_base.h:402
Definition syms_msf_parser.h:33
SYMS_U8 * stream_indices
Definition syms_msf_parser.h:34
SYMS_U32 size
Definition syms_msf_parser.h:35
Definition syms_msf_parser.h:38
SYMS_MsfHeaderInfo header
Definition syms_msf_parser.h:39
SYMS_MsfAccelStreamInfo * stream_info
Definition syms_msf_parser.h:41
SYMS_U32 stream_count
Definition syms_msf_parser.h:40
Definition syms_msf.h:20
SYMS_U16 block_count
Definition syms_msf.h:23
SYMS_U32 block_size
Definition syms_msf.h:21
SYMS_U32 directory_size
Definition syms_msf.h:24
Definition syms_msf.h:29
SYMS_U32 block_size
Definition syms_msf.h:30
SYMS_U32 block_count
Definition syms_msf.h:32
SYMS_U32 directory_super_map
Definition syms_msf.h:35
SYMS_U32 directory_size
Definition syms_msf.h:33
Definition syms_msf_parser.h:10
SYMS_U32 block_count
Definition syms_msf_parser.h:13
SYMS_U32 directory_super_map
Definition syms_msf_parser.h:15
SYMS_U32 directory_size
Definition syms_msf_parser.h:14
SYMS_U32 block_size
Definition syms_msf_parser.h:12
SYMS_U32 index_size
Definition syms_msf_parser.h:11
Definition syms_msf_parser.h:24
SYMS_MsfStreamNumber sn
Definition syms_msf_parser.h:25
SYMS_U32 off
Definition syms_msf_parser.h:26
SYMS_U32 size
Definition syms_msf_parser.h:27
Definition syms_msf_parser.h:18
SYMS_U32 size
Definition syms_msf_parser.h:21
SYMS_MsfStreamNumber sn
Definition syms_msf_parser.h:19
SYMS_U8 * stream_indices
Definition syms_msf_parser.h:20
Definition syms_base.h:306
Definition syms_base.h:296
SYMS_U8 * str
Definition syms_base.h:297
SYMS_U64 size
Definition syms_base.h:298
Definition syms_base.h:259
Definition syms_base.h:264
SYMS_API SYMS_U64 syms_based_range_read(void *base, SYMS_U64Range range, SYMS_U64 offset, SYMS_U64 out_size, void *out)
Definition syms_base.c:753
SYMS_API SYMS_String8 syms_string_list_join(SYMS_Arena *arena, SYMS_String8List *list, SYMS_StringJoin *join_ptr)
Definition syms_base.c:315
SYMS_API SYMS_String8 syms_str8_range(SYMS_U8 *first, SYMS_U8 *opl)
Definition syms_base.c:184
SYMS_API SYMS_ArenaTemp syms_get_scratch(SYMS_Arena **conflicts, SYMS_U64 conflict_count)
Definition syms_base.c:694
SYMS_API SYMS_U64Range syms_make_u64_range(SYMS_U64 min, SYMS_U64 max)
Definition syms_base.c:18
SYMS_API void syms_string_list_push(SYMS_Arena *arena, SYMS_String8List *list, SYMS_String8 string)
Definition syms_base.c:282
#define syms_true
Definition syms_base.h:105
#define syms_based_range_read_struct(b, r, o, p)
Definition syms_base.h:593
#define syms_push_array(a, T, c)
Definition syms_base.h:561
#define SYMS_ClampTop(a, b)
Definition syms_base.h:182
#define SYMS_CeilIntegerDiv(a, b)
Definition syms_base.h:185
#define SYMS_MEMBER_OFFSET(type, member)
Definition syms_base.h:149
#define syms_false
Definition syms_base.h:104
#define SYMS_API
Definition syms_base.h:29
#define SYMS_ASSERT(x)
Definition syms_base.h:125
SYMS_S32 SYMS_B32
Definition syms_base.h:99
#define syms_push_array_zero(a, T, c)
Definition syms_base.h:564
#define syms_release_scratch
Definition syms_base.h:567
uint32_t SYMS_U32
Definition syms_crt_overrides.h:38
uint64_t SYMS_U64
Definition syms_crt_overrides.h:39
#define syms_memmove
Definition syms_crt_overrides.h:65
#define syms_memcmp
Definition syms_crt_overrides.h:67
#define SYMS_U64
Definition syms_crt_overrides.h:54
#define SYMS_U32
Definition syms_crt_overrides.h:53
uint8_t SYMS_U8
Definition syms_crt_overrides.h:36
#define SYMS_Arena
Definition syms_default_arena.h:61
#define SYMS_ProfEnd()
Definition syms_dev.h:212
#define SYMS_ProfBegin(str)
Definition syms_dev.h:209
SYMS_READ_ONLY SYMS_GLOBAL char syms_msf20_magic[]
Definition syms_msf.h:13
#define SYMS_MSF_MAX_MAGIC_SIZE
Definition syms_msf.h:18
#define SYMS_MSF20_MAGIC_SIZE
Definition syms_msf.h:16
SYMS_READ_ONLY SYMS_GLOBAL char syms_msf70_magic[]
Definition syms_msf.h:14
SYMS_U16 SYMS_MsfStreamNumber
Definition syms_msf.h:11
#define SYMS_MSF70_MAGIC_SIZE
Definition syms_msf.h:17
SYMS_API SYMS_String8 syms_msf_read_whole_range(SYMS_Arena *arena, SYMS_String8 data, SYMS_MsfAccel *msf, SYMS_MsfRange range)
Definition syms_msf_parser.c:418
SYMS_API SYMS_MsfAccel * syms_msf_deep_copy(SYMS_Arena *arena, SYMS_MsfAccel *msf)
Definition syms_msf_parser.c:241
SYMS_API SYMS_MsfRange syms_msf_range_from_sn(SYMS_MsfAccel *msf, SYMS_MsfStreamNumber sn)
Definition syms_msf_parser.c:371
SYMS_API SYMS_B32 syms_msf_bounds_check_in_range(SYMS_MsfRange range, SYMS_U32 off)
Definition syms_msf_parser.c:402
SYMS_API SYMS_B32 syms_msf_read_in_range(SYMS_String8 data, SYMS_MsfAccel *msf, SYMS_MsfRange range, SYMS_U32 off, SYMS_U32 size, void *out)
Definition syms_msf_parser.c:408
SYMS_API SYMS_MsfHeaderInfo syms_msf_header_info_from_data_slow(SYMS_String8 data)
Definition syms_msf_parser.c:10
SYMS_API SYMS_MsfRange syms_msf_sub_range_from_off_range(SYMS_MsfRange range, SYMS_U32Range off_range)
Definition syms_msf_parser.c:393
SYMS_API SYMS_B32 syms_msf_bounds_check(SYMS_MsfAccel *msf, SYMS_MsfStreamNumber sn, SYMS_U32 off)
Definition syms_msf_parser.c:303
SYMS_API SYMS_MsfStreamInfo syms_msf_stream_info_from_sn(SYMS_MsfAccel *msf, SYMS_MsfStreamNumber sn)
Definition syms_msf_parser.c:290
SYMS_API SYMS_MsfRange syms_msf_make_range(SYMS_MsfStreamNumber sn, SYMS_U32 off, SYMS_U32 len)
Definition syms_msf_parser.c:365
SYMS_API SYMS_MsfRange syms_msf_sub_range(SYMS_MsfRange range, SYMS_U32 off, SYMS_U32 size)
Definition syms_msf_parser.c:382
SYMS_API SYMS_B32 syms_msf_read(SYMS_String8 data, SYMS_MsfAccel *msf, SYMS_MsfStreamNumber sn, SYMS_U32 off, SYMS_U32 size, void *out)
Definition syms_msf_parser.c:313
SYMS_API SYMS_MsfAccel * syms_msf_accel_dummy_from_raw_data(SYMS_Arena *arena, SYMS_String8 data)
Definition syms_msf_parser.c:252
SYMS_API SYMS_U32 syms_msf_get_stream_count(SYMS_MsfAccel *msf)
Definition syms_msf_parser.c:285
SYMS_API SYMS_MsfAccel * syms_msf_accel_from_data(SYMS_Arena *arena, SYMS_String8 data)
Definition syms_msf_parser.c:56
SYMS_API SYMS_MsfHeaderInfo syms_msf_header_info_from_msf(SYMS_MsfAccel *msf)
Definition syms_msf_parser.c:280
SYMS_API SYMS_String8 syms_msf_read_zstring_in_range(SYMS_Arena *arena, SYMS_String8 data, SYMS_MsfAccel *msf, SYMS_MsfRange range, SYMS_U32 r_off)
Definition syms_msf_parser.c:427