diff options
author | Chris Johns <chrisj@rtems.org> | 2016-04-03 15:41:08 +1000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2016-04-03 15:41:08 +1000 |
commit | 635a28f1fb332c6fde6ed299ed1863b180a8fee3 (patch) | |
tree | c736878c8b7b078a2c079ba545a3dd3a482496a8 | |
parent | 8dc277265b414b7966563493a2ab159fcdfd49a3 (diff) |
rtemstoolkit: Add a buffer helper class to insert and extract data.
-rw-r--r-- | rtemstoolkit/rld-buffer.cpp | 218 | ||||
-rw-r--r-- | rtemstoolkit/rld-buffer.h | 257 | ||||
-rw-r--r-- | rtemstoolkit/wscript | 39 |
3 files changed, 490 insertions, 24 deletions
diff --git a/rtemstoolkit/rld-buffer.cpp b/rtemstoolkit/rld-buffer.cpp new file mode 100644 index 0000000..095d8a3 --- /dev/null +++ b/rtemstoolkit/rld-buffer.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2016, Chris Johns <chrisj@rtems.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <string.h> + +#include <rld-buffer.h> +#include <rtems-utils.h> + +namespace rld +{ + namespace buffer + { + buffer::buffer (const size_t size, bool le) + : data (0), + size (size), + le (le), + in (0), + out (0), + level_ (0) + { + data = new uint8_t[size]; + clear (); + } + + buffer::buffer () + : data (0), + size (0), + le (true), + in (0), + out (0), + level_ (0) + { + } + + buffer::buffer (const buffer& orig) + : data (0), + size (orig.size), + le (orig.le), + in (orig.in), + out (orig.out), + level_ (orig.level_) + { + data = new uint8_t[size]; + memcpy (data, orig.data, size); + } + + buffer::~buffer () + { + if (data) + delete [] data; + } + + void + buffer::clear () + { + memset (data, 0, size); + out = 0; + in = 0; + level_ = 0; + } + + void + buffer::write (const void* data_, const size_t length) + { + if ((out + length) > size) + throw rld::error ("Buffer overflow", "buffer:write"); + memcpy (&data[out], data_, length); + out += length; + if (out > level_) + level_ = out; + } + + void + buffer::read (void* data_, const size_t length) + { + if ((in + length) > level_) + throw rld::error ("Buffer underflow", "buffer:read"); + memcpy (data_, &data[in], length); + in += length; + } + + void + buffer::fill (const size_t length, const uint8_t value) + { + if ((out + length) > size) + throw rld::error ("Buffer overflow", "buffer:fill"); + memset (&data[out], value, length); + out += length; + if (out > level_) + level_ = out; + } + + void + buffer::set (const size_t out_, const uint8_t value) + { + if (out_ < out) + throw rld::error ("Invalid set out", "buffer:set"); + fill (out_ - out, value); + } + + size_t + buffer::level () const + { + return level_; + } + + void + buffer::write (files::image& img) + { + if (out > 0) + { + img.write (data, level_); + clear (); + } + } + + void + buffer::read (files::image& img, size_t length) + { + if (length > size) + throw rld::error ("Invalid length", "buffer:read"); + if (length == 0) + length = size; + img.read (data, length); + in = 0; + out = 0; + level_ = length; + } + + void + buffer::dump () + { + rtems::utils::dump (data, level_, 1); + } + + buffer& operator<< (buffer& buf, const uint64_t value) + { + write < uint64_t > (buf, value); + return buf; + } + + buffer& operator>> (buffer& buf, uint64_t& value) + { + read < uint64_t > (buf, value); + return buf; + } + + buffer& operator<< (buffer& buf, const uint32_t value) + { + write < uint32_t > (buf, value); + return buf; + } + + buffer& operator>> (buffer& buf, uint32_t& value) + { + read < uint32_t > (buf, value); + return buf; + } + + buffer& operator<< (buffer& buf, const uint16_t value) + { + write < uint16_t > (buf, value); + return buf; + } + + buffer& operator>> (buffer& buf, uint16_t& value) + { + read < uint16_t > (buf, value); + return buf; + } + + buffer& operator<< (buffer& buf, const uint8_t value) + { + buf.write (&value, 1); + return buf; + } + + buffer& operator>> (buffer& buf, uint8_t& value) + { + buf.read (&value, 1); + return buf; + } + + buffer& operator<< (buffer& buf, const std::string& str) + { + buf.write (str.c_str (), str.size ()); + return buf; + } + + b_fill fill (const size_t amount, const uint8_t value) + { + return b_fill (amount, value); + } + + b_set set (const size_t level, const uint8_t value) + { + return b_set (level, value); + } + + b_skip skip (const size_t amount) + { + return b_skip (amount); + } + } +} diff --git a/rtemstoolkit/rld-buffer.h b/rtemstoolkit/rld-buffer.h new file mode 100644 index 0000000..ea94a9a --- /dev/null +++ b/rtemstoolkit/rld-buffer.h @@ -0,0 +1,257 @@ +/* + * Copyright (c) 2016, Chris Johns <chrisj@rtems.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/** + * @file + * + * @ingroup rtems-ld + * + * @brief A buffer of data. + * + */ + +#if !defined (_RLD_BUFFER_H_) +#define _RLD_BUFFER_H_ + +#include <string> + +#include <rld-files.h> + +namespace rld +{ + namespace buffer + { + /** + * A buffer to help manage formats. + */ + class buffer + { + public: + /** + * Create a buffer. + */ + buffer (const size_t size, bool le = true); + + /** + * An empty buffer + */ + buffer (); + + /** + * Copy a buffer. + */ + buffer (const buffer& orig); + + /* + * Destory the buffer. + */ + ~buffer (); + + /** + * Clear the buffer reseting the level to zero. + */ + void clear (); + + /** + * Write the data to the buffer. + * + * @param data The data to write to the buffer. + * @param length The amount of data in bytes to write. + */ + void write (const void* data_, const size_t length); + + /** + * Read the data from the buffer. + * + * @param data Read from the buffer in the data. + * @param length The amount of data in bytes to read. + */ + void read (void* data_, const size_t length); + + /** + * Fill the data to the buffer. + * + * @param length The amount of data in bytes to fill with. + * @param value The value to fill the buffer with. + */ + void fill (const size_t length, const uint8_t value = 0); + + /** + * Set the write pointer in the buffer to the level provided filing with + * the value also provided. + * + * @param out_ The new out pointer. + * @param value The value to fill the buffer with. + */ + void set (const size_t out_, const uint8_t value = 0); + + /** + * Skip the data in the buffer moving the read pointer. + * + * @param length The amount of data in bytes to skip. + */ + void skip (const size_t length); + + /** + * Rewind the in pointer the buffer to the pointer. + * + * @param in_ The new in pointer. + */ + void rewind (const size_t in_); + + /* + * The level in the buffer. + */ + size_t level () const; + + /* + * Write the data buffered to the image. Clear the buffer after. + */ + void write (files::image& img); + + /* + * Read the data from the image into the start of buffer. + */ + void read (files::image& img, size_t length = 0); + + /* + * Dump. + */ + void dump (); + + private: + uint8_t* data; //< The data held in the buffer. + size_t size; //< The zie of the date the buffer hold. + bool le; //< True is little endian else it is big. + size_t in; //< The data in pointer, used when writing. + size_t out; //< The data out ponter, used when reading. + size_t level_; //< The level of data in the buffer. + }; + + /** + * Buffer template function for writing data to the buffer. + */ + template < typename T > + void write (buffer& buf, const T value) + { + uint8_t bytes[sizeof (T)]; + T v = value; + int b = sizeof (T) - 1; + while (b >= 0) + { + bytes[b--] = (uint8_t) v; + v >>= 8; + } + buf.write (bytes, sizeof (T)); + } + + /** + * Buffer template function for reading data to the buffer. + */ + template < typename T > + void read (buffer& buf, T& value) + { + uint8_t bytes[sizeof (T)]; + int b = sizeof (T) - 1; + buf.read (bytes, sizeof(T)); + value = 0; + while (b >= 0) + { + value <<= 8; + value |= (T) bytes[b--]; + } + } + + /* + * Insertion operators. + */ + buffer& operator<< (buffer& buf, const uint64_t value); + buffer& operator<< (buffer& buf, const uint32_t value); + buffer& operator<< (buffer& buf, const uint16_t value); + buffer& operator<< (buffer& buf, const uint8_t value); + buffer& operator<< (buffer& buf, const std::string& str); + + /* + * Extraction operators. + */ + buffer& operator>> (buffer& buf, uint64_t& value); + buffer& operator>> (buffer& buf, uint32_t& value); + buffer& operator>> (buffer& buf, uint16_t& value); + buffer& operator>> (buffer& buf, uint8_t& value); + + /* + * Buffer fill manipulator. + */ + struct b_fill + { + const uint8_t value; + const size_t amount; + + b_fill (const size_t amount, const uint8_t value) + : value (value), + amount (amount) { + } + + friend buffer& operator<< (buffer& buf, const b_fill& bf) { + buf.fill (bf.amount, bf.value); + return buf; + } + }; + + b_fill fill (const size_t amount, const uint8_t value = 0); + + /* + * Buffer set manipulator. + */ + struct b_set + { + const uint8_t value; + const size_t level; + + b_set (const size_t level, const uint8_t value) + : value (value), + level (level) { + } + + friend buffer& operator<< (buffer& buf, const b_set& bs) { + buf.set (bs.level, bs.value); + return buf; + } + }; + + b_set set (const size_t level, const uint8_t value = 0); + + /* + * Buffer skip manipulator. + */ + struct b_skip + { + const size_t amount; + + b_skip (const size_t amount) + : amount (amount) { + } + + friend buffer& operator>> (buffer& buf, const b_skip& bs) { + buf.skip (bs.amount); + return buf; + } + }; + + b_skip skip (const size_t amount); + } +} + +#endif diff --git a/rtemstoolkit/wscript b/rtemstoolkit/wscript index 71eadfa..d018624 100644 --- a/rtemstoolkit/wscript +++ b/rtemstoolkit/wscript @@ -1,31 +1,21 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2014, 2015 Chris Johns (chrisj@rtems.org) +# Copyright 2014-2016 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. # -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. # -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # @@ -93,18 +83,19 @@ def build(bld): # rld_source = ['ConvertUTF.c', 'pkgconfig.cpp', + 'rld-buffer.cpp', + 'rld-cc.cpp', + 'rld-compression.cpp', 'rld-config.cpp', 'rld-elf.cpp', 'rld-files.cpp', - 'rld-cc.cpp', - 'rld-compression.cpp', 'rld-outputter.cpp', 'rld-path.cpp', 'rld-process.cpp', + 'rld-rap.cpp', 'rld-resolver.cpp', 'rld-rtems.cpp', 'rld-symbols.cpp', - 'rld-rap.cpp', 'rld.cpp'] # |