<commit_before>#ifndef  DISSENT_ANONYMITY_SHUFFLE_ROUND_H_GUARD
#define DISSENT_ANONYMITY_SHUFFLE_ROUND_H_GUARD

#include <QBitArray>
#include <QDataStream>
#include <QMetaEnum>
#include <QSharedPointer>

#include "Connections/Network.hpp"

#include "Log.hpp"
#include "Round.hpp"

namespace Dissent {
namespace Anonymity {

  /**
   * Dissent's shuffling algorithm.
   *
   * A subset of members, shufflers, provide a pair of public encryption keys
   * called inner and outer keys.  In the protocol these key pairs are
   * distributed first.  Some other subset of peers has a message they want to
   * share anonymously and those that do not have a null packet.  Each member
   * encrypts their message first with each inner key and then with each outer
   * key.  Keys are ordered by the peer Id of the owner from largest to
   * smallest largest in Integer format.  The resulting message is sent to the
   * first member in the shufflers group.  Each shuffler removes their outer
   * encryption, shuffles (permutes) the message order, and transmits the
   * resulting message to the next member.  When the last shuffler completes
   * their decryption and permutation, the message is broadcasted to all
   * members in the group.
   *
   * Each member broadcasts to a go along with the hash of all broadcast
   * messages received thus far if their inner encrypted message is present or
   * a no go if not.  If all members submit a go and have the same broadcast
   * message hash, each shuffler reveals their private keys.  Otherwise peers
   * begin a blame phase and broadcast their logs to each other.  Afterward,
   * each peer distributes the hash of the messages and the signature, so that
   * each other member can verify they are viewing the same state.  Each peer
   * will replay the round and determine the faulty peer.
   *
   * The blame phase is still being evolved.
   */

  class ShuffleRound : public Round {
    Q_OBJECT

    Q_ENUMS(State);
    Q_ENUMS(MessageType);

    public:
      /**
       * Various states that the system can be in during the shuffle
       */
      enum State {
        Offline,
        KeySharing,
        DataSubmission,
        WaitingForShuffle,
        Shuffling,
        WaitingForEncryptedInnerData,
        Verification,
        PrivateKeySharing,
        Decryption,
        BlameInit,
        BlameShare,
        BlameReviewing,
        Finished
      };

      /**
       * Converts an State into a QString
       * @param state value to convert
       */
      static QString StateToString(State state)
      {
        int index = staticMetaObject.indexOfEnumerator("State");
        return staticMetaObject.enumerator(index).valueToKey(state);
      }

      /**
       * Various message types sent and received
       */
      enum MessageType {
        PublicKeys,
        Data,
        ShuffleData,
        EncryptedData,
        GoMessage,
        NoGoMessage,
        PrivateKey,
        BlameData,
        BlameVerification
      };

      /**
       * Converts a MessageType into a QString
       * @param mt value to convert
       */
      static QString MessageTypeToString(MessageType mt)
      {
        int index = staticMetaObject.indexOfEnumerator("MessageType");
        return staticMetaObject.enumerator(index).valueToKey(mt);
      }

      /**
       * Block size for the cleartext shuffle data
       */
      static const int BlockSize = 1024;

      /**
       * Empty block used for nodes who do not send any data
       */
      static const QByteArray DefaultData;

      /**
       * Constructor
       * @param group Group used during this round
       * @param ident the local nodes credentials
       * @param round_id Unique round id (nonce)
       * @param network handles message sending
       * @param get_data requests data to share during this session
       */
      explicit ShuffleRound(const Group &group,
          const PrivateIdentity &ident, const Id &round_id,
          QSharedPointer<Network> network, GetDataCallback &get_data);

      /**
       * Deconstructor
       */
      virtual ~ShuffleRound();

      /**
       * Deletes each individual entry in a QVector of AsymmetricKeys
       * @param keys keys to delete
       */
      void DeleteKeys(QVector<AsymmetricKey *> &keys);

      /**
       * Returns the systems current state
       */
      inline State GetState() const { return _state; }

      /**
       * Returns the state at which the system began blame
       */
      inline State GetBlameState() const { return _blame_state; }

      /**
       * Inner and outer public keys are kept in reversed order, this returns
       * the public key index for a given group index.
       * @param idx the group index
       */
      inline int CalculateKidx(int idx) { return _shufflers.Count() - 1 - idx; }

      /**
       * Returns a list of members who have been blamed in the round
       */
      inline virtual const QVector<int> &GetBadMembers() const { return _bad_members; }

      /**
       * Returns the shufflers group
       */
      const Group &GetShufflers() { return _shufflers; }

      virtual bool Start();

      inline virtual QString ToString() const { return "ShuffleRound: " + GetRoundId().ToString(); }

    protected:
      virtual void ProcessData(const Id &from, const QByteArray &data);

      /**
       * Allows direct access to the message parsing without a try / catch
       * surrounding it
       * @param from the node the data is from
       * @param data input data
       */
      void ProcessDataBase(const Id &from, const QByteArray &data);

      /**
       * Parses incoming public key messages
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandlePublicKeys(QDataStream &stream, const Id &id);

      /**
       * First node receives data from all peers
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleData(QDataStream &stream, const Id &id);

      /**
       * Each node besides the first receives shuffled data
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleShuffle(QDataStream &stream, const Id &id);

      /**
       * The inner encrypted only messages sent by the last peer
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleDataBroadcast(QDataStream &stream, const Id &id);

      /**
       * Each peer sends a go / no go message
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleVerification(QDataStream &stream, bool go, const Id &id);

      /**
       * Each peer shares with each other their inner private keys
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandlePrivateKey(QDataStream &stream, const Id &id);

      /**
       * Each peer shares their incoming messages logs with each other in order
       * to reconstruct where something bad may have occurred
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleBlame(QDataStream &stream, const Id &id);

      /**
       * Prior to reviewing the blame data, shares the signatures of the blames
       * that they received
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleBlameVerification(QDataStream &stream, const Id &id);

      /**
       * Broadcasts the nodes inner and outer public keys to all other nodes
       */
      virtual void BroadcastPublicKeys();

      /**
       * Encrypts and submits the data block to the first node
       */
      virtual void SubmitData();

      /**
       * Takes input shuffle data, verifies no duplicate messages, decrypts a
       * layer and forwards onward or broadcasts to all nodes if it is the
       * final node
       */
      virtual void Shuffle();

      /**
       * After receiving the inner encrypted data, each node will send a go
       * or no go message.
       */
      virtual void VerifyInnerCiphertext();

      /**
       * Shares the inner private key with all nodes
       */
      virtual void BroadcastPrivateKey();

      /**
       * After receiving all inner keys, the node will decrypt the data blocks
       * and push "real" data into the listener to the round (session)
       */
      virtual void Decrypt();

      /**
       * Shares blame data (message log, outer private key, and a signature of
       * the hash of this message) with all other nodes.
       */
      virtual void StartBlame();

      /**
       * Broadcasts the hash and signature of all blame data received to other
       * nodes, so all nodes can be certain they are working from teh same
       * blame data.
       */
      virtual void BroadcastBlameVerification();

      /**
       * After receiving all blame verifications, begin blame round.
       */
      virtual void BlameRound();

      /**
       * Takes a data block and makes it proper encoding for the shuffle
       * @param data data input
       */
      QByteArray PrepareData();

      /**
       * Retrieves from a data block from shuffle data
       * @param data shuffle data
       */
      QByteArray ParseData(QByteArray data);

      /**
       * Group of members responsible for providing anonymity
       */
      Group _shufflers;

      /**
       * Is the node a shuffler?
       */
      bool _shuffler;

      /**
       * Local nodes current state
       */
      State _state;

