source: rtems-tools/rtemstoolkit/rld-compression.h @ 3618a62

Last change on this file since 3618a62 was 87e0e76, checked in by Chris Johns <chrisj@…>, on Sep 13, 2014 at 2:09:16 AM

Refactor code into the RTEMS Toolkit.

  • Property mode set to 100644
File size: 7.1 KB
Line 
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
30namespace 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
198static 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
204static 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
210static 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
216static 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
222static 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
Note: See TracBrowser for help on using the repository browser.