summaryrefslogtreecommitdiffstats
path: root/docs/release/scripts/build/verinfo.py
diff options
context:
space:
mode:
Diffstat (limited to 'docs/release/scripts/build/verinfo.py')
-rw-r--r--docs/release/scripts/build/verinfo.py181
1 files changed, 181 insertions, 0 deletions
diff --git a/docs/release/scripts/build/verinfo.py b/docs/release/scripts/build/verinfo.py
new file mode 100644
index 00000000000..3437288b447
--- /dev/null
+++ b/docs/release/scripts/build/verinfo.py
@@ -0,0 +1,181 @@
+#!/usr/bin/python
+##
+## license:BSD-3-Clause
+## copyright-holders:Aaron Giles, Andrew Gardner
+
+from __future__ import with_statement
+
+import re
+import sys
+
+
+def parse_args():
+ def usage():
+ sys.stderr.write('Usage: verinfo.py [-b mame|mess|ume] [-r|-p] [-o <outfile>] <srcfile>\n')
+ sys.exit(1)
+
+ flags = True
+ target = 'mame'
+ format = 'rc'
+ input = None
+ output = None
+ i = 1
+ while i < len(sys.argv):
+ if flags and (sys.argv[i] == '-r'):
+ format = 'rc'
+ elif flags and (sys.argv[i] == '-p'):
+ format = 'plist'
+ elif flags and (sys.argv[i] == '-b'):
+ i += 1
+ if (i >= len(sys.argv)):
+ usage()
+ else:
+ target = sys.argv[i]
+ elif flags and (sys.argv[i] == '-o'):
+ i += 1
+ if (i >= len(sys.argv)) or (output is not None):
+ usage()
+ else:
+ output = sys.argv[i]
+ elif flags and (sys.argv[i] == '--'):
+ flags = False
+ elif flags and sys.argv[i].startswith('-'):
+ usage()
+ elif input is not None:
+ usage()
+ else:
+ input = sys.argv[i]
+ i += 1
+ if input is None:
+ usage()
+ return target, format, input, output
+
+
+def extract_version(input):
+ pattern = re.compile('\s+BARE_BUILD_VERSION\s+"(([^."]+)\.([^."]+))"')
+ for line in input.readlines():
+ match = pattern.search(line)
+ if match:
+ return match.group(1), match.group(2), match.group(3)
+ return None, None, None
+
+
+build, outfmt, srcfile, dstfile = parse_args()
+
+try:
+ fp = open(srcfile, 'rU')
+except IOError:
+ sys.stderr.write("Unable to open source file '%s'\n" % srcfile)
+ sys.exit(1)
+
+version_string, version_major, version_minor = extract_version(fp)
+version_build = "0"
+version_subbuild = "0"
+if not version_string:
+ sys.stderr.write("Unable to extract version from source file '%s'\n" % srcfile)
+ sys.exit(1)
+fp.close()
+
+if dstfile is not None:
+ try:
+ fp = open(dstfile, 'w')
+ except IOError:
+ sys.stderr.write("Unable to open output file '%s'\n" % dstfile)
+ sys.exit(1)
+else:
+ fp = sys.stdout
+
+legal_copyright = "Copyright Nicola Salmoria and the MAME team"
+
+if build == "mess":
+ # MESS
+ author = "MESS Team"
+ comments = "Multi Emulation Super System"
+ company_name = "MESS Team"
+ file_description = "MESS"
+ internal_name = "MESS"
+ original_filename = "MESS"
+ product_name = "MESS"
+ bundle_identifier = "org.mamedev.mess"
+elif build == "hbmame":
+ # HBMAME
+ author = "Robbbert and the MAME team"
+ legal_copyright = author
+ comments = "Homebrew MAME"
+ company_name = "MAME Team"
+ file_description = "HBMAME"
+ internal_name = "HBMAME"
+ original_filename = "HBMAME"
+ product_name = "HBMAME"
+ bundle_identifier = "org.mamedev.hbmame"
+else:
+ # MAME
+ author = "Nicola Salmoria and the MAME Team"
+ comments = "Multi-purpose emulation framework"
+ company_name = "MAME Team"
+ file_description = "MAME"
+ internal_name = "MAME" if build == "mame" else build
+ original_filename = "MAME" if build == "mame" else build
+ product_name = "MAME" if build == "mame" else build
+ bundle_identifier = "org.mamedev." + build
+
+if outfmt == 'rc':
+ fp.write('VS_VERSION_INFO VERSIONINFO\n')
+ fp.write('\tFILEVERSION %s,%s,%s,%s\n' % (version_major, version_minor, version_build, version_subbuild))
+ fp.write('\tPRODUCTVERSION %s,%s,%s,%s\n' % (version_major, version_minor, version_build, version_subbuild))
+ fp.write('\tFILEFLAGSMASK 0x3fL\n')
+ if version_build == 0:
+ fp.write('\tFILEFLAGS 0x0L\n')
+ else:
+ fp.write('\tFILEFLAGS VS_FF_PRERELEASE\n')
+ fp.write('\tFILEOS VOS_NT_WINDOWS32\n')
+ fp.write('\tFILETYPE VFT_APP\n')
+ fp.write('\tFILESUBTYPE VFT2_UNKNOWN\n')
+ fp.write('BEGIN\n')
+ fp.write('\tBLOCK "StringFileInfo"\n')
+ fp.write('\tBEGIN\n')
+ fp.write('#ifdef UNICODE\n')
+ fp.write('\t\tBLOCK "040904b0"\n')
+ fp.write('#else\n')
+ fp.write('\t\tBLOCK "040904E4"\n')
+ fp.write('#endif\n')
+ fp.write('\t\tBEGIN\n')
+ fp.write('\t\t\tVALUE "Author", "%s\\0"\n' % author)
+ fp.write('\t\t\tVALUE "Comments", "%s\\0"\n' % comments)
+ fp.write('\t\t\tVALUE "CompanyName", "%s\\0"\n' % company_name)
+ fp.write('\t\t\tVALUE "FileDescription", "%s\\0"\n' % file_description)
+ fp.write('\t\t\tVALUE "FileVersion", "%s, %s, %s, %s\\0"\n' % (version_major, version_minor, version_build, version_subbuild))
+ fp.write('\t\t\tVALUE "InternalName", "%s\\0"\n' % internal_name)
+ fp.write('\t\t\tVALUE "LegalCopyright", "%s\\0"\n' % legal_copyright)
+ fp.write('\t\t\tVALUE "OriginalFilename", "%s\\0"\n' % original_filename)
+ fp.write('\t\t\tVALUE "ProductName", "%s\\0"\n' % product_name)
+ fp.write('\t\t\tVALUE "ProductVersion", "%s\\0"\n' % version_string)
+ fp.write('\t\tEND\n')
+ fp.write('\tEND\n')
+ fp.write('\tBLOCK "VarFileInfo"\n')
+ fp.write('\tBEGIN\n')
+ fp.write('#ifdef UNICODE\n')
+ fp.write('\t\tVALUE "Translation", 0x409, 1200\n')
+ fp.write('#else\n')
+ fp.write('\t\tVALUE "Translation", 0x409, 1252\n')
+ fp.write('#endif\n')
+ fp.write('\tEND\n')
+ fp.write('END\n')
+elif outfmt == 'plist':
+ fp.write('<?xml version="1.0" encoding="UTF-8"?>\n')
+ fp.write('<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n')
+ fp.write('<plist version="1.0">\n')
+ fp.write('<dict>\n')
+ fp.write('\t<key>CFBundleDisplayName</key>\n')
+ fp.write('\t<string>%s</string>\n' % product_name)
+ fp.write('\t<key>CFBundleIdentifier</key>\n')
+ fp.write('\t<string>%s</string>\n' % bundle_identifier)
+ fp.write('\t<key>CFBundleInfoDictionaryVersion</key>\n')
+ fp.write('\t<string>6.0</string>\n')
+ fp.write('\t<key>CFBundleName</key>\n')
+ fp.write('\t<string>%s</string>\n' % product_name)
+ fp.write('\t<key>CFBundleShortVersionString</key>\n')
+ fp.write('\t<string>%s.%s.%s</string>\n' % (version_major, version_minor, version_build))
+ fp.write('</dict>\n')
+ fp.write('</plist>\n')
+fp.flush()
dding-right: 5px; } span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
/***************************************************************************

    vecstream.h

    streams with vector storage

    These types are useful if you want a persistent buffer for formatted
    text and you need to use it like a character array or character
    pointer, as you get read-only access to it without copying.  The
    storage is always guaranteed to be contiguous.  Writing to the
    stream may invalidate pointers to storage.

***************************************************************************/