      /**
       * Local nodes last state before blame
       */
      State _blame_state;

      /**
       * All the remote peers inner keys, in reverse order
       */
      QVector<AsymmetricKey *> _public_inner_keys;

      /**
       * All the remote peers outer keys, in reverse order
       */
      QVector<AsymmetricKey *> _public_outer_keys;

      /**
       * Counter for keeping track of keys received
       */
      int _keys_received;

      /**
       * The private inner encrypting key
       */
      QScopedPointer<AsymmetricKey> _inner_key;

      /**
       * The private outer encrypting key
       */
      QScopedPointer<AsymmetricKey> _outer_key;

      /**
       * All the remote peers inner private keys
       */
      QVector<AsymmetricKey *> _private_inner_keys;

      /**
       * All the remote peers outer private keys, used during a blame
       */
      QVector<AsymmetricKey *> _private_outer_keys;

      /**
       * Number of peers to have submitted data to first node or blame phase
       */
      int _data_received;

      /**
       * Number of peers to send a go message
       */
      int _go_count;

      /**
       * Blame verifications received
       */
      int _blame_verifications;

      /**
       * Stores the positively received goes by group index
       */
      QBitArray _go_received;

      /**
       * Stores the positively received goes by group index
       */
      QBitArray _go;

      /**
       * Data pushed into the shuffle
       */
      QVector<QByteArray> _shuffle_cleartext;

      /**
       * Data pulled from the shuffle
       */
      QVector<QByteArray> _shuffle_ciphertext;

      /**
       * Inner encrypted only data
       */
      QVector<QByteArray> _encrypted_data;

      /**
       * Local nodes inner onion ciphertext
       */
      QByteArray _inner_ciphertext;

      /**
       * Local nodes outer onion ciphertext
       */
      QByteArray _outer_ciphertext;

      /**
       * Stores all validated messages that arrived before start was called
       */
      Log _offline_log;

      /**
       * Stores all validated incoming messages
       */
      Log _log;

      /**
       * Locally generated broadcast hash
       */
      QByteArray _broadcast_hash;

      /**
       * Stores peers incoming / outgoing broadcasted components
       */
      QVector<QByteArray> _broadcast_hashes;

      /**
       * Maintains who has and has not sent a blame message yet
       */
      QBitArray _blame_received;

      /**
       * Stores all the in blame logs
       */
      QVector<Log> _logs;

      /**
       * Stores all the shortened blame messages
       */
      QVector<QByteArray> _blame_hash;

      /**
       * Stores all the blame verifications
       */
      QVector<QByteArray> _blame_signatures;

      typedef QPair<QVector<QByteArray>, QVector<QByteArray> > HashSig;

      /**
       * Store remote blame hash / signatures until we have received all blame data
       */
      QVector<HashSig> _blame_verification_msgs;

      /**
       * Received a blame verification from the remote peer
       */
      QBitArray _received_blame_verification;

      /**
       * List of the index of all bad peers
       */
      QVector<int> _bad_members;
  };
}
}

#endif
<commit_msg>Adding note on anonymity to shuffleround<commit_after>#ifndef  DISSENT_ANONYMITY_SHUFFLE_ROUND_H_GUARD
#define DISSENT_ANONYMITY_SHUFFLE_ROUND_H_GUARD

#include <QBitArray>
#include <QDataStream>
#include <QMetaEnum>
#include <QSharedPointer>

#include "Connections/Network.hpp"

#include "Log.hpp"
#include "Round.hpp"

namespace Dissent {
namespace Anonymity {

  /**
   * Dissent's shuffling algorithm.
   *
   * A subset of members, shufflers, provide a pair of public encryption keys
   * called inner and outer keys.  In the protocol these key pairs are
   * distributed first.  Some other subset of peers has a message they want to
   * share anonymously and those that do not have a null packet.  Each member
   * encrypts their message first with each inner key and then with each outer
   * key.  Keys are ordered by the peer Id of the owner from largest to
   * smallest largest in Integer format.  The resulting message is sent to the
   * first member in the shufflers group.  Each shuffler removes their outer
   * encryption, shuffles (permutes) the message order, and transmits the
   * resulting message to the next member.  When the last shuffler completes
   * their decryption and permutation, the message is broadcasted to all
   * members in the group.
   *
   * Each member broadcasts to a go along with the hash of all broadcast
   * messages received thus far if their inner encrypted message is present or
   * a no go if not.  If all members submit a go and have the same broadcast
   * message hash, each shuffler reveals their private keys.  Otherwise peers
   * begin a blame phase and broadcast their logs to each other.  Afterward,
   * each peer distributes the hash of the messages and the signature, so that
   * each other member can verify they are viewing the same state.  Each peer
   * will replay the round and determine the faulty peer.
   *
   * The blame phase is still being evolved.
   *
   * @TODO XXX: In the client/server model, the servers should each decrypt
   * the ciphertext set and send the signed plaintex messages to the clients
   */

  class ShuffleRound : public Round {
    Q_OBJECT

    Q_ENUMS(State);
    Q_ENUMS(MessageType);

    public:
      /**
       * Various states that the system can be in during the shuffle
       */
      enum State {
        Offline,
        KeySharing,
        DataSubmission,
        WaitingForShuffle,
        Shuffling,
        WaitingForEncryptedInnerData,
        Verification,
        PrivateKeySharing,
        Decryption,
        BlameInit,
        BlameShare,
        BlameReviewing,
        Finished
      };

      /**
       * Converts an State into a QString
       * @param state value to convert
       */
      static QString StateToString(State state)
      {
        int index = staticMetaObject.indexOfEnumerator("State");
        return staticMetaObject.enumerator(index).valueToKey(state);
      }

      /**
       * Various message types sent and received
       */
      enum MessageType {
        PublicKeys,
        Data,
        ShuffleData,
        EncryptedData,
        GoMessage,
        NoGoMessage,
        PrivateKey,
        BlameData,
        BlameVerification
      };

      /**
       * Converts a MessageType into a QString
       * @param mt value to convert
       */
      static QString MessageTypeToString(MessageType mt)
      {
        int index = staticMetaObject.indexOfEnumerator("MessageType");
        return staticMetaObject.enumerator(index).valueToKey(mt);
      }

      /**
       * Block size for the cleartext shuffle data
       */
      static const int BlockSize = 1024;

      /**
       * Empty block used for nodes who do not send any data
       */
      static const QByteArray DefaultData;

      /**
       * Constructor
       * @param group Group used during this round
       * @param ident the local nodes credentials
       * @param round_id Unique round id (nonce)
       * @param network handles message sending
       * @param get_data requests data to share during this session
       */
      explicit ShuffleRound(const Group &group,
          const PrivateIdentity &ident, const Id &round_id,
          QSharedPointer<Network> network, GetDataCallback &get_data);

      /**
       * Deconstructor
       */
      virtual ~ShuffleRound();

      /**
       * Deletes each individual entry in a QVector of AsymmetricKeys
       * @param keys keys to delete
       */
      void DeleteKeys(QVector<AsymmetricKey *> &keys);

      /**
       * Returns the systems current state
       */
      inline State GetState() const { return _state; }

      /**
       * Returns the state at which the system began blame
       */
      inline State GetBlameState() const { return _blame_state; }

      /**
       * Inner and outer public keys are kept in reversed order, this returns
       * the public key index for a given group index.
       * @param idx the group index
       */
      inline int CalculateKidx(int idx) { return _shufflers.Count() - 1 - idx; }

      /**
       * Returns a list of members who have been blamed in the round
       */
      inline virtual const QVector<int> &GetBadMembers() const { return _bad_members; }

      /**
       * Returns the shufflers group
       */
      const Group &GetShufflers() { return _shufflers; }

