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

5
Last change on this file since 3618a62 was 875c071, checked in by Joel Sherrill <joel@…>, on 09/14/17 at 23:05:38

rtemstoolkit/rld-compression.cpp: Fix warning for comparing signed to unsigned

  • Property mode set to 100644
File size: 6.4 KB
RevLine 
[3f37835]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.
22 *
23 */
24
25#if HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <fstream>
30#include <iostream>
31
32#include <errno.h>
33#include <string.h>
34
35#include <rld.h>
36#include <rld-compression.h>
37
38#include "fastlz.h"
39
40namespace rld
41{
42  namespace compress
43  {
44    compressor::compressor (files::image& image,
45                            size_t        size,
[db216fe]46                            bool          out,
[3f37835]47                            bool          compress)
48      : image (image),
49        size (size),
[db216fe]50        out (out),
[3f37835]51        compress (compress),
52        buffer (0),
53        io (0),
54        level (0),
55        total (0),
56        total_compressed (0)
57    {
[93e80d5]58      if (size > 0xffff)
59        throw rld::error ("Size too big, 16 bits only", "compression");
60
[3f37835]61      buffer = new uint8_t[size];
62      io = new uint8_t[size + (size / 10)];
63    }
64
65    compressor::~compressor ()
66    {
67      flush ();
68      delete [] buffer;
69      delete [] io;
70    }
71
72    void
73    compressor::write (const void* data_, size_t length)
74    {
[db216fe]75      if (!out)
76        throw rld::error ("Write on read-only", "compression");
77
[3f37835]78      const uint8_t* data = static_cast <const uint8_t*> (data_);
79
[93e80d5]80      while (length)
[3f37835]81      {
[93e80d5]82        size_t appending;
[3f37835]83
[93e80d5]84        if (length > (size - level))
85          appending = size - level;
86        else
87          appending = length;
[3f37835]88
[93e80d5]89        ::memcpy ((void*) (buffer + level), data, appending);
[3f37835]90
[194160c]91        data += appending;
[93e80d5]92        level += appending;
93        length -= appending;
[194160c]94        total += appending;
[3f37835]95
[93e80d5]96        output ();
[3f37835]97      }
98    }
99
[076d935]100    void
101    compressor::write (files::image& input, off_t offset, size_t length)
102    {
[db216fe]103      if (!out)
104        throw rld::error ("Write on read-only", "compression");
105
[076d935]106      input.seek (offset);
107
108      while (length)
109      {
110        size_t appending;
111
112        if (length > (size - level))
113          appending = size - level;
114        else
115          appending = length;
116
117        input.read ((void*) (buffer + level), appending);
118
119        level += appending;
120        length -= appending;
[194160c]121        total += appending;
[076d935]122
[93e80d5]123        output ();
[076d935]124      }
125    }
126
[4e9b324]127    size_t
[db216fe]128    compressor::read (void* data_, size_t length)
129    {
130      if (out)
131        throw rld::error ("Read on write-only", "compression");
132
133      uint8_t* data = static_cast <uint8_t*> (data_);
134
[4e9b324]135      size_t amount = 0;
136
[db216fe]137      while (length)
138      {
139        input ();
140
[4e9b324]141        if (level == 0)
142          break;
143
[db216fe]144        size_t appending;
145
146        if (length > level)
147          appending = level;
148        else
149          appending = length;
150
151        ::memcpy (data, buffer, appending);
[4e9b324]152        ::memmove (buffer, buffer + appending, level - appending);
[db216fe]153
154        data += appending;
155        level -= appending;
156        length -= appending;
157        total += appending;
[4e9b324]158        amount += appending;
[db216fe]159      }
[4e9b324]160
161      return amount;
[db216fe]162    }
163
[4e9b324]164    size_t
[db216fe]165    compressor::read (files::image& output_, off_t offset, size_t length)
166    {
167      if (out)
168        throw rld::error ("Read on write-only", "compression");
169
170      output_.seek (offset);
171
[4e9b324]172      return read (output_, length);
173    }
174
175    size_t
176    compressor::read (files::image& output_, size_t length)
177    {
178      if (out)
179        throw rld::error ("Read on write-only", "compression");
180
181      size_t amount = 0;
182
[db216fe]183      while (length)
184      {
185        input ();
186
[4e9b324]187        if (level == 0)
188          break;
189
[db216fe]190        size_t appending;
191
192        if (length > level)
193          appending = level;
194        else
195          appending = length;
196
197        output_.write (buffer, appending);
198
[4e9b324]199        ::memmove (buffer, buffer + appending, level - appending);
200
[db216fe]201        level -= appending;
202        length -= appending;
203        total += appending;
[4e9b324]204        amount += appending;
[db216fe]205      }
[4e9b324]206
207      return amount;
[db216fe]208    }
209
[3f37835]210    void
211    compressor::flush ()
212    {
[93e80d5]213      output (true);
[3f37835]214    }
215
216    size_t
217    compressor::transferred () const
218    {
219      return total;
220    }
221
222    size_t
223    compressor::compressed () const
224    {
225      return total_compressed;
226    }
227
[4e9b324]228    off_t
229    compressor::offset () const
230    {
231      return total;
232    }
233
[93e80d5]234    void
235    compressor::output (bool forced)
236    {
[db216fe]237      if (out && ((forced && level) || (level >= size)))
[93e80d5]238      {
239        if (compress)
240        {
241          int     writing = ::fastlz_compress (buffer, level, io);
242          uint8_t header[2];
243
[194160c]244          if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
245            std::cout << "rtl: comp: offset=" << total_compressed
246                      << " block-size=" << writing << std::endl;
247
[93e80d5]248          header[0] = writing >> 8;
249          header[1] = writing;
250
251          image.write (header, 2);
252          image.write (io, writing);
253
254          total_compressed += 2 + writing;
255        }
256        else
257        {
258          image.write (buffer, level);
259        }
260
261        level = 0;
262      }
263    }
264
[db216fe]265    void
266    compressor::input ()
267    {
268      if (!out && (level == 0))
269      {
270        if (compress)
271        {
272          uint8_t header[2];
273
[4e9b324]274          if (image.read (header, 2) == 2)
275          {
[875c071]276            ssize_t block_size =
277              (((ssize_t) header[0]) << 8) | (ssize_t) header[1];
[db216fe]278
[4e9b324]279            if (block_size == 0)
280              throw rld::error ("Block size is invalid (0)", "compression");
[db216fe]281
[4e9b324]282            total_compressed += 2 + block_size;
[db216fe]283
[4e9b324]284            if (rld::verbose () >= RLD_VERBOSE_FULL_DEBUG)
285              std::cout << "rtl: decomp: block-size=" << block_size
286                        << std::endl;
[db216fe]287
[4e9b324]288            if (image.read (io, block_size) != block_size)
289              throw rld::error ("Read past end", "compression");
[db216fe]290
[4e9b324]291            level = ::fastlz_decompress (io, block_size, buffer, size);
292          }
[db216fe]293        }
294        else
295        {
296          image.read (buffer, size);
297          level = size;
298        }
299      }
300    }
301
[3f37835]302  }
303}
Note: See TracBrowser for help on using the repository browser.