/***************************************************************************
    copyright           : (C) 2011 by Mathias Panzenböck
    email               : grosser.meister.morti@gmx.net
 ***************************************************************************/

/***************************************************************************
 *   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., 51 Franklin Street, Fifth Floor, Boston,            *
 *   MA  02110-1301  USA                                                   *
 ***************************************************************************/

#ifndef TAGLIB_MODFILEPRIVATE_H
#define TAGLIB_MODFILEPRIVATE_H

// some helper-macros only used internally by (s3m|it|xm)file.cpp
#define READ_ASSERT(cond)                                                 \
  do {                                                                    \
    if(!(cond)) {                                                         \
      setValid(false);                                                    \
      return;                                                             \
    }                                                                     \
  } while(0)

#define READ(setter, type, read)                                          \
  do {                                                                    \
    type number;                                                          \
    READ_ASSERT(read(number));                                            \
    setter(number);                                                       \
  } while(0)

#define READ_BYTE(setter) READ(setter, unsigned char, readByte)
#define READ_U16L(setter) READ(setter, unsigned short, readU16L)
#define READ_U32L(setter) READ(setter, unsigned long, readU32L)
#define READ_U16B(setter) READ(setter, unsigned short, readU16B)
#define READ_U32B(setter) READ(setter, unsigned long, readU32B)

#define READ_STRING(setter, size)                                         \
  do {                                                                    \
    String s;                                                             \
    READ_ASSERT(readString(s, size));                                     \
    setter(s);                                                            \
  } while(0)

#define READ_AS(type, name, read)                                         \
  type name = 0;                                                          \
  READ_ASSERT(read(name))

#define READ_BYTE_AS(name) READ_AS(unsigned char, name, readByte)
#define READ_U16L_AS(name) READ_AS(unsigned short, name, readU16L)
#define READ_U32L_AS(name) READ_AS(unsigned long, name, readU32L)
#define READ_U16B_AS(name) READ_AS(unsigned short, name, readU16B)
#define READ_U32B_AS(name) READ_AS(unsigned long, name, readU32B)

#define READ_STRING_AS(name, size)                                        \
  String name;                                                            \
  READ_ASSERT(readString(name, size))
#endif