      virtual bool Start();

      inline virtual QString ToString() const { return "ShuffleRound: " + GetRoundId().ToString(); }

    protected:
      virtual void ProcessData(const Id &from, const QByteArray &data);

      /**
       * Allows direct access to the message parsing without a try / catch
       * surrounding it
       * @param from the node the data is from
       * @param data input data
       */
      void ProcessDataBase(const Id &from, const QByteArray &data);

      /**
       * Parses incoming public key messages
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandlePublicKeys(QDataStream &stream, const Id &id);

      /**
       * First node receives data from all peers
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleData(QDataStream &stream, const Id &id);

      /**
       * Each node besides the first receives shuffled data
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleShuffle(QDataStream &stream, const Id &id);

      /**
       * The inner encrypted only messages sent by the last peer
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleDataBroadcast(QDataStream &stream, const Id &id);

      /**
       * Each peer sends a go / no go message
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleVerification(QDataStream &stream, bool go, const Id &id);

      /**
       * Each peer shares with each other their inner private keys
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandlePrivateKey(QDataStream &stream, const Id &id);

      /**
       * Each peer shares their incoming messages logs with each other in order
       * to reconstruct where something bad may have occurred
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleBlame(QDataStream &stream, const Id &id);

      /**
       * Prior to reviewing the blame data, shares the signatures of the blames
       * that they received
       * @param stream serialized message
       * @param id the remote peer sending the message
       */
      void HandleBlameVerification(QDataStream &stream, const Id &id);

      /**
       * Broadcasts the nodes inner and outer public keys to all other nodes
       */
      virtual void BroadcastPublicKeys();

      /**
       * Encrypts and submits the data block to the first node
       */
      virtual void SubmitData();

      /**
       * Takes input shuffle data, verifies no duplicate messages, decrypts a
       * layer and forwards onward or broadcasts to all nodes if it is the
       * final node
       */
      virtual void Shuffle();

      /**
       * After receiving the inner encrypted data, each node will send a go
       * or no go message.
       */
      virtual void VerifyInnerCiphertext();

      /**
       * Shares the inner private key with all nodes
       */
      virtual void BroadcastPrivateKey();

      /**
       * After receiving all inner keys, the node will decrypt the data blocks
       * and push "real" data into the listener to the round (session)
       */
      virtual void Decrypt();

      /**
       * Shares blame data (message log, outer private key, and a signature of
       * the hash of this message) with all other nodes.
       */
      virtual void StartBlame();

      /**
       * Broadcasts the hash and signature of all blame data received to other
       * nodes, so all nodes can be certain they are working from teh same
       * blame data.
       */
      virtual void BroadcastBlameVerification();

      /**
       * After receiving all blame verifications, begin blame round.
       */
      virtual void BlameRound();

      /**
       * Takes a data block and makes it proper encoding for the shuffle
       * @param data data input
       */
      QByteArray PrepareData();

      /**
       * Retrieves from a data block from shuffle data
       * @param data shuffle data
       */
      QByteArray ParseData(QByteArray data);

      /**
       * Group of members responsible for providing anonymity
       */
      Group _shufflers;

      /**
       * Is the node a shuffler?
       */
      bool _shuffler;

      /**
       * Local nodes current state
       */
      State _state;

      /**
       * Local nodes last state before blame
       */
      State _blame_state;

      /**
       * All the remote peers inner keys, in reverse order
       */
      QVector<AsymmetricKey *> _public_inner_keys;

      /**
       * All the remote peers outer keys, in reverse order
       */
      QVector<AsymmetricKey *> _public_outer_keys;

      /**
       * Counter for keeping track of keys received
       */
      int _keys_received;

      /**
       * The private inner encrypting key
       */
      QScopedPointer<AsymmetricKey> _inner_key;

      /**
       * The private outer encrypting key
       */
      QScopedPointer<AsymmetricKey> _outer_key;

      /**
       * All the remote peers inner private keys
       */
      QVector<AsymmetricKey *> _private_inner_keys;

      /**
       * All the remote peers outer private keys, used during a blame
       */
      QVector<AsymmetricKey *> _private_outer_keys;

      /**
       * Number of peers to have submitted data to first node or blame phase
       */
      int _data_received;

      /**
       * Number of peers to send a go message
       */
      int _go_count;

      /**
       * Blame verifications received
       */
      int _blame_verifications;

      /**
       * Stores the positively received goes by group index
       */
      QBitArray _go_received;

      /**
       * Stores the positively received goes by group index
       */
      QBitArray _go;

      /**
       * Data pushed into the shuffle
       */
      QVector<QByteArray> _shuffle_cleartext;

      /**
       * Data pulled from the shuffle
       */
      QVector<QByteArray> _shuffle_ciphertext;

      /**
       * Inner encrypted only data
       */
      QVector<QByteArray> _encrypted_data;

      /**
       * Local nodes inner onion ciphertext
       */
      QByteArray _inner_ciphertext;

      /**
       * Local nodes outer onion ciphertext
       */
      QByteArray _outer_ciphertext;

      /**
       * Stores all validated messages that arrived before start was called
       */
      Log _offline_log;

      /**
       * Stores all validated incoming messages
       */
      Log _log;

      /**
       * Locally generated broadcast hash
       */
      QByteArray _broadcast_hash;

      /**
       * Stores peers incoming / outgoing broadcasted components
       */
      QVector<QByteArray> _broadcast_hashes;

      /**
       * Maintains who has and has not sent a blame message yet
       */
      QBitArray _blame_received;

      /**
       * Stores all the in blame logs
       */
      QVector<Log> _logs;

      /**
       * Stores all the shortened blame messages
       */
      QVector<QByteArray> _blame_hash;

      /**
       * Stores all the blame verifications
       */
      QVector<QByteArray> _blame_signatures;

      typedef QPair<QVector<QByteArray>, QVector<QByteArray> > HashSig;

      /**
       * Store remote blame hash / signatures until we have received all blame data
       */
      QVector<HashSig> _blame_verification_msgs;

      /**
       * Received a blame verification from the remote peer
       */
      QBitArray _received_blame_verification;

      /**
       * List of the index of all bad peers
       */
      QVector<int> _bad_members;
  };
}
}

#endif
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Generic Win32 window class.
 *//*--------------------------------------------------------------------*/

#include "tcuWin32Window.hpp"

