1 module ppc.bundle;
2 import ppc;
3 import ppc.exceptions;
4 import ppc.utils;
5 
6 import std.stdio;
7 import std.conv;
8 import std.bitmanip;
9 
10 
11 public class BundleFactory : ContentFactory {
12 	public this() {
13 		super(TypeId.Bundle);
14 	}
15 
16 	public override Content Construct(ubyte[] data) {
17 		return new Bundle(data);
18 	}
19 }
20 
21 public class Bundle : Content {
22 
23 	public Content[string] BundleContents;
24 
25 	public this(string name) {
26 		super(TypeId.Bundle, name);
27 	}
28 
29 	public this(ubyte[] data) {
30 		super(data);
31 		ulong[] d_lookup = [];
32 		Content[] d_cont = [];
33 
34 		int ulong_size = ulong.sizeof;
35 
36 		// Get lookup table size.
37 		ubyte[ulong.sizeof] s = this.data[0..ulong_size];
38 		ulong d_lookup_len = bigEndianToNative!ulong(s);
39 
40 		// Load lookup table.
41 		for (int i = 0; i < d_lookup_len; i++) {
42 			d_lookup.length++;
43 			writeln(i.text);
44 			ulong start = ulong_size+(ulong_size*i);
45 			s = this.data[start..start+ulong_size];
46 			d_lookup[d_lookup.length-1] = bigEndianToNative!ulong(s);
47 		}
48 
49 		// Iterate through lookup table.
50 		for(int i = 0; i < d_lookup.length; i++) {
51 			// Get read-length.
52 			ulong lookup = d_lookup[i];
53 			ulong n_lookup = data.length;
54 			if (i+1 < d_lookup.length) n_lookup = d_lookup[i+1];
55 
56 			// Read and create content.
57 			d_cont.length++;
58 			d_cont[d_cont.length-1] = ContentManager.Load(this.data[lookup..n_lookup]);
59 		}
60 
61 		// Move over to storage inside bundle.
62 		foreach(Content c; d_cont) {
63 			this.BundleContents[c.Name] = c;
64 		}
65 	}
66 
67 	public void Add(Content cont) {
68 		BundleContents[cont.Name] = cont;
69 	}
70 
71 	public override void Convert(ubyte[] data) {
72 		// Do Nothing, nonconvertible type for now
73 	}
74 
75 	public override ubyte[] Compile() {
76 		ubyte[] d = [];
77 		ubyte[] d_lookup_b = [];
78 		ulong[] d_lookup = [];
79 		ubyte[] d_lookup_t_len = [];
80 
81 		// Compile components.
82 		foreach(Content c; BundleContents) {
83 			
84 			// Add next position to lookup table.
85 			d_lookup.length++;
86 			d_lookup[d_lookup.length-1] = d.length;
87 
88 			// Compile content and add it to data output.
89 			d = Combine(d, c.CompileFull());
90 		}
91 
92 		// Create lookup table
93 		foreach(ulong lookup_id; d_lookup) {
94 			d_lookup_b = Combine(d_lookup_b, nativeToBigEndian(lookup_id));
95 		}
96 
97 		// Create lookup table length.
98 		d_lookup_t_len = nativeToBigEndian(d_lookup_b.length);
99 
100 		// Combine all and push to output.
101 		return Combine(Combine(d_lookup_t_len, d_lookup_b), d);
102 	}
103 }