v2 / vlib / v / embed_file / embed_file.v
103 lines · 95 sloc · 2.88 KB · 7d57a19d7e4924b0da97185fefb4191e677d2639
Raw
1module embed_file
2
3// EmbedFileData encapsulates functionality for the `$embed_file()` compile time call.
4pub struct EmbedFileData {
5 apath string
6 compression_type string
7mut:
8 compressed &u8 = unsafe { nil }
9 uncompressed &u8 = unsafe { nil }
10 free_compressed bool
11 free_uncompressed bool
12pub:
13 len int
14 path string
15}
16
17pub fn (ed EmbedFileData) str() string {
18 return 'embed_file.EmbedFileData{ len: ${ed.len}, path: "${ed.path}", apath: "${ed.apath}", uncompressed: ${ptr_str(ed.uncompressed)} }'
19}
20
21@[unsafe]
22pub fn (mut ed EmbedFileData) free() {
23 unsafe {
24 ed.path.free()
25 ed.apath.free()
26 ed.compression_type.free()
27 if ed.free_compressed {
28 free(ed.compressed)
29 ed.compressed = &u8(nil)
30 }
31 if ed.free_uncompressed {
32 free(ed.uncompressed)
33 ed.uncompressed = &u8(nil)
34 }
35 }
36}
37
38pub fn (original &EmbedFileData) to_string() string {
39 unsafe {
40 mut ed := &EmbedFileData(original)
41 the_copy := &u8(memdup(ed.data(), ed.len))
42 return the_copy.vstring_with_len(ed.len)
43 }
44}
45
46pub fn (original &EmbedFileData) to_bytes() []u8 {
47 unsafe {
48 mut ed := &EmbedFileData(original)
49 the_copy := memdup(ed.data(), ed.len)
50 return the_copy.vbytes(ed.len)
51 }
52}
53
54pub fn (mut ed EmbedFileData) data() &u8 {
55 if ed.uncompressed != unsafe { nil } {
56 return ed.uncompressed
57 }
58 if ed.uncompressed == unsafe { nil } && ed.compressed != unsafe { nil } {
59 decoder := g_embed_file_decoders.decoders[ed.compression_type] or {
60 panic('EmbedFileData error: unknown compression of "${ed.path}": "${ed.compression_type}"')
61 }
62 compressed := unsafe { ed.compressed.vbytes(ed.len) }
63 decompressed := decoder.decompress(compressed) or {
64 panic('EmbedFileData error: decompression of "${ed.path}" failed: ${err}')
65 }
66 unsafe {
67 ed.uncompressed = &u8(memdup(decompressed.data, ed.len))
68 }
69 } else {
70 $if !freestanding {
71 reload_from_file_at_runtime(mut ed)
72 }
73 }
74 return ed.uncompressed
75}
76
77//////////////////////////////////////////////////////////////////////////////
78// EmbedFileIndexEntry is used internally by the V compiler when you compile a
79// program that uses $embed_file('file.bin') in -prod mode.
80// V will generate a static index of all embedded files, and will call the
81// find_index_entry_by_path over the index and the relative paths of the embeds.
82// Note: these are public on purpose, to help -usecache.
83pub struct EmbedFileIndexEntry {
84 id int
85 path string
86 algo string
87 data &u8 = unsafe { nil }
88}
89
90// find_index_entry_by_path is used internally by the V compiler:
91@[markused]
92pub fn find_index_entry_by_path(start voidptr, path string, algo string) &EmbedFileIndexEntry {
93 unsafe {
94 mut x := &EmbedFileIndexEntry(start)
95 for x.id >= 0 && x.data != 0 && (x.algo != algo || x.path != path) {
96 x++
97 }
98 $if trace_embed_file ? {
99 eprintln('>> v.embed_file find_index_entry_by_path ${ptr_str(start)}, id: ${x.id}, path: "${path}", algo: "${algo}" => ${ptr_str(x)}')
100 }
101 return x
102 }
103}
104