namespace tcu
{
namespace win32
{

static LRESULT CALLBACK windowProcCallback (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	Window* window = reinterpret_cast<Window*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
	if (window)
		return window->windowProc(uMsg, wParam, lParam);
	else
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

Window::Window (HINSTANCE instance, int width, int height)
	: m_window	(DE_NULL)
{
	try
	{
		static const char	s_className[]	= "dEQP Test Process Class";
		static const char	s_windowName[]	= "dEQP Test Process";

		{
			WNDCLASS wndClass;
			memset(&wndClass, 0, sizeof(wndClass));
			wndClass.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
			wndClass.lpfnWndProc	= windowProcCallback;
			wndClass.cbClsExtra		= 0;
			wndClass.cbWndExtra		= 0;
			wndClass.hInstance		= instance;
			wndClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
			wndClass.hCursor		= LoadCursor(NULL, IDC_ARROW);
			wndClass.hbrBackground	= CreateSolidBrush(RGB(0, 0, 0));
			wndClass.lpszMenuName	= NULL;
			wndClass.lpszClassName	= s_className;

			RegisterClass(&wndClass);
		}

		m_window = CreateWindow(s_className, s_windowName,
								WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW,
								CW_USEDEFAULT, CW_USEDEFAULT,
								width, height,
								NULL, NULL, instance, NULL);

		if (!m_window)
			TCU_THROW(ResourceError, "Failed to create Win32 window");

		// Store this as userdata
		SetWindowLongPtr(m_window, GWLP_USERDATA, (LONG_PTR)this);

		setSize(width, height);
	}
	catch (...)
	{
		if (m_window)
			DestroyWindow(m_window);

		throw;
	}
}

Window::~Window (void)
{
	if (m_window)
	{
		// Clear this pointer from windowproc
		SetWindowLongPtr(m_window, GWLP_USERDATA, 0);
	}

	DestroyWindow(m_window);
}

void Window::setVisible (bool visible)
{
	ShowWindow(m_window, visible ? SW_SHOW : SW_HIDE);
}

void Window::setSize (int width, int height)
{
	RECT rc;

	rc.left		= 0;
	rc.top		= 0;
	rc.right	= width;
	rc.bottom	= height;

	if (!AdjustWindowRect(&rc, GetWindowLong(m_window, GWL_STYLE), GetMenu(m_window) != NULL))
		TCU_THROW(TestError, "AdjustWindowRect() failed");

	if (!SetWindowPos(m_window, NULL, 0, 0,
					  rc.right - rc.left, rc.bottom - rc.top,
					  SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER))
		TCU_THROW(TestError, "SetWindowPos() failed");
}

IVec2 Window::getSize (void) const
{
	RECT rc;
	if (!GetClientRect(m_window, &rc))
		TCU_THROW(TestError, "GetClientRect() failed");

	return IVec2(rc.right - rc.left,
				 rc.bottom - rc.top);
}

void Window::processEvents (void)
{
	MSG msg;
	while (PeekMessage(&msg, m_window, 0, 0, PM_REMOVE))
		DispatchMessage(&msg);
}

LRESULT Window::windowProc (UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		// \todo [2014-03-12 pyry] Handle WM_SIZE?

		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;

		case WM_KEYDOWN:
			if (wParam == VK_ESCAPE)
			{
				PostQuitMessage(0);
				return 0;
			}
			// fall-through

		default:
			return DefWindowProc(m_window, uMsg, wParam, lParam);
	}
}

} // win32
} // tcu
<commit_msg>Change win32 window style to WS_POPUP<commit_after>/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Generic Win32 window class.
 *//*--------------------------------------------------------------------*/

#include "tcuWin32Window.hpp"

namespace tcu
{
namespace win32
{

static LRESULT CALLBACK windowProcCallback (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	Window* window = reinterpret_cast<Window*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
	if (window)
		return window->windowProc(uMsg, wParam, lParam);
	else
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

Window::Window (HINSTANCE instance, int width, int height)
	: m_window	(DE_NULL)
{
	try
	{
		static const char	s_className[]	= "dEQP Test Process Class";
		static const char	s_windowName[]	= "dEQP Test Process";

		{
			WNDCLASS wndClass;
			memset(&wndClass, 0, sizeof(wndClass));
			wndClass.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
			wndClass.lpfnWndProc	= windowProcCallback;
			wndClass.cbClsExtra		= 0;
			wndClass.cbWndExtra		= 0;
			wndClass.hInstance		= instance;
			wndClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
			wndClass.hCursor		= LoadCursor(NULL, IDC_ARROW);
			wndClass.hbrBackground	= CreateSolidBrush(RGB(0, 0, 0));
			wndClass.lpszMenuName	= NULL;
			wndClass.lpszClassName	= s_className;

			RegisterClass(&wndClass);
		}

		m_window = CreateWindow(s_className, s_windowName,
								WS_CLIPCHILDREN | WS_POPUP,
								CW_USEDEFAULT, CW_USEDEFAULT,
								width, height,
								NULL, NULL, instance, NULL);

		if (!m_window)
			TCU_THROW(ResourceError, "Failed to create Win32 window");

		// Store this as userdata
		SetWindowLongPtr(m_window, GWLP_USERDATA, (LONG_PTR)this);

		setSize(width, height);
	}
	catch (...)
	{
		if (m_window)
			DestroyWindow(m_window);

		throw;
	}
}

Window::~Window (void)
{
	if (m_window)
	{
		// Clear this pointer from windowproc
		SetWindowLongPtr(m_window, GWLP_USERDATA, 0);
	}

	DestroyWindow(m_window);
}

void Window::setVisible (bool visible)
{
	ShowWindow(m_window, visible ? SW_SHOW : SW_HIDE);
}

void Window::setSize (int width, int height)
{
	RECT rc;

	rc.left		= 0;
	rc.top		= 0;
	rc.right	= width;
	rc.bottom	= height;

	if (!AdjustWindowRect(&rc, GetWindowLong(m_window, GWL_STYLE), GetMenu(m_window) != NULL))
		TCU_THROW(TestError, "AdjustWindowRect() failed");

	if (!SetWindowPos(m_window, NULL, 0, 0,
					  rc.right - rc.left, rc.bottom - rc.top,
					  SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER))
		TCU_THROW(TestError, "SetWindowPos() failed");
}

IVec2 Window::getSize (void) const
{
	RECT rc;
	if (!GetClientRect(m_window, &rc))
		TCU_THROW(TestError, "GetClientRect() failed");

	return IVec2(rc.right - rc.left,
				 rc.bottom - rc.top);
}

void Window::processEvents (void)
{
	MSG msg;
	while (PeekMessage(&msg, m_window, 0, 0, PM_REMOVE))
		DispatchMessage(&msg);
}

LRESULT Window::windowProc (UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
		// \todo [2014-03-12 pyry] Handle WM_SIZE?

		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;

		case WM_KEYDOWN:
			if (wParam == VK_ESCAPE)
			{
				PostQuitMessage(0);
				return 0;
			}
			// fall-through

		default:
			return DefWindowProc(m_window, uMsg, wParam, lParam);
	}
}

} // win32
} // tcu
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: saxnamespacefilter.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: kz $ $Date: 2004-02-25 17:55:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
               with solaris headers ...
*/
#include <vector>

#include <stdio.h>

#include <xml/saxnamespacefilter.hxx>
#include <xml/attributelist.hxx>

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::uno;

const OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" ));
const OUString aXMLAttributeType( RTL_CONSTASCII_USTRINGPARAM( "CDATA" ));

