source: rtems-tools/linkers/rld-compression.h @ 544de91

4.104.115
Last change on this file since 544de91 was 4e9b324, checked in by Chris Johns <chrisj@…>, on 12/21/12 at 06:08:17

Decompressor fixes.

Make reading compressed files more robust returning the amount
of data that can be read. Also add >> operartors to get the
data. Add exceptions when a read fails.

  • Property mode set to 100644
File size: 6.9 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       */
90      size_t read (void* data, size_t length);
91
92      /**
93       * Read the decompressed data writing it to the image.
94       *
95       * @param output The output image.
96       * @param offset The output image offset to write from.
97       * @param length The mount of data in bytes to read.
98       */
99      size_t read (files::image& output_, off_t offset, size_t length);
100
101      /**
102       * Read the decompressed data writing it to the image.
103       *
104       * @param output The output image.
105       * @param length The mount of data in bytes to read.
106       */
107      size_t read (files::image& output_, size_t length);
108
109      /**
110       * The amount of uncompressed data transferred.
111       *
112       * @param return size_t The amount of data tranferred.
113       */
114      size_t transferred () const;
115
116      /**
117       * The amount of compressed data transferred.
118       *
119       * @param return size_t The amount of compressed data tranferred.
120       */
121      size_t compressed () const;
122
123      /**
124       * The current offset in the stream.
125       */
126      off_t offset () const;
127
128    private:
129
130      /**
131       * Output the block of data to the output file with the block header.
132       *
133       * @param forced If true output the buffer.
134       */
135      void output (bool forced = false);
136
137      /**
138       * Input a block of compressed data and decompress it.
139       */
140      void input ();
141
142      files::image& image;            //< The image to read or write to or from.
143      size_t        size;             //< The size of the buffer.
144      bool          out;              //< If true the it is compression.
145      bool          compress;         //< If true compress the data.
146      uint8_t*      buffer;           //< The decompressed buffer
147      uint8_t*      io;               //< The I/O buffer.
148      size_t        level;            //< The amount of data in the buffer.
149      size_t        total;            //< The amount of uncompressed data
150                                      //  transferred.
151      size_t        total_compressed; //< The amount of compressed data
152                                      //  transferred.
153    };
154
155    /**
156     * Compressor template function for writing data to the compressor.
157     */
158    template < typename T >
159    void write (compressor& comp, const T value)
160    {
161      uint8_t bytes[sizeof (T)];
162      T       v = value;
163      int     b = sizeof (T) - 1;
164      while (b >= 0)
165      {
166        bytes[b--] = (uint8_t) v;
167        v >>= 8;
168      }
169      comp.write (bytes, sizeof (T));
170    }
171
172    /**
173     * Compressor template function for reading data from the compressor.
174     */
175    template < typename T >
176    T read (compressor& comp)
177    {
178      uint8_t  bytes[sizeof (T)];
179      T        v = 0;
180      uint32_t b = 0;
181      if (comp.read (bytes, sizeof (T)) != sizeof (T))
182        throw rld::error ("Reading of value failed", "compression");
183      while (b < sizeof (T))
184      {
185        v = (v << 8) | ((T) bytes[b++]);
186      }
187      return v;
188    }
189
190  }
191}
192
193static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp,
194                                                     const uint64_t             value) {
195  rld::compress::write < uint64_t > (comp, value);
196  return comp;
197}
198
199static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp,
200                                                     const uint32_t             value) {
201  rld::compress::write < uint32_t > (comp, value);
202  return comp;
203}
204
205static inline rld::compress::compressor& operator<< (rld::compress::compressor& comp,
206                                                     const std::string&         str) {
207  comp.write (str.c_str (), str.size ());
208  return comp;
209}
210
211static inline rld::compress::compressor& operator>> (rld::compress::compressor& comp,
212                                                     uint64_t&                  value) {
213  value = rld::compress::read < uint64_t > (comp);
214  return comp;
215}
216
217static inline rld::compress::compressor& operator>> (rld::compress::compressor& comp,
218                                                     uint32_t&                  value) {
219  value = rld::compress::read < uint32_t > (comp);
220  return comp;
221}
222
223#endif
Note: See TracBrowser for help on using the repository browser.