1 /*****************************************************************************\
3 * Name : common bundler definitions *
4 * Author : Chris Koeritz *
6 *******************************************************************************
7 * Copyright (c) 2007-$now By Author. This program is free software; you can *
8 * redistribute it and/or modify it under the terms of the GNU General Public *
9 * License as published by the Free Software Foundation; either version 2 of *
10 * the License or (at your option) any later version. This is online at: *
11 * http://www.fsf.org/copyleft/gpl.html *
12 * Please send any updates to: fred@gruntose.com *
13 \*****************************************************************************/
15 #include "common_bundle.h"
17 #include <basis/byte_array.h>
18 #include <basis/contracts.h>
19 #include <filesystem/byte_filer.h>
20 #include <filesystem/file_time.h>
21 #include <structures/object_packers.h>
22 #include <structures/set.h>
24 using namespace basis;
25 using namespace filesystem;
26 using namespace structures;
28 manifest_chunk::~manifest_chunk()
31 int manifest_chunk::packed_filetime_size()
33 static file_time hidden_comparison_object;
34 return hidden_comparison_object.packed_size();
37 void manifest_chunk::pack(byte_array &target) const
39 structures::obscure_attach(target, _size);
40 _payload.pack(target);
41 structures::attach(target, _flags);
43 _keywords.pack(target);
47 bool manifest_chunk::unpack(byte_array &source)
49 if (!structures::obscure_detach(source, _size)) return false;
50 if (!_payload.unpack(source)) return false;
51 if (!structures::detach(source, _flags)) return false;
52 if (!_parms.unpack(source)) return false;
53 if (!_keywords.unpack(source)) return false;
54 if (source.length() < 8) return false;
55 c_filetime = source.subarray(0, 7);
60 bool manifest_chunk::read_an_int(byte_filer &bundle, un_int &found)
62 FUNCDEF("read_an_int");
64 if (bundle.read(temp, sizeof(int)) != sizeof(int)) return false;
65 if (!structures::detach(temp, found)) return false;
69 bool manifest_chunk::read_an_obscured_int(byte_filer &bundle, un_int &found)
71 FUNCDEF("read_an_obscured_int");
73 if (bundle.read(temp, 2 * sizeof(int)) != 2 * sizeof(int)) return false;
74 if (!structures::obscure_detach(temp, found)) return false;
78 bool manifest_chunk::read_a_filetime(byte_filer &bundle, byte_array &found)
80 FUNCDEF("read_a_filetime");
82 // the trick below only works because we know we have a constant sized packed version
84 if (bundle.read(temp, packed_filetime_size()) != packed_filetime_size()) return false;
89 astring manifest_chunk::read_a_string(byte_filer &bundle)
91 FUNCDEF("read_a_string");
94 // read in the zero-terminated character string.
95 while (!bundle.eof()) {
96 // read a single byte out of the file.
97 if (bundle.read(temp, 1) <= 0)
100 // add the byte to the string we're accumulating.
103 // this string is done now.
110 bool manifest_chunk::read_manifest(byte_filer &bundle, manifest_chunk &curr)
113 bool worked = read_an_obscured_int(bundle, curr._size);
117 curr._payload = read_a_string(bundle);
118 if (!curr._payload) return false;
119 worked = read_an_int(bundle, curr._flags);
122 curr._parms = read_a_string(bundle);
123 // it's valid for the _parms to be empty.
124 //if (curr._parms.length()) { printf("parms len=%d are: \"%s\"\n", curr._parms.length(), curr._parms.s()); }
125 // now get the keywords list, if it exists.
126 un_int key_elems = 0; // number of keywords.
127 worked = read_an_obscured_int(bundle, key_elems); // get number of elements.
130 curr._keywords.reset();
131 for (int i = 0; i < (int)key_elems; i++) {
132 astring found = read_a_string(bundle);
133 if (!found) return false; // not allowed an empty keyword.
134 curr._keywords += found;
136 worked = read_a_filetime(bundle, curr.c_filetime);