namespace framework{

SaxNamespaceFilter::SaxNamespaceFilter( Reference< XDocumentHandler >& rSax1DocumentHandler ) :
    ThreadHelpBase( &Application::GetSolarMutex() ), OWeakObject(),
    xDocumentHandler( rSax1DocumentHandler ),
    m_xLocator( 0 ),
    m_nDepth( 0 )
{
}

SaxNamespaceFilter::~SaxNamespaceFilter()
{
}

Any SAL_CALL SaxNamespaceFilter::queryInterface( const Type & rType ) throw( RuntimeException )
{
    Any a = ::cppu::queryInterface(
                rType ,
                SAL_STATIC_CAST( XDocumentHandler*, this ));
    if ( a.hasValue() )
        return a;

    return OWeakObject::queryInterface( rType );
}

// XDocumentHandler
void SAL_CALL SaxNamespaceFilter::startDocument(void)
    throw ( SAXException, RuntimeException )
{
}

void SAL_CALL SaxNamespaceFilter::endDocument(void)
    throw(  SAXException, RuntimeException )
{
}

void SAL_CALL SaxNamespaceFilter::startElement(
    const rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
    throw(  SAXException, RuntimeException )
{
    XMLNamespaces aXMLNamespaces;
    if ( m_aNamespaceStack.size() > 0 )
        aXMLNamespaces = m_aNamespaceStack.top();

    AttributeListImpl* pNewList = new AttributeListImpl();

    // examine all namespaces for this level
    ::std::vector< int > aAttributeIndexes;
    {
        for ( int i=0; i< xAttribs->getLength(); i++ )
        {
            OUString aName = xAttribs->getNameByIndex( i );
            if ( aName.compareTo( aXMLAttributeNamespace, aXMLAttributeNamespace.getLength() ) == 0 )
                aXMLNamespaces.addNamespace( aName, xAttribs->getValueByIndex( i ));
            else
                aAttributeIndexes.push_back( i );
        }
    }

    // current namespaces for this level
    m_aNamespaceStack.push( aXMLNamespaces );

    try
    {
        // apply namespaces to all remaing attributes
        for ( sal_uInt32 i=0; i< aAttributeIndexes.size(); i++ )
        {
            OUString aAttributeName          = xAttribs->getNameByIndex( aAttributeIndexes[i] );
            OUString aValue                  = xAttribs->getValueByIndex( aAttributeIndexes[i] );
            OUString aNamespaceAttributeName = aXMLNamespaces.applyNSToAttributeName( aAttributeName );
            pNewList->addAttribute( aNamespaceAttributeName, aXMLAttributeType, aValue );
        }
    }
    catch ( SAXException& e )
    {
        e.Message = OUString( getErrorLineString() + e.Message );
        throw e;
    }

    OUString aNamespaceElementName;

    try
    {
         aNamespaceElementName = aXMLNamespaces.applyNSToElementName( aName );
    }
    catch ( SAXException& e )
    {
        e.Message = OUString( getErrorLineString() + e.Message );
        throw e;
    }

    xDocumentHandler->startElement( aNamespaceElementName, pNewList );
}

void SAL_CALL SaxNamespaceFilter::endElement(const rtl::OUString& aName)
    throw(  SAXException, RuntimeException )
{
    XMLNamespaces& aXMLNamespaces = m_aNamespaceStack.top();
    OUString aNamespaceElementName;

    try
    {
        aNamespaceElementName = aXMLNamespaces.applyNSToElementName( aName );
    }
    catch ( SAXException& e )
    {
        e.Message = OUString( getErrorLineString() + e.Message );
        throw e;
    }

    xDocumentHandler->endElement( aNamespaceElementName );
    m_aNamespaceStack.pop();
}

void SAL_CALL SaxNamespaceFilter::characters(const rtl::OUString& aChars)
    throw(  SAXException, RuntimeException )
{
    xDocumentHandler->characters( aChars );
}

void SAL_CALL SaxNamespaceFilter::ignorableWhitespace(const rtl::OUString& aWhitespaces)
    throw(  SAXException, RuntimeException )
{
    xDocumentHandler->ignorableWhitespace( aWhitespaces );
}

void SAL_CALL SaxNamespaceFilter::processingInstruction(
    const rtl::OUString& aTarget, const rtl::OUString& aData)
    throw(  SAXException, RuntimeException )
{
    xDocumentHandler->processingInstruction( aTarget, aData );
}

void SAL_CALL SaxNamespaceFilter::setDocumentLocator(
    const Reference< XLocator > &xLocator)
    throw(  SAXException, RuntimeException )
{
    m_xLocator = xLocator;
    xDocumentHandler->setDocumentLocator( xLocator );
}

OUString SaxNamespaceFilter::getErrorLineString()
{
    char buffer[32];

    if ( m_xLocator.is() )
    {
        snprintf( buffer, sizeof(buffer), "Line: %ld - ", m_xLocator->getLineNumber() );
        return OUString::createFromAscii( buffer );
    }
    else
        return OUString();
}

} // namespace
<commit_msg>INTEGRATION: CWS ooo19126 (1.2.334); FILE MERGED 2005/09/05 13:07:26 rt 1.2.334.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: saxnamespacefilter.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 02:04:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
               with solaris headers ...
*/
#include <vector>

#include <stdio.h>

#include <xml/saxnamespacefilter.hxx>
#include <xml/attributelist.hxx>

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::uno;

const OUString aXMLAttributeNamespace( RTL_CONSTASCII_USTRINGPARAM( "xmlns" ));
const OUString aXMLAttributeType( RTL_CONSTASCII_USTRINGPARAM( "CDATA" ));

namespace framework{

SaxNamespaceFilter::SaxNamespaceFilter( Reference< XDocumentHandler >& rSax1DocumentHandler ) :
    ThreadHelpBase( &Application::GetSolarMutex() ), OWeakObject(),
    xDocumentHandler( rSax1DocumentHandler ),
    m_xLocator( 0 ),
    m_nDepth( 0 )
{
}

SaxNamespaceFilter::~SaxNamespaceFilter()
{
}

Any SAL_CALL SaxNamespaceFilter::queryInterface( const Type & rType ) throw( RuntimeException )
{
    Any a = ::cppu::queryInterface(
                rType ,
                SAL_STATIC_CAST( XDocumentHandler*, this ));
    if ( a.hasValue() )
        return a;

    return OWeakObject::queryInterface( rType );
}

// XDocumentHandler
void SAL_CALL SaxNamespaceFilter::startDocument(void)
    throw ( SAXException, RuntimeException )
{
}

void SAL_CALL SaxNamespaceFilter::endDocument(void)
    throw(  SAXException, RuntimeException )
{
}

void SAL_CALL SaxNamespaceFilter::startElement(
    const rtl::OUString& aName, const Reference< XAttributeList > &xAttribs )
    throw(  SAXException, RuntimeException )
{
    XMLNamespaces aXMLNamespaces;
    if ( m_aNamespaceStack.size() > 0 )
        aXMLNamespaces = m_aNamespaceStack.top();

    AttributeListImpl* pNewList = new AttributeListImpl();

    // examine all namespaces for this level
    ::std::vector< int > aAttributeIndexes;
    {
        for ( int i=0; i< xAttribs->getLength(); i++ )
        {
            OUString aName = xAttribs->getNameByIndex( i );
            if ( aName.compareTo( aXMLAttributeNamespace, aXMLAttributeNamespace.getLength() ) == 0 )
                aXMLNamespaces.addNamespace( aName, xAttribs->getValueByIndex( i ));
            else
                aAttributeIndexes.push_back( i );
        }
    }

    // current namespaces for this level
    m_aNamespaceStack.push( aXMLNamespaces );

    try
    {
        // apply namespaces to all remaing attributes
        for ( sal_uInt32 i=0; i< aAttributeIndexes.size(); i++ )
        {
            OUString aAttributeName          = xAttribs->getNameByIndex( aAttributeIndexes[i] );
            OUString aValue                  = xAttribs->getValueByIndex( aAttributeIndexes[i] );
            OUString aNamespaceAttributeName = aXMLNamespaces.applyNSToAttributeName( aAttributeName );
            pNewList->addAttribute( aNamespaceAttributeName, aXMLAttributeType, aValue );
        }
    }
    catch ( SAXException& e )
    {
        e.Message = OUString( getErrorLineString() + e.Message );
        throw e;
    }

    OUString aNamespaceElementName;

    try
    {
         aNamespaceElementName = aXMLNamespaces.applyNSToElementName( aName );
    }
    catch ( SAXException& e )
    {
        e.Message = OUString( getErrorLineString() + e.Message );
        throw e;
    }

    xDocumentHandler->startElement( aNamespaceElementName, pNewList );
}

void SAL_CALL SaxNamespaceFilter::endElement(const rtl::OUString& aName)
    throw(  SAXException, RuntimeException )
{
    XMLNamespaces& aXMLNamespaces = m_aNamespaceStack.top();
    OUString aNamespaceElementName;

    try
    {
        aNamespaceElementName = aXMLNamespaces.applyNSToElementName( aName );
    }
    catch ( SAXException& e )
    {
        e.Message = OUString( getErrorLineString() + e.Message );
        throw e;
    }

    xDocumentHandler->endElement( aNamespaceElementName );
    m_aNamespaceStack.pop();
}

void SAL_CALL SaxNamespaceFilter::characters(const rtl::OUString& aChars)
    throw(  SAXException, RuntimeException )
{
    xDocumentHandler->characters( aChars );
}

void SAL_CALL SaxNamespaceFilter::ignorableWhitespace(const rtl::OUString& aWhitespaces)
    throw(  SAXException, RuntimeException )
{
    xDocumentHandler->ignorableWhitespace( aWhitespaces );
}

void SAL_CALL SaxNamespaceFilter::processingInstruction(
    const rtl::OUString& aTarget, const rtl::OUString& aData)
    throw(  SAXException, RuntimeException )
{
    xDocumentHandler->processingInstruction( aTarget, aData );
}

void SAL_CALL SaxNamespaceFilter::setDocumentLocator(
    const Reference< XLocator > &xLocator)
    throw(  SAXException, RuntimeException )
{
    m_xLocator = xLocator;
    xDocumentHandler->setDocumentLocator( xLocator );
}

OUString SaxNamespaceFilter::getErrorLineString()
{
    char buffer[32];

    if ( m_xLocator.is() )
    {
        snprintf( buffer, sizeof(buffer), "Line: %ld - ", m_xLocator->getLineNumber() );
        return OUString::createFromAscii( buffer );
    }
    else
        return OUString();
}

} // namespace
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: ZipFile.hxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-26 14:13:41 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _ZIP_FILE_HXX
#define _ZIP_FILE_HXX

#ifndef _BYTE_GRABBER_HXX_
#include <ByteGrabber.hxx>
#endif
#ifndef _HASHMAPS_HXX
#include <HashMaps.hxx>
#endif
#ifndef _INFLATER_HXX
#include <Inflater.hxx>
#endif
#ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPEXCEPTION_HPP_
#include <com/sun/star/packages/zip/ZipException.hpp>
#endif

namespace com { namespace sun { namespace star {
    namespace lang { class XMultiServiceFactory; }
    namespace ucb  { class XProgressHandler; }
} } }
namespace vos
{
    template < class T > class ORef;
}
/*
 * We impose arbitrary but reasonable limit on ZIP files.
 */

#define ZIP_MAXNAMELEN 512
#define ZIP_MAXEXTRA 256
#define ZIP_MAXENTRIES (0x10000 - 2)

typedef void* rtlCipher;
class ZipEnumeration;
class EncryptionData;

class ZipFile
{
protected:
    ::rtl::OUString sName;          /* zip file name */
    ::rtl::OUString sComment;       /* zip file comment */
    EntryHash       aEntries;
    ByteGrabber     aGrabber;
    Inflater        aInflater;
    com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
    com::sun::star::uno::Reference < com::sun::star::io::XSeekable > xSeek;
    const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > xFactory;
    ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XProgressHandler > xProgressHandler;

