feisty meow concerns codebase  2.140
common_bundle.cpp
Go to the documentation of this file.
1 /*****************************************************************************\
2 * *
3 * Name : common bundler definitions *
4 * Author : Chris Koeritz *
5 * *
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 \*****************************************************************************/
14 
15 #include "common_bundle.h"
16 
17 #include <basis/byte_array.h>
18 #include <basis/contracts.h>
19 #include <filesystem/byte_filer.h>
20 #include <filesystem/file_time.h>
22 #include <structures/set.h>
23 
24 using namespace basis;
25 using namespace filesystem;
26 using namespace structures;
27 
29 {}
30 
32 {
33  static file_time hidden_comparison_object;
34  return hidden_comparison_object.packed_size();
35 }
36 
37 void manifest_chunk::pack(byte_array &target) const
38 {
39  structures::obscure_attach(target, _size);
40  _payload.pack(target);
41  structures::attach(target, _flags);
42  _parms.pack(target);
43  _keywords.pack(target);
44  target += c_filetime;
45 }
46 
48 {
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);
56  source.zap(0, 7);
57  return true;
58 }
59 
61 {
62  FUNCDEF("read_an_int");
63  byte_array temp;
64  if (bundle.read(temp, sizeof(int)) != sizeof(int)) return false;
65  if (!structures::detach(temp, found)) return false;
66  return true;
67 }
68 
70 {
71  FUNCDEF("read_an_obscured_int");
72  byte_array temp;
73  if (bundle.read(temp, 2 * sizeof(int)) != 2 * sizeof(int)) return false;
74  if (!structures::obscure_detach(temp, found)) return false;
75  return true;
76 }
77 
79 {
80  FUNCDEF("read_a_filetime");
81  byte_array temp;
82  // the trick below only works because we know we have a constant sized packed version
83  // for the file time.
84  if (bundle.read(temp, packed_filetime_size()) != packed_filetime_size()) return false;
85  found = temp;
86  return true;
87 }
88 
90 {
91  FUNCDEF("read_a_string");
92  astring found;
93  byte_array temp;
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)
98  break;
99  if (temp[0]) {
100  // add the byte to the string we're accumulating.
101  found += temp[0];
102  } else {
103  // this string is done now.
104  break;
105  }
106  }
107  return found;
108 }
109 
111 {
112  curr._size = 0;
113  bool worked = read_an_obscured_int(bundle, curr._size);
114  if (!worked)
115  return false;
116  byte_array temp;
117  curr._payload = read_a_string(bundle);
118  if (!curr._payload) return false;
119  worked = read_an_int(bundle, curr._flags);
120  if (!worked)
121  return false;
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.
128  if (!worked)
129  return false;
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;
135  }
136  worked = read_a_filetime(bundle, curr.c_filetime);
137  return worked;
138 }
139 
void reset(int number=0, const contents *initial_contents=NULL_POINTER)
Resizes this array and sets the contents from an array of contents.
Definition: array.h:349
array subarray(int start, int end) const
Returns the array segment between the indices "start" and "end".
Definition: array.h:443
int length() const
Returns the current reported length of the allocated C array.
Definition: array.h:115
outcome zap(int start, int end)
Deletes from "this" the objects inclusively between "start" and "end".
Definition: array.h:769
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
A very common template for a dynamic array of bytes.
Definition: byte_array.h:36
Provides file managment services using the standard I/O support.
Definition: byte_filer.h:32
int read(basis::abyte *buffer, int buffer_size)
reads "buffer_size" bytes from the file into "buffer".
Definition: byte_filer.cpp:123
bool eof()
returns true if the cursor is at (or after) the end of the file.
Definition: byte_filer.cpp:121
virtual int packed_size() const
Definition: file_time.cpp:132
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition: enhance_cpp.h:57
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
unsigned int un_int
Abbreviated name for unsigned integers.
Definition: definitions.h:62
A platform independent way to obtain the timestamp of a file.
Definition: byte_filer.cpp:37
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55
bool obscure_detach(byte_array &packed_form, un_int &to_detach)
shifts the number back and checks validity, false returned if corrupted.
void obscure_attach(byte_array &packed_form, un_int to_attach)
like the normal attach but shifts in some recognizable sentinel data.
void attach(byte_array &packed_form, const byte_array &to_attach)
Packs a byte_array "to_attach" into "packed_form".
bool detach(byte_array &packed_form, byte_array &to_detach)
Unpacks a byte_array "to_detach" from "packed_form".
we will read the manifest pieces out of our own exe image.
Definition: common_bundle.h:54
basis::un_int _flags
uses the special_bundling_flags.
Definition: common_bundle.h:57
basis::astring _parms
the parameters to pass on the command line.
Definition: common_bundle.h:58
static basis::astring read_a_string(filesystem::byte_filer &bundle)
reads a string from the "bundle" file, one byte at a time.
basis::astring _payload
guts of the chunk, such as location for file on target or a variable definition.
Definition: common_bundle.h:56
void pack(basis::byte_array &target) const
streams out into the "target".
static bool read_an_obscured_int(filesystem::byte_filer &bundle, basis::un_int &found)
reads in our obscured packing format for an int, which takes 8 bytes.
static bool read_manifest(filesystem::byte_filer &bundle, manifest_chunk &to_fill)
reads a chunk out of the "bundle" and stores it in "to_fill".
virtual ~manifest_chunk()
static bool read_a_filetime(filesystem::byte_filer &bundle, basis::byte_array &found)
retrieves packed_filetime_size() byte timestamp from the "bundle".
static bool read_an_int(filesystem::byte_filer &bundle, basis::un_int &found)
reads an integer (4 bytes) from the file into "found".
basis::un_int _size
the size of the packed file.
Definition: common_bundle.h:55
bool unpack(basis::byte_array &source)
streams in from the "source".
static int packed_filetime_size()
basis::byte_array c_filetime
more than enough room for unix file time.
Definition: common_bundle.h:60
structures::string_set _keywords
keywords applicable to this item.
Definition: common_bundle.h:59