#ifndef MAME_UTIL_VECSTREAM_H
#define MAME_UTIL_VECSTREAM_H

#pragma once

#include <algorithm>
#include <cassert>
#include <ios>
#include <istream>
#include <ostream>
#include <memory>
#include <ostream>
#include <streambuf>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

namespace util {

template <typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT> >
class basic_vectorbuf : public std::basic_streambuf<CharT, Traits>
{
public:
	typedef typename std::basic_streambuf<CharT, Traits>::char_type char_type;
	typedef typename std::basic_streambuf<CharT, Traits>::int_type  int_type;
	typedef typename std::basic_streambuf<CharT, Traits>::pos_type  pos_type;
	typedef typename std::basic_streambuf<CharT, Traits>::off_type  off_type;
	typedef Allocator                                               allocator_type;
	typedef std::vector<char_type, Allocator>                       vector_type;

	basic_vectorbuf(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_streambuf<CharT, Traits>(), m_mode(mode), m_storage(), m_threshold(nullptr)
	{
		setup();
	}

	basic_vectorbuf(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_streambuf<CharT, Traits>(), m_mode(mode), m_storage(content), m_threshold(nullptr)
	{
		setup();
	}

	basic_vectorbuf(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_streambuf<CharT, Traits>(), m_mode(mode), m_storage(std::move(content)), m_threshold(nullptr)
	{
		setup();
	}

	basic_vectorbuf(basic_vectorbuf const &that) : std::basic_streambuf<CharT, Traits>(that), m_mode(that.m_mode), m_storage(that.m_storage), m_threshold(nullptr)
	{
		adjust();
	}

	basic_vectorbuf(basic_vectorbuf &&that) : std::basic_streambuf<CharT, Traits>(that), m_mode(that.m_mode), m_storage(std::move(that.m_storage)), m_threshold(that.m_threshold)
	{
		that.clear();
	}

	vector_type const &vec() const
	{
		if (m_mode & std::ios_base::out)
		{
			if (this->pptr() > m_threshold) m_threshold = this->pptr();
			auto const base(this->pbase());
			auto const end(m_threshold - base);
			if (m_storage.size() > std::make_unsigned_t<decltype(end)>(end))
			{
				m_storage.resize(std::make_unsigned_t<decltype(end)>(end));
				assert(&m_storage[0] == base);
				auto const put_offset(this->pptr() - base);
				const_cast<basic_vectorbuf *>(this)->setp(base, base + put_offset);
				const_cast<basic_vectorbuf *>(this)->pbump(put_offset);
			}
		}
		return m_storage;
	}

	void vec(const vector_type &content)
	{
		m_storage = content;
		setup();
	}

	void vec(vector_type &&content)
	{
		m_storage = std::move(content);
		setup();
	}

	void clear()
	{
		m_storage.clear();
		setup();
	}

	void swap(basic_vectorbuf &that)
	{
		using std::swap;
		std::basic_streambuf<CharT, Traits>::swap(that);
		swap(m_mode, that.m_mode);
		swap(m_storage, that.m_storage);
		swap(m_threshold, that.m_threshold);
	}

	void reserve(typename vector_type::size_type size)
	{
		if ((m_mode & std::ios_base::out) && (m_storage.capacity() < size))
		{
			m_storage.reserve(size);
			adjust();
		}
	}

	basic_vectorbuf &operator=(basic_vectorbuf const &that)
	{
		std::basic_streambuf<CharT, Traits>::operator=(that);
		m_mode = that.m_mode;
		m_storage = that.m_storage;
		m_threshold = that.m_threshold;
		adjust();
		return *this;
	}

	basic_vectorbuf &operator=(basic_vectorbuf &&that)
	{
		std::basic_streambuf<CharT, Traits>::operator=(that);
		m_mode = that.m_mode;
		m_storage = std::move(that.m_storage);
		m_threshold = that.m_threshold;
		that.clear();
		return *this;
	}

protected:
	virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
	{
		bool const in(which & std::ios_base::in);
		bool const out(which & std::ios_base::out);
		if ((!in && !out) ||
			(in && out && (std::ios_base::cur == dir)) ||
			(in && !(m_mode & std::ios_base::in)) ||
			(out && !(m_mode & std::ios_base::out)))
		{
			return pos_type(off_type(-1));
		}
		maximise_egptr();
		off_type const end((m_mode & std::ios_base::out) ? off_type(m_threshold - this->pbase()) : off_type(m_storage.size()));
		switch (dir)
		{
		case std::ios_base::beg:
			break;
		case std::ios_base::end:
			off += end;
			break;
		case std::ios_base::cur:
			off += off_type(in ? (this->gptr() - this->eback()) : (this->pptr() - this->pbase()));
			break;
		default:
			return pos_type(off_type(-1));
		}
		if ((off_type(0) > off) || ((m_mode & std::ios_base::app) && out && (end != off))) return pos_type(off_type(-1));
		if ((out ? off_type(this->epptr() - this->pbase()) : end) < off) return pos_type(off_type(-1));
		if (out)
		{
			this->setp(this->pbase(), this->epptr());
			this->pbump(off);
			if (m_threshold < this->pptr()) m_threshold = this->pptr();
			if (m_mode & std::ios_base::in)
			{
				if (in) this->setg(this->eback(), this->eback() + off, m_threshold);
				else if (this->egptr() < m_threshold) this->setg(this->eback(), this->gptr(), m_threshold);
			}
		}
		else if (in)
		{
			this->setg(this->eback(), this->eback() + off, this->egptr());
		}
		return pos_type(off);
	}

	virtual pos_type seekpos(pos_type pos, std::ios_base::openmode which = std::ios_base::in |std:: ios_base::out) override
	{
		return seekoff(off_type(pos), std::ios_base::beg, which);
	}

	virtual int_type underflow() override
	{
		if (!this->gptr()) return Traits::eof();
		maximise_egptr();
		return (this->gptr() < this->egptr()) ? Traits::to_int_type(*this->gptr()) : Traits::eof();
	}

	virtual int_type overflow(int_type ch = Traits::eof()) override
	{
		if (!(m_mode & std::ios_base::out)) return Traits::eof();
		if (Traits::eq_int_type(ch, Traits::eof())) return Traits::not_eof(ch);
		auto const put_offset(this->pptr() - this->pbase() + 1);
		auto const threshold_offset((std::max)(m_threshold - this->pbase(), put_offset));
		m_storage.push_back(Traits::to_char_type(ch));
		m_storage.resize(m_storage.capacity());
		auto const base(&m_storage[0]);
		this->setp(base, base + m_storage.size());
		m_threshold = base + threshold_offset;
		if (m_mode & std::ios_base::in) this->setg(base, base + (this->gptr() - this->eback()), m_threshold);
		this->pbump(int(put_offset));
		return ch;
	}

	virtual int_type pbackfail(int_type ch = Traits::eof()) override
	{
		if (this->gptr() != this->eback())
		{
			if (Traits::eq_int_type(ch, Traits::eof()))
			{
				this->gbump(-1);
				return Traits::not_eof(ch);
			}
			else if (Traits::eq(Traits::to_char_type(ch), this->gptr()[-1]))
			{
				this->gbump(-1);
				return ch;
			}
			else if (m_mode & std::ios_base::out)
			{
				this->gbump(-1);
				*this->gptr() = Traits::to_char_type(ch);
				return ch;
			}
		}
		return Traits::eof();
	}

private:
	void setup()
	{
		if (m_mode & std::ios_base::out)
		{
			auto const end(m_storage.size());
			m_storage.resize(m_storage.capacity());
			if (m_storage.empty())
			{
				m_threshold = nullptr;
				this->setg(nullptr, nullptr, nullptr);
				this->setp(nullptr, nullptr);
			}
			else
			{
				auto const base(&m_storage[0]);
				m_threshold = base + end;
				this->setp(base, base + m_storage.size());
				if (m_mode & std::ios_base::in) this->setg(base, base, m_threshold);
			}
			if (m_mode & (std::ios_base::app | std::ios_base::ate)) this->pbump(int(unsigned(end)));
		}
		else if (m_storage.empty())
		{
			this->setg(nullptr, nullptr, nullptr);
		}
		else if (m_mode & std::ios_base::in)
		{
			auto const base(&m_storage[0]);
			this->setg(base, base, base + m_storage.size());
		}
	}

	void adjust()
	{
		auto const put_offset(this->pptr() - this->pbase());
		auto const get_offset(this->gptr() - this->eback());
		setup();
		if (m_mode & std::ios_base::out)
		{
			this->pbump(int(put_offset));
			m_threshold = this->pptr();
			if (m_mode & std::ios_base::in)
			{
				auto const base(&m_storage[0]);
				this->setg(base, base + get_offset, m_threshold);
			}
		}
		else if (m_mode & std::ios_base::in)
		{
			this->gbump(int(get_offset));
		}
	}

	void maximise_egptr()
	{
		if (m_mode & std::ios_base::out)
		{
			if (m_threshold < this->pptr()) m_threshold = this->pptr();
			if ((m_mode & std::ios_base::in) && (this->egptr() < m_threshold)) this->setg(this->eback(), this->gptr(), m_threshold);
		}
	}

	std::ios_base::openmode m_mode;
	mutable vector_type     m_storage;
	mutable CharT           *m_threshold;
};

template <typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT> >
class basic_ivectorstream : public std::basic_istream<CharT, Traits>
{
public:
	typedef typename basic_vectorbuf<CharT, Traits, Allocator>::vector_type vector_type;

	basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(mode) { }
	basic_ivectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { }
	basic_ivectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in) : std::basic_istream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { }

	basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return static_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_istream<CharT, Traits>::rdbuf()); }
	vector_type const &vec() const { return rdbuf()->vec(); }
	void vec(const vector_type &content) { rdbuf()->vec(content); }
	void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); }

	void swap(basic_ivectorstream &that) { std::basic_istream<CharT, Traits>::swap(that); rdbuf()->swap(*that.rdbuf()); }