    com::sun::star::uno::Reference < com::sun::star::io::XInputStream >  createMemoryStream(
            ZipEntry & rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bRawStream,
            sal_Bool bDecrypt );

    com::sun::star::uno::Reference < com::sun::star::io::XInputStream >  createFileStream(
            ZipEntry & rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bRawStream,
            sal_Bool bDecrypt );

    com::sun::star::uno::Reference < com::sun::star::io::XInputStream >  createUnbufferedStream(
            ZipEntry & rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bRawStream,
            sal_Bool bDecrypt );

    sal_Bool hasValidPassword ( ZipEntry & rEntry, const vos::ORef < EncryptionData > &rData );

    sal_Bool checkSizeAndCRC( const ZipEntry& aEntry );

    sal_Int32 getCRC( sal_Int32 nOffset, sal_Int32 nSize );

    void getSizeAndCRC( sal_Int32 nOffset, sal_Int32 nCompressedSize, sal_Int32 *nSize, sal_Int32 *nCRC );

public:

    ZipFile( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &xInput,
             const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory,
             sal_Bool bInitialise
             )
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);

    ZipFile( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &xInput,
             const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory,
             sal_Bool bInitialise,
             sal_Bool bForceRecover,
             ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XProgressHandler > xProgress
             )
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);

    ~ZipFile();

    void setInputStream ( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewStream );
    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawStream(
            ZipEntry& rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bDecrypt)
        throw(::com::sun::star::io::IOException, ::com::sun::star::packages::zip::ZipException, ::com::sun::star::uno::RuntimeException);

    static void StaticGetCipher ( const vos::ORef < EncryptionData > & xEncryptionData, rtlCipher &rCipher );
    static void StaticFillHeader ( const vos::ORef < EncryptionData > & rData, sal_Int32 nSize, sal_Int8 * & pHeader );
    static sal_Bool StaticFillData ( vos::ORef < EncryptionData > & rData, sal_Int32 &rSize, ::com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &rStream );

    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(
            ZipEntry& rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bDecrypt )
        throw(::com::sun::star::io::IOException, ::com::sun::star::packages::zip::ZipException, ::com::sun::star::uno::RuntimeException);
    ::rtl::OUString SAL_CALL getName(  )
        throw(::com::sun::star::uno::RuntimeException);
    sal_Int32 SAL_CALL getSize(  )
        throw(::com::sun::star::uno::RuntimeException);

    ZipEnumeration * SAL_CALL entries(  );
protected:
    sal_Bool        readLOC ( ZipEntry &rEntry)
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
    sal_Int32       readCEN()
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
    sal_Int32       findEND()
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
    sal_Int32       recover()
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);

};

#endif
<commit_msg>INTEGRATION: CWS mav05 (1.18.18); FILE MERGED 2003/09/04 07:57:13 mav 1.18.18.3: #i15929# WrongPasswordException.idl is in packages now 2003/07/21 14:14:19 mav 1.18.18.2: #i15929# include MediaType in raw stream header, and other fixes 2003/07/18 14:20:47 mav 1.18.18.1: #i15929# support encryption in storages<commit_after>/*************************************************************************
 *
 *  $RCSfile: ZipFile.hxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: kz $ $Date: 2003-09-11 10:13:55 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): Martin Gallwey (gallwey@sun.com)
 *
 *
 ************************************************************************/
#ifndef _ZIP_FILE_HXX
#define _ZIP_FILE_HXX

#ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPEXCEPTION_HPP_
#include <com/sun/star/packages/zip/ZipException.hpp>
#endif
#ifndef _COM_SUN_STAR_PACKAGES_ZIP_ZIPIOEXCEPTION_HPP_
#include <com/sun/star/packages/zip/ZipIOException.hpp>
#endif
#ifndef _COM_SUN_STAR_PACKAGES_NOENCRYPTIONEXCEPTION_HPP_
#include <com/sun/star/packages/NoEncryptionException.hpp>
#endif

#ifndef _COM_SUN_STAR_PACKAGES_WRONGPASSWORDEXCEPTION_HPP_
#include <com/sun/star/packages/WrongPasswordException.hpp>
#endif

#ifndef _BYTE_GRABBER_HXX_
#include <ByteGrabber.hxx>
#endif
#ifndef _HASHMAPS_HXX
#include <HashMaps.hxx>
#endif
#ifndef _INFLATER_HXX
#include <Inflater.hxx>
#endif

namespace com { namespace sun { namespace star {
    namespace lang { class XMultiServiceFactory; }
    namespace ucb  { class XProgressHandler; }
} } }
namespace vos
{
    template < class T > class ORef;
}
/*
 * We impose arbitrary but reasonable limit on ZIP files.
 */

#define ZIP_MAXNAMELEN 512
#define ZIP_MAXEXTRA 256
#define ZIP_MAXENTRIES (0x10000 - 2)

