summaryrefslogtreecommitdiffstats
path: root/lib/kaitai/kaitaistream.h
diff options
context:
space:
mode:
authorEvan Dekker <ehendrikd@gmail.com>2019-05-24 21:36:57 +1000
committerEvan Dekker <ehendrikd@gmail.com>2019-05-24 21:38:15 +1000
commit83e1b45e5cfbdef5f66ecc117a2a782bc43686c9 (patch)
tree36fea735b224ec05795ca1e59e2be78b211600f5 /lib/kaitai/kaitaistream.h
parentf5d7e7de5b2c26424b2477fdcb2e096ba13420ff (diff)
Rekordbox library feature that reads tracks, playlists and folders from removable devices
Diffstat (limited to 'lib/kaitai/kaitaistream.h')
-rwxr-xr-xlib/kaitai/kaitaistream.h250
1 files changed, 250 insertions, 0 deletions
diff --git a/lib/kaitai/kaitaistream.h b/lib/kaitai/kaitaistream.h
new file mode 100755
index 0000000000..9592771db0
--- /dev/null
+++ b/lib/kaitai/kaitaistream.h
@@ -0,0 +1,250 @@
+#ifndef KAITAI_STREAM_H
+#define KAITAI_STREAM_H
+
+// Kaitai Struct runtime API version: x.y.z = 'xxxyyyzzz' decimal
+#define KAITAI_STRUCT_VERSION 7000L
+
+#include <istream>
+#include <sstream>
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace kaitai {
+
+/**
+ * Kaitai Stream class (kaitai::kstream) is an implementation of
+ * <a href="https://github.com/kaitai-io/kaitai_struct/wiki/Kaitai-Struct-stream-API">Kaitai Struct stream API</a>
+ * for C++/STL. It's implemented as a wrapper over generic STL std::istream.
+ *
+ * It provides a wide variety of simple methods to read (parse) binary
+ * representations of primitive types, such as integer and floating
+ * point numbers, byte arrays and strings, and also provides stream
+ * positioning / navigation methods with unified cross-language and
+ * cross-toolkit semantics.
+ *
+ * Typically, end users won't access Kaitai Stream class manually, but would
+ * describe a binary structure format using .ksy language and then would use
+ * Kaitai Struct compiler to generate source code in desired target language.
+ * That code, in turn, would use this class and API to do the actual parsing
+ * job.
+ */
+class kstream {
+public:
+ /**
+ * Constructs new Kaitai Stream object, wrapping a given std::istream.
+ * \param io istream object to use for this Kaitai Stream
+ */
+ kstream(std::istream* io);
+
+ /**
+ * Constructs new Kaitai Stream object, wrapping a given in-memory data
+ * buffer.
+ * \param data data buffer to use for this Kaitai Stream
+ */
+ kstream(std::string& data);
+
+ void close();
+
+ /** @name Stream positioning */
+ //@{
+ /**
+ * Check if stream pointer is at the end of stream. Note that the semantics
+ * are different from traditional STL semantics: one does *not* need to do a
+ * read (which will fail) after the actual end of the stream to trigger EOF
+ * flag, which can be accessed after that read. It is sufficient to just be
+ * at the end of the stream for this method to return true.
+ * \return "true" if we are located at the end of the stream.
+ */
+ bool is_eof() const;
+
+ /**
+ * Set stream pointer to designated position.
+ * \param pos new position (offset in bytes from the beginning of the stream)
+ */
+ void seek(uint64_t pos);
+
+ /**
+ * Get current position of a stream pointer.
+ * \return pointer position, number of bytes from the beginning of the stream
+ */
+ uint64_t pos();
+
+ /**
+ * Get total size of the stream in bytes.
+ * \return size of the stream in bytes
+ */
+ uint64_t size();
+ //@}
+
+ /** @name Integer numbers */
+ //@{
+
+ // ------------------------------------------------------------------------
+ // Signed
+ // ------------------------------------------------------------------------
+
+ int8_t read_s1();
+
+ // ........................................................................
+ // Big-endian
+ // ........................................................................
+
+ int16_t read_s2be();
+ int32_t read_s4be();
+ int64_t read_s8be();
+
+ // ........................................................................
+ // Little-endian
+ // ........................................................................
+
+ int16_t read_s2le();
+ int32_t read_s4le();
+ int64_t read_s8le();
+
+ // ------------------------------------------------------------------------
+ // Unsigned
+ // ------------------------------------------------------------------------
+
+ uint8_t read_u1();
+
+ // ........................................................................
+ // Big-endian
+ // ........................................................................
+
+ uint16_t read_u2be();
+ uint32_t read_u4be();
+ uint64_t read_u8be();
+
+ // ........................................................................
+ // Little-endian
+ // ........................................................................
+
+ uint16_t read_u2le();
+ uint32_t read_u4le();
+ uint64_t read_u8le();
+
+ //@}
+
+ /** @name Floating point numbers */
+ //@{
+
+ // ........................................................................
+ // Big-endian
+ // ........................................................................
+
+ float read_f4be();
+ double read_f8be();
+
+ // ........................................................................
+ // Little-endian
+ // ........................................................................
+
+ float read_f4le();
+ double read_f8le();
+
+ //@}
+
+ /** @name Unaligned bit values */
+ //@{
+
+ void align_to_byte();
+ uint64_t read_bits_int(int n);
+
+ //@}
+
+ /** @name Byte arrays */
+ //@{
+
+ std::string read_bytes(std::streamsize len);
+ std::string read_bytes_full();
+ std::string read_bytes_term(char term, bool include, bool consume, bool eos_error);
+ std::string ensure_fixed_contents(std::string expected);
+
+ static std::string bytes_strip_right(std::string src, char pad_byte);
+ static std::string bytes_terminate(std::string src, char term, bool include);
+ static std::string bytes_to_str(std::string src, std::string src_enc);
+
+ //@}
+
+ /** @name Byte array processing */
+ //@{
+
+ /**
+ * Performs a XOR processing with given data, XORing every byte of input with a single
+ * given value.
+ * @param data data to process
+ * @param key value to XOR with
+ * @return processed data
+ */
+ static std::string process_xor_one(std::string data, uint8_t key);
+
+ /**
+ * Performs a XOR processing with given data, XORing every byte of input with a key
+ * array, repeating key array many times, if necessary (i.e. if data array is longer
+ * than key array).
+ * @param data data to process
+ * @param key array of bytes to XOR with
+ * @return processed data
+ */
+ static std::string process_xor_many(std::string data, std::string key);
+
+ /**
+ * Performs a circular left rotation shift for a given buffer by a given amount of bits,
+ * using groups of 1 bytes each time. Right circular rotation should be performed
+ * using this procedure with corrected amount.
+ * @param data source data to process
+ * @param amount number of bits to shift by
+ * @return copy of source array with requested shift applied
+ */
+ static std::string process_rotate_left(std::string data, int amount);
+
+#ifdef KS_ZLIB
+ /**
+ * Performs an unpacking ("inflation") of zlib-compressed data with usual zlib headers.
+ * @param data data to unpack
+ * @return unpacked data
+ * @throws IOException
+ */
+ static std::string process_zlib(std::string data);
+#endif
+
+ //@}
+
+ /**
+ * Performs modulo operation between two integers: dividend `a`
+ * and divisor `b`. Divisor `b` is expected to be positive. The
+ * result is always 0 <= x <= b - 1.
+ */
+ static int mod(int a, int b);
+
+ /**
+ * Converts given integer `val` to a decimal string representation.
+ * Should be used in place of std::to_string() (which is available only
+ * since C++11) in older C++ implementations.
+ */
+ static std::string to_string(int val);
+
+ /**
+ * Reverses given string `val`, so that the first character becomes the
+ * last and the last one becomes the first. This should be used to avoid
+ * the need of local variables at the caller.
+ */
+ static std::string reverse(std::string val);
+
+private:
+ std::istream* m_io;
+ std::istringstream m_io_str;
+ int m_bits_left;
+ uint64_t m_bits;
+
+ void init();
+ void exceptions_enable() const;
+
+ static uint64_t get_mask_ones(int n);
+
+ static const int ZLIB_BUF_SIZE = 128 * 1024;
+};
+
+}
+
+#endif