RTEMS Linker  0.0.1
RTEMS Tools Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
/Users/chris/Development/rtems/src/apps/rtl-host.chrisj/rld-compression.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Chris Johns <chrisj@rtems.org>
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 /**
17  * @file
18  *
19  * @ingroup rtems-ld
20  *
21  * @brief RTEMS Linker compression handles compressed images.
22  *
23  */
24 
25 #if !defined (_RLD_COMPRESSION_H_)
26 #define _RLD_COMPRESSION_H_
27 
28 #include <rld-files.h>
29 
30 namespace rld
31 {
32  namespace compress
33  {
34  /**
35  * A compressor.
36  */
37  class compressor
38  {
39  public:
40  /**
41  * Construct the compressor for the given image.
42  *
43  * @param image The image to read or write to.
44  * @param size The size of the input and output buffers.
45  * @param out The compressor is compressing.
46  * @param compress Set to false to disable compression.
47  */
48  compressor (files::image& image,
49  size_t size,
50  bool out = true,
51  bool compress = true);
52 
53  /**
54  * Destruct the compressor.
55  */
56  ~compressor ();
57 
58  /**
59  * Write the data to the output buffer and once the image buffer is full
60  * compress and write the compressed data to the image.
61  *
62  * @param data The data to write to the image compressed
63  * @param length The mount of data in bytes to write.
64  */
65  void write (const void* data, size_t length);
66 
67  /**
68  * Write the section of the input image file to the output buffer and
69  * once the image buffer is full compress and write the compressed data
70  * to the image.
71  *
72  * @param input The input image.
73  * @param offset The input image offset to read from.
74  * @param length The mount of data in bytes to write.
75  */
76  void write (files::image& input, off_t offset, size_t length);
77 
78  /**
79  * Flush the output buffer is data is present.
80  */
81  void flush ();
82 
83  /**
84  * Read the compressed data into the input buffer and return the section
85  * requested.
86  *
87  * @param data Write the decompressed data here.
88  * @param length The mount of data in bytes to read.
89  * @return size_t The amount of data read.
90  */
91  size_t read (void* data, size_t length);
92 
93  /**
94  * Read the decompressed data writing it to the image.
95  *
96  * @param output_ The output image.
97  * @param offset The output image offset to write from.
98  * @param length The mount of data in bytes to read.
99  * @return size_t The amount of data read.
100  */
101  size_t read (files::image& output_, off_t offset, size_t length);
102 
103  /**
104  * Read the decompressed data writing it to the image.
105  *
106  * @param output_ The output image.
107  * @param length The mount of data in bytes to read.
108  * @return size_t The amount of data read.
109  */
110  size_t read (files::image& output_, size_t length);
111 
112  /**
113  * The amount of uncompressed data transferred.
114  *
115  * @return size_t The amount of data tranferred.
116  */
117  size_t transferred () const;
118 
119  /**
120  * The amount of compressed data transferred.
121  *
122  * @return size_t The amount of compressed data tranferred.
123  */
124  size_t compressed () const;
125 
126  /**
127  * The current offset in the stream.
128  *
129  * @return off_t The current uncompressed offset.
130  */
131  off_t offset () const;
132 
133  private:
134 
135  /**
136  * Output the block of data to the output file with the block header.
137  *
138  * @param forced If true output the buffer.
139  */
140  void output (bool forced = false);
141 
142  /**
143  * Input a block of compressed data and decompress it.
144  */
145  void input ();
146 
147  files::image& image; //< The image to read or write to or from.
148  size_t size; //< The size of the buffer.
149  bool out; //< If true the it is compression.
150  bool compress; //< If true compress the data.
151  uint8_t* buffer; //< The decompressed buffer
152  uint8_t* io; //< The I/O buffer.
153  size_t level; //< The amount of data in the buffer.
154  size_t total; //< The amount of uncompressed data
155  // transferred.
156  size_t total_compressed; //< The amount of compressed data
157  // transferred.
158  };
159 
160  /**
161  * Compressor template function for writing data to the compressor.
162  */
163  template < typename T >
164  void write (compressor& comp, const T value)
165  {
166  uint8_t bytes[sizeof (T)];
167  T v = value;
168  int b = sizeof (T) - 1;
169  while (b >= 0)
170  {
171  bytes[b--] = (uint8_t) v;
172  v >>= 8;
173  }
174  comp.write (bytes, sizeof (T));
175  }
176 
177  /**
178  * Compressor template function for reading data from the compressor.
179  */
180  template < typename T >
181  T read (compressor& comp)
182  {
183  uint8_t bytes[sizeof (T)];
184  T v = 0;
185  uint32_t b = 0;
186  if (comp.read (bytes, sizeof (T)) != sizeof (T))
187  throw rld::error ("Reading of value failed", "compression");
188  while (b < sizeof (T))
189  {
190  v = (v << 8) | ((T) bytes[b++]);
191  }
192  return v;
193  }
194 
195  }
196 }
197 
198 static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp,
199  const uint64_t value) {
200  rld::compress::write < uint64_t > (comp, value);
201  return comp;
202 }
203 
204 static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp,
205  const uint32_t value) {
206  rld::compress::write < uint32_t > (comp, value);
207  return comp;
208 }
209 
210 static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp,
211  const std::string& str) {
212  comp.write (str.c_str (), str.size ());
213  return comp;
214 }
215 
216 static inline rld::compress::compressor& operator>> (rld::compress::compressor& comp,
217  uint64_t& value) {
218  value = rld::compress::read < uint64_t > (comp);
219  return comp;
220 }
221 
222 static inline rld::compress::compressor& operator>> (rld::compress::compressor& comp,
223  uint32_t& value) {
224  value = rld::compress::read < uint32_t > (comp);
225  return comp;
226 }
227 
228 #endif