typedef void* rtlCipher;
class ZipEnumeration;
class EncryptionData;

class ZipFile
{
protected:
    ::rtl::OUString sName;          /* zip file name */
    ::rtl::OUString sComment;       /* zip file comment */
    EntryHash       aEntries;
    ByteGrabber     aGrabber;
    Inflater        aInflater;
    com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream;
    com::sun::star::uno::Reference < com::sun::star::io::XSeekable > xSeek;
    const ::com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > xFactory;
    ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XProgressHandler > xProgressHandler;

    com::sun::star::uno::Reference < com::sun::star::io::XInputStream >  createMemoryStream(
            ZipEntry & rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bRawStream,
            sal_Bool bDecrypt );

    com::sun::star::uno::Reference < com::sun::star::io::XInputStream >  createFileStream(
            ZipEntry & rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bRawStream,
            sal_Bool bDecrypt );

    // aMediaType parameter is used only for raw stream header creation
    com::sun::star::uno::Reference < com::sun::star::io::XInputStream >  createUnbufferedStream(
            ZipEntry & rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Int8 nStreamMode,
            sal_Bool bDecrypt,
            ::rtl::OUString aMediaType = ::rtl::OUString() );

    sal_Bool hasValidPassword ( ZipEntry & rEntry, const vos::ORef < EncryptionData > &rData );

    sal_Bool checkSizeAndCRC( const ZipEntry& aEntry );

    sal_Int32 getCRC( sal_Int32 nOffset, sal_Int32 nSize );

    void getSizeAndCRC( sal_Int32 nOffset, sal_Int32 nCompressedSize, sal_Int32 *nSize, sal_Int32 *nCRC );

public:

    ZipFile( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &xInput,
             const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory,
             sal_Bool bInitialise
             )
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);

    ZipFile( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &xInput,
             const com::sun::star::uno::Reference < com::sun::star::lang::XMultiServiceFactory > &xNewFactory,
             sal_Bool bInitialise,
             sal_Bool bForceRecover,
             ::com::sun::star::uno::Reference < ::com::sun::star::ucb::XProgressHandler > xProgress
             )
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);

    ~ZipFile();

    void setInputStream ( com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xNewStream );
    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getRawData(
            ZipEntry& rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bDecrypt)
        throw(::com::sun::star::io::IOException, ::com::sun::star::packages::zip::ZipException, ::com::sun::star::uno::RuntimeException);

    static void StaticGetCipher ( const vos::ORef < EncryptionData > & xEncryptionData, rtlCipher &rCipher );

    static void StaticFillHeader ( const vos::ORef < EncryptionData > & rData,
                                    sal_Int32 nSize,
                                    const ::rtl::OUString& aMediaType,
                                    sal_Int8 * & pHeader );

    static sal_Bool StaticFillData ( vos::ORef < EncryptionData > & rData,
                                     sal_Int32 &rSize,
                                     ::rtl::OUString& aMediaType,
                                     ::com::sun::star::uno::Reference < com::sun::star::io::XInputStream > &rStream );

    static ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > StaticGetDataFromRawStream(
            const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xStream,
            const vos::ORef < EncryptionData > &rData )
        throw ( ::com::sun::star::packages::WrongPasswordException,
                ::com::sun::star::packages::zip::ZipIOException,
                ::com::sun::star::uno::RuntimeException );

    static sal_Bool StaticHasValidPassword ( const ::com::sun::star::uno::Sequence< sal_Int8 > &aReadBuffer,
                                             const vos::ORef < EncryptionData > &rData );

    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(
            ZipEntry& rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bDecrypt )
        throw(::com::sun::star::io::IOException, ::com::sun::star::packages::zip::ZipException, ::com::sun::star::uno::RuntimeException);

    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getDataStream(
            ZipEntry& rEntry,
            const vos::ORef < EncryptionData > &rData,
            sal_Bool bDecrypt )
        throw ( ::com::sun::star::packages::WrongPasswordException,
                ::com::sun::star::io::IOException,
                ::com::sun::star::packages::zip::ZipException,
                ::com::sun::star::uno::RuntimeException );

    ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getWrappedRawStream(
            ZipEntry& rEntry,
            const vos::ORef < EncryptionData > &rData,
            const ::rtl::OUString& aMediaType )
        throw ( ::com::sun::star::packages::NoEncryptionException,
                ::com::sun::star::io::IOException,
                ::com::sun::star::packages::zip::ZipException,
                ::com::sun::star::uno::RuntimeException );

    ::rtl::OUString SAL_CALL getName(  )
        throw(::com::sun::star::uno::RuntimeException);
    sal_Int32 SAL_CALL getSize(  )
        throw(::com::sun::star::uno::RuntimeException);

    ZipEnumeration * SAL_CALL entries(  );
protected:
    sal_Bool        readLOC ( ZipEntry &rEntry)
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
    sal_Int32       readCEN()
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
    sal_Int32       findEND()
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);
    sal_Int32       recover()
        throw(::com::sun::star::io::IOException, com::sun::star::packages::zip::ZipException, com::sun::star::uno::RuntimeException);

};

#endif
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*! @file
    @brief  input クラス @n
			数値、文字列などの入力クラス
			Copyright 2017 Kunihito Hiramatsu
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>

extern "C" {

	char sci_getch(void);

};

namespace utils {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  標準入力ファンクタ
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class def_chainp {
		const char* str_;
		char		last_;
		bool		unget_;
	public:
		def_chainp(const char* str = nullptr) : str_(str), last_(0), unget_(false) { }

		void unget() {
			unget_ = true;
		}

		char operator() () {
			if(unget_) {
				unget_ = false;
			} else {
				if(str_ == nullptr) {
					last_ = sci_getch();
				} else {
					last_ = *str_;
					if(last_ != 0) { ++str_; }
				}
			}
			return last_;
		}
	};

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  汎用入力クラス
		@param[in]	INP	入力クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class INP>
	class basic_input {

		const char*	form_;

		INP			inp_;