private:
	basic_vectorbuf<CharT, Traits, Allocator> m_rdbuf;
};

template <typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT> >
class basic_ovectorstream : public std::basic_ostream<CharT, Traits>
{
public:
	typedef typename basic_vectorbuf<CharT, Traits, Allocator>::vector_type vector_type;

	basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(mode) { }
	basic_ovectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { }
	basic_ovectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::out) : std::basic_ostream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { }

	basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return static_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_ostream<CharT, Traits>::rdbuf()); }

	vector_type const &vec() const { return rdbuf()->vec(); }
	void vec(const vector_type &content) { rdbuf()->vec(content); }
	void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); }
	basic_ovectorstream &reserve(typename vector_type::size_type size) { rdbuf()->reserve(size); return *this; }

	void swap(basic_ovectorstream &that) { std::basic_ostream<CharT, Traits>::swap(that); rdbuf()->swap(*that.rdbuf()); }

private:
	basic_vectorbuf<CharT, Traits, Allocator> m_rdbuf;
};

template <typename CharT, typename Traits = std::char_traits<CharT>, typename Allocator = std::allocator<CharT> >
class basic_vectorstream : public std::basic_iostream<CharT, Traits>
{
public:
	typedef typename basic_vectorbuf<CharT, Traits, Allocator>::vector_type vector_type;

