Merge branch 'master' of ssh://git.code.sf.net/p/feistymeow/trunk into dev
[feisty_meow.git] / nucleus / applications / bundler / common_bundle.h
1 #ifndef COMMON_BUNDLER_DEFS
2 #define COMMON_BUNDLER_DEFS
3
4 /*****************************************************************************\
5 *                                                                             *
6 *  Name   : common bundler definitions                                        *
7 *  Author : Chris Koeritz                                                     *
8 *                                                                             *
9 *******************************************************************************
10 * Copyright (c) 2007-$now By Author.  This program is free software; you can  *
11 * redistribute it and/or modify it under the terms of the GNU General Public  *
12 * License as published by the Free Software Foundation; either version 2 of   *
13 * the License or (at your option) any later version.  This is online at:      *
14 *     http://www.fsf.org/copyleft/gpl.html                                    *
15 * Please send any updates to: fred@gruntose.com                               *
16 \*****************************************************************************/
17
18 //! Contains some definitions used by both the bundle creator and unpacker.
19 /*!
20   Note that this is a heavyweight header and should not be pulled into
21   other headers.
22 */
23
24 #include <basis/astring.h>
25 #include <basis/contracts.h>
26 #include <filesystem/byte_filer.h>
27 #include <structures/set.h>
28
29 ////////////////////////////////////////////////////////////////////////////
30
31 //! flags that control special attributes of the packed files.
32 enum special_bundling_flags {
33   SOURCE_EXECUTE = 0x2,  //!< the file should be executed before bundling.
34   TARGET_EXECUTE = 0x4,  //!< the file should be executed on unbundling.
35   RECURSIVE_SRC = 0x8,  //!< source is a recursive folder.
36   OMIT_PACKING = 0x10,  //!< for a source side exe, do not pack the file.
37   SET_VARIABLE = 0x20,  //!< this item just has a variable assignment.
38   IGNORE_ERRORS = 0x40,  //!< if set, errors in an item will not stop program.
39   NO_OVERWRITE = 0x80,  //!< target file will not be overwritten if exists.
40   QUIET_FAILURE = 0x100,  //!< when errors happen, no popup message happens.
41   MAKE_BACKUP_FILE = 0x200,  //!< save a copy if original file already exists.
42   TEST_VARIABLE_DEFINED = 0x400  //!< check for required variable's presence.
43 };
44
45 ////////////////////////////////////////////////////////////////////////////
46
47 //! we will read the manifest pieces out of our own exe image.
48 /*!
49   the manifest chunks provide us with enough information to unpack the
50   data chunks that come afterward.
51 */
52
53 struct manifest_chunk : public basis::text_formable
54 {
55   basis::un_int _size;  //!< the size of the packed file.
56   basis::astring _payload;  //!< guts of the chunk, such as location for file on target or a variable definition.
57   basis::un_int _flags;  //!< uses the special_bundling_flags.
58   basis::astring _parms;  //!< the parameters to pass on the command line.
59   structures::string_set _keywords;  //!< keywords applicable to this item.
60   basis::byte_array c_filetime;  //!< more than enough room for unix file time.
61
62   // note: when flags has SET_VARIABLE, the _payload is the variable
63   // name to be set and the _parms is the value to use.
64
65   static int packed_filetime_size();
66
67   //! the chunk is the unit found in the packing manifest in the bundle.
68   manifest_chunk(int size, const basis::astring &target, int flags,
69       const basis::astring &parms, const structures::string_set &keywords)
70       : _size(size), _payload(target), _flags(flags), _parms(parms),
71         _keywords(keywords), c_filetime(packed_filetime_size()) {
72     for (int i = 0; i < packed_filetime_size(); i++) c_filetime[i] = 0;
73   }
74
75   manifest_chunk() : _size(0), _flags(0), c_filetime(packed_filetime_size()) {
76     //!< default constructor.
77     for (int i = 0; i < packed_filetime_size(); i++) c_filetime[i] = 0;
78   }
79
80   virtual ~manifest_chunk();
81
82   virtual void text_form(basis::base_string &state_fill) const {
83     state_fill.assign(basis::astring(class_name())
84         + basis::a_sprintf(": size=%d payload=%s flags=%x parms=%s",
85               _size, _payload.s(), _flags, _parms.s()));
86   }
87
88   DEFINE_CLASS_NAME("manifest_chunk");
89
90   void pack(basis::byte_array &target) const;  //!< streams out into the "target".
91   bool unpack(basis::byte_array &source);  //!< streams in from the "source".
92
93   static bool read_manifest(filesystem::byte_filer &bundle, manifest_chunk &to_fill);
94     //!< reads a chunk out of the "bundle" and stores it in "to_fill".
95     /*!< false is returned if the read failed. */
96
97   static basis::astring read_a_string(filesystem::byte_filer &bundle);
98     //!< reads a string from the "bundle" file, one byte at a time.
99
100   static bool read_an_int(filesystem::byte_filer &bundle, basis::un_int &found);
101     //!< reads an integer (4 bytes) from the file into "found".
102
103   static bool read_an_obscured_int(filesystem::byte_filer &bundle, basis::un_int &found);
104     //!< reads in our obscured packing format for an int, which takes 8 bytes.
105
106   static bool read_a_filetime(filesystem::byte_filer &bundle, basis::byte_array &found);
107     //!< retrieves packed_filetime_size() byte timestamp from the "bundle".
108 };
109
110 ////////////////////////////////////////////////////////////////////////////
111
112 #endif
113