		uint32_t bin_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '1') {
				a <<= 1;
				a += ch - '0';
			}
			return a;
		}

		uint32_t oct_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '7') {
				a <<= 3;
				a += ch - '0';
			}
			return a;
		}

		uint32_t dec_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '9') {
				a *= 10;
				a += ch - '0';
			}
			return a;
		}

		uint32_t hex_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0) {
				if(ch >= '0' && ch <= '9') {
					a <<= 4;
					a += ch - '0';
				} else if(ch >= 'A' && ch <= 'F') {
					a <<= 4;
					a += ch - 'A' + 10;
				} else if(ch >= 'a' && ch <= 'f') {
					a <<= 4;
					a += ch - 'a' + 10;
				} else {
					break;
				}
			}
			return a;
		}

		enum class mode : uint8_t {
			NONE,
			BIN,
			OCT,
			DEC,
			HEX,
		};
		mode	mode_;
		bool	err_;

		static uint16_t	cnvcnt_;

		enum class fmm : uint8_t {
			none,
			type,

		};

		void next_()
		{
			fmm cm = fmm::none;
			char ch;
			while((ch = *form_++) != 0) {
				switch(cm) {
				case fmm::none:
					if(ch == '[') {
						auto a = inp_();
						const char* p = form_;
						bool ok = false;
						while((ch = *p++) != 0 && ch != ']') {
							if(ch == a) ok = true;
						}
						form_ = p;
						if(!ok) {
							err_ = true;
							return;
						}
					} else if(ch == '%' && *form_ != '%') {
						cm = fmm::type;
					} else if(ch != inp_()) {
						err_ = true;
						return;
					}
					break;
				case fmm::type:
					if(ch == 'b' || ch == 'B') {
						mode_ = mode::BIN;
					} else if(ch == 'o' || ch == 'O') {
						mode_ = mode::OCT;
					} else if(ch == 'd' || ch == 'D') {
						mode_ = mode::DEC;
					} else if(ch == 'x' || ch == 'X') {
						mode_ = mode::HEX;
					} else {
						err_ = true;
					}
					return;
				}
			}
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	form	入力形式
			@param[in]	inp		変換文字列（nullptrの場合、sci_getch で取得）
		*/
		//-----------------------------------------------------------------//
		basic_input(const char* form, const char* inp = nullptr) : form_(form), inp_(inp),
			mode_(mode::NONE), err_(false)
		{
			cnvcnt_ = 0;
			next_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  正常変換数を取得
			@return 正常変換数
		*/
		//-----------------------------------------------------------------//
		static uint16_t get_conversion() { return cnvcnt_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  オペレーター「%」（int32_t）
			@param[in]	val	整数値
			@return	自分の参照
		*/
		//-----------------------------------------------------------------//
		basic_input& operator % (int32_t& val)
		{
			if(err_) return *this;

			bool neg = false;
			{
				auto s = inp_();
				if(s == '-') { neg = true; }
				else if(s == '+') { neg = false; }
				else inp_.unget();
			}
			uint32_t v = 0;
			switch(mode_) {
			case mode::BIN:
				v = bin_();
				break;
			case mode::OCT:
				v = oct_();
				break;
			case mode::DEC:
				v = dec_();
				break;
			case mode::HEX:
				v = hex_();
				break;
			default:
				err_ = true;
				break;
			}
			if(neg) val = -static_cast<int32_t>(v);
			else val = static_cast<int32_t>(v);
			if(!err_) {
				++cnvcnt_;
				inp_.unget();
				next_();
			}
			return *this;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  オペレーター「%」（uint32_t）
			@param[in]	val	整数値
			@return	自分の参照
		*/
		//-----------------------------------------------------------------//
		basic_input& operator % (uint32_t& val)
		{
			if(err_) return *this;

			uint32_t v = 0;
			switch(mode_) {
			case mode::BIN:
				v = bin_();
				break;
			case mode::OCT:
				v = oct_();
				break;
			case mode::DEC:
				v = dec_();
				break;
			case mode::HEX:
				v = hex_();
				break;
			default:
				err_ = true;
				break;
			}
			if(!err_) {
				++cnvcnt_;
				inp_.unget();
				next_();
				val = v;
			}
			return *this;
		}
	};

	template<class INP> uint16_t basic_input<INP>::cnvcnt_;

	typedef basic_input<def_chainp> input;

}
<commit_msg>update operator<commit_after>#pragma once
//=====================================================================//
/*! @file
    @brief  input クラス @n
			数値、文字列などの入力クラス
			Copyright 2017 Kunihito Hiramatsu
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <type_traits>

extern "C" {

	char sci_getch(void);

};

namespace utils {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  標準入力ファンクタ
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class def_chainp {
		const char* str_;
		char		last_;
		bool		unget_;
	public:
		def_chainp(const char* str = nullptr) : str_(str), last_(0), unget_(false) { }

		void unget() {
			unget_ = true;
		}

		char operator() () {
			if(unget_) {
				unget_ = false;
			} else {
				if(str_ == nullptr) {
					last_ = sci_getch();
				} else {
					last_ = *str_;
					if(last_ != 0) { ++str_; }
				}
			}
			return last_;
		}
	};

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  汎用入力クラス
		@param[in]	INP	入力クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class INP>
	class basic_input {

		const char*	form_;

		INP			inp_;

		uint32_t bin_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '1') {
				a <<= 1;
				a += ch - '0';
			}
			return a;
		}

		uint32_t oct_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '7') {
				a <<= 3;
				a += ch - '0';
			}
			return a;
		}

		uint32_t dec_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0 && ch >= '0' && ch <= '9') {
				a *= 10;
				a += ch - '0';
			}
			return a;
		}

		uint32_t hex_() {
			uint32_t a = 0;
			char ch;
			while((ch = inp_()) != 0) {
				if(ch >= '0' && ch <= '9') {
					a <<= 4;
					a += ch - '0';
				} else if(ch >= 'A' && ch <= 'F') {
					a <<= 4;
					a += ch - 'A' + 10;
				} else if(ch >= 'a' && ch <= 'f') {
					a <<= 4;
					a += ch - 'a' + 10;
				} else {
					break;
				}
			}
			return a;
		}

		enum class mode : uint8_t {
			NONE,
			BIN,
			OCT,
			DEC,
			HEX,
		};
		mode	mode_;
		bool	err_;

		int		num_;

		enum class fmm : uint8_t {
			none,
			type,

		};

		void next_()
		{
			fmm cm = fmm::none;
			char ch;
			while((ch = *form_++) != 0) {
				switch(cm) {
				case fmm::none:
					if(ch == '[') {
						auto a = inp_();
						const char* p = form_;
						bool ok = false;
						while((ch = *p++) != 0 && ch != ']') {
							if(ch == a) ok = true;
						}
						form_ = p;
						if(!ok) {
							err_ = true;
							return;
						}
					} else if(ch == '%' && *form_ != '%') {
						cm = fmm::type;
					} else if(ch != inp_()) {
						err_ = true;
						return;
					}
					break;
				case fmm::type:
					if(ch == 'b' || ch == 'B') {
						mode_ = mode::BIN;
					} else if(ch == 'o' || ch == 'O') {
						mode_ = mode::OCT;
					} else if(ch == 'd' || ch == 'D') {
						mode_ = mode::DEC;
					} else if(ch == 'x' || ch == 'X') {
						mode_ = mode::HEX;
					} else {
						err_ = true;
					}
					return;
				}
			}
			if(ch == 0 && inp_() == 0) ;
			else {
				err_ = true;
			}
		}

		int32_t nb_(bool sign = true)
		{
			bool neg = false;
			if(sign) {
				auto s = inp_();
				if(s == '-') { neg = true; }
				else if(s == '+') { neg = false; }
				else inp_.unget();
			}
			uint32_t v = 0;
			switch(mode_) {
			case mode::BIN:
				v = bin_();
				break;
			case mode::OCT:
				v = oct_();
				break;
			case mode::DEC:
				v = dec_();
				break;
			case mode::HEX:
				v = hex_();
				break;
			default:
				err_ = true;
				break;
			}
			if(!err_) {
				inp_.unget();
				next_();
				if(!err_) ++num_;
			}
			if(neg) return -static_cast<int32_t>(v);
			else return static_cast<int32_t>(v);
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
			@param[in]	form	入力形式
			@param[in]	inp		変換文字列（nullptrの場合、sci_getch で取得）
		*/
		//-----------------------------------------------------------------//
		basic_input(const char* form, const char* inp = nullptr) : form_(form), inp_(inp),
			mode_(mode::NONE), err_(false), num_(0)
		{
			next_();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  正常変換数を取得
			@return 正常変換数
		*/
		//-----------------------------------------------------------------//
		int num() const { return num_; }

		//-----------------------------------------------------------------//
		/*!
			@brief  テンプレート・オペレーター「%」
			@param[in]	val	整数型
			@return	自分の参照
		*/
		//-----------------------------------------------------------------//
		template <typename T>
		basic_input& operator % (T& val)
		{
			if(err_) return *this;
			val = nb_(!std::is_signed<T>::value);
			return *this;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  オペレーター「=」
		*/
		//-----------------------------------------------------------------//
		basic_input& operator = (const basic_input& in) { return *this; }
	};

	typedef basic_input<def_chainp> input;

}
<|endoftext|>