	basic_vectorstream(std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(mode) { }
	basic_vectorstream(vector_type const &content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(content, mode) { }
	basic_vectorstream(vector_type &&content, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) : std::basic_iostream<CharT, Traits>(&m_rdbuf), m_rdbuf(std::move(content), mode) { }

	basic_vectorbuf<CharT, Traits, Allocator> *rdbuf() const { return static_cast<basic_vectorbuf<CharT, Traits, Allocator> *>(std::basic_iostream<CharT, Traits>::rdbuf()); }

	vector_type const &vec() const { return rdbuf()->vec(); }
	void vec(const vector_type &content) { rdbuf()->vec(content); }
	void vec(vector_type &&content) { rdbuf()->vec(std::move(content)); }
	basic_vectorstream &reserve(typename vector_type::size_type size) { rdbuf()->reserve(size); return *this; }

	void swap(basic_vectorstream &that) { std::basic_iostream<CharT, Traits>::swap(that); rdbuf()->swap(*that.rdbuf()); }

private:
	basic_vectorbuf<CharT, Traits, Allocator> m_rdbuf;
};

typedef basic_ivectorstream<char>       ivectorstream;
typedef basic_ivectorstream<wchar_t>    wivectorstream;
typedef basic_ovectorstream<char>       ovectorstream;
typedef basic_ovectorstream<wchar_t>    wovectorstream;
typedef basic_vectorstream<char>        vectorstream;
typedef basic_vectorstream<wchar_t>     wvectorstream;

template <typename CharT, typename Traits, typename Allocator>
void swap(basic_vectorbuf<CharT, Traits, Allocator> &a, basic_vectorbuf<CharT, Traits, Allocator> &b) { a.swap(b); }

template <typename CharT, typename Traits, typename Allocator>
void swap(basic_ivectorstream<CharT, Traits, Allocator> &a, basic_ivectorstream<CharT, Traits, Allocator> &b) { a.swap(b); }
template <typename CharT, typename Traits, typename Allocator>
void swap(basic_ovectorstream<CharT, Traits, Allocator> &a, basic_ovectorstream<CharT, Traits, Allocator> &b) { a.swap(b); }
template <typename CharT, typename Traits, typename Allocator>
void swap(basic_vectorstream<CharT, Traits, Allocator> &a, basic_vectorstream<CharT, Traits, Allocator> &b) { a.swap(b); }

extern template class basic_ivectorstream<char>;
extern template class basic_ivectorstream<wchar_t>;
extern template class basic_ovectorstream<char>;
extern template class basic_ovectorstream<wchar_t>;
extern template class basic_vectorstream<char>;
extern template class basic_vectorstream<wchar_t>;

} // namespace util

#endif // MAME_UTIL_VECSTREAM_H