<commit_before>// Copyright 2008-present Contributors to the OpenImageIO project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md
#include "bmp_pvt.h"

OIIO_PLUGIN_NAMESPACE_BEGIN

using namespace bmp_pvt;

// Obligatory material to make this a recognizeable imageio plugin
OIIO_PLUGIN_EXPORTS_BEGIN

OIIO_EXPORT int bmp_imageio_version = OIIO_PLUGIN_VERSION;

OIIO_EXPORT const char*
bmp_imageio_library_version()
{
    return nullptr;
}

OIIO_EXPORT ImageInput*
bmp_input_imageio_create()
{
    return new BmpInput;
}

OIIO_EXPORT const char* bmp_input_extensions[] = { "bmp", nullptr };

OIIO_PLUGIN_EXPORTS_END

bool
BmpInput::valid_file(const std::string& filename) const
{
    FILE* fd = Filesystem::fopen(filename, "rb");
    if (!fd)
        return false;
    bmp_pvt::BmpFileHeader bmp_header;
    bool ok = bmp_header.read_header(fd) && bmp_header.isBmp();
    fclose(fd);
    return ok;
}

bool
BmpInput::open(const std::string& name, ImageSpec& spec)
{
    // saving 'name' for later use
    m_filename = name;

    m_fd = Filesystem::fopen(m_filename, "rb");
    if (!m_fd) {
        errorf("Could not open file \"%s\"", name);
        return false;
    }

    // we read header of the file that we think is BMP file
    if (!m_bmp_header.read_header(m_fd)) {
        errorf("\"%s\": wrong bmp header size", m_filename);
        close();
        return false;
    }
    if (!m_bmp_header.isBmp()) {
        errorf("\"%s\" is not a BMP file, magic number doesn't match",
               m_filename);
        close();
        return false;
    }
    if (!m_dib_header.read_header(m_fd)) {
        errorf("\"%s\": wrong bitmap header size", m_filename);
        close();
        return false;
    }

    const int nchannels = (m_dib_header.bpp == 32) ? 4 : 3;
    const int height    = (m_dib_header.height >= 0) ? m_dib_header.height
                                                  : -m_dib_header.height;
    m_spec = ImageSpec(m_dib_header.width, height, nchannels, TypeDesc::UINT8);
    m_spec.attribute("XResolution", (int)m_dib_header.hres);
    m_spec.attribute("YResolution", (int)m_dib_header.vres);
    m_spec.attribute("ResolutionUnit", "m");

    // computing size of one scanline - this is the size of one scanline that
    // is stored in the file, not in the memory
    int swidth = 0;
    switch (m_dib_header.bpp) {
    case 32:
    case 24:
        m_padded_scanline_size = ((m_spec.width * m_spec.nchannels) + 3) & ~3;
        break;
    case 16:
        m_padded_scanline_size = ((m_spec.width << 1) + 3) & ~3;
        m_spec.attribute("oiio:BitsPerSample", 4);
        break;
    case 8:
        m_padded_scanline_size = (m_spec.width + 3) & ~3;
        if (!read_color_table())
            return false;
        break;
    case 4:
        swidth                 = (m_spec.width + 1) / 2;
        m_padded_scanline_size = (swidth + 3) & ~3;
        if (!read_color_table())
            return false;
        break;
    case 1:
        swidth                 = (m_spec.width + 7) / 8;
        m_padded_scanline_size = (swidth + 3) & ~3;
        if (!read_color_table())
            return false;
        break;
    }

    // file pointer is set to the beginning of image data
    // we save this position - it will be helpfull in read_native_scanline
    m_image_start = Filesystem::ftell(m_fd);

    spec = m_spec;
    return true;
}

bool
BmpInput::read_native_scanline(int subimage, int miplevel, int y, int /*z*/,
                               void* data)
{
    lock_guard lock(*this);
    if (!seek_subimage(subimage, miplevel))
        return false;

    if (y < 0 || y > m_spec.height)
        return false;

    // if the height is positive scanlines are stored bottom-up
    if (m_dib_header.width >= 0)
        y = m_spec.height - y - 1;
    const int64_t scanline_off = y * m_padded_scanline_size;

    std::unique_ptr<unsigned char[]> fscanline(
        new unsigned char[m_padded_scanline_size]);
    Filesystem::fseek(m_fd, m_image_start + scanline_off, SEEK_SET);
    size_t n = fread(fscanline.get(), 1, m_padded_scanline_size, m_fd);
    if (n != (size_t)m_padded_scanline_size) {
        if (feof(m_fd))
            errorf("Hit end of file unexpectedly");
        else
            errorf("read error");
        return false;  // Read failed
    }

    // in each case we process only first m_spec.scanline_bytes () bytes
    // as only they contain information about pixels. The rest are just
    // because scanline size have to be 32-bit boundary
    if (m_dib_header.bpp == 24 || m_dib_header.bpp == 32) {
        for (unsigned int i = 0; i < m_spec.scanline_bytes();
             i += m_spec.nchannels)
            std::swap(fscanline[i], fscanline[i + 2]);
        memcpy(data, fscanline.get(), m_spec.scanline_bytes());
        return true;
    }

    size_t scanline_bytes = m_spec.scanline_bytes();
    std::unique_ptr<unsigned char[]> mscanline(
        new unsigned char[scanline_bytes]);
    if (m_dib_header.bpp == 16) {
        const uint16_t RED   = 0x7C00;
        const uint16_t GREEN = 0x03E0;
        const uint16_t BLUE  = 0x001F;
        for (unsigned int i = 0, j = 0; j < scanline_bytes; i += 2, j += 3) {
            uint16_t pixel   = (uint16_t) * (&fscanline[i]);
            mscanline[j]     = (uint8_t)((pixel & RED) >> 8);
            mscanline[j + 1] = (uint8_t)((pixel & GREEN) >> 4);
            mscanline[j + 2] = (uint8_t)(pixel & BLUE);
        }
    }
    if (m_dib_header.bpp == 8) {
        for (unsigned int i = 0, j = 0; j < scanline_bytes; ++i, j += 3) {
            mscanline[j]     = m_colortable[fscanline[i]].r;
            mscanline[j + 1] = m_colortable[fscanline[i]].g;
            mscanline[j + 2] = m_colortable[fscanline[i]].b;
        }
    }
    if (m_dib_header.bpp == 4) {
        for (unsigned int i = 0, j = 0; j + 6 < scanline_bytes; ++i, j += 6) {
            uint8_t mask     = 0xF0;
            mscanline[j]     = m_colortable[(fscanline[i] & mask) >> 4].r;
            mscanline[j + 1] = m_colortable[(fscanline[i] & mask) >> 4].g;
            mscanline[j + 2] = m_colortable[(fscanline[i] & mask) >> 4].b;
            mask             = 0x0F;
            mscanline[j + 3] = m_colortable[fscanline[i] & mask].r;
            mscanline[j + 4] = m_colortable[fscanline[i] & mask].g;
            mscanline[j + 5] = m_colortable[fscanline[i] & mask].b;
        }
    }
    if (m_dib_header.bpp == 1) {
        for (int64_t i = 0, k = 0; i < m_padded_scanline_size; ++i) {
            for (int j = 7; j >= 0; --j, k += 3) {
                if (size_t(k + 2) >= scanline_bytes)
                    break;
                int index = 0;
                if (fscanline[i] & (1 << j))
                    index = 1;
                mscanline[k]     = m_colortable[index].r;
                mscanline[k + 1] = m_colortable[index].g;
                mscanline[k + 2] = m_colortable[index].b;
            }
        }
    }
    memcpy(data, &mscanline[0], scanline_bytes);
    return true;
}

bool inline BmpInput::close(void)
{
    if (m_fd) {
        fclose(m_fd);
        m_fd = NULL;
    }
    init();
    return true;
}

bool
BmpInput::read_color_table(void)
{
    // size of color table is defined  by m_dib_header.cpalete
    // if this field is 0 - color table has max colors:
    // pow(2, m_dib_header.cpalete) otherwise color table have
    // m_dib_header.cpalete entries
    const int32_t colors = (m_dib_header.cpalete) ? m_dib_header.cpalete
                                                  : 1 << m_dib_header.bpp;
    size_t entry_size = 4;
    // if the file is OS V2 bitmap color table entr has only 3 bytes, not four
    if (m_dib_header.size == OS2_V1)
        entry_size = 3;
    m_colortable.resize(colors);
    for (int i = 0; i < colors; i++) {
        size_t n = fread(&m_colortable[i], 1, entry_size, m_fd);
        if (n != entry_size) {
            if (feof(m_fd))
                errorf(
                    "Hit end of file unexpectedly while reading color table");
            else
                errorf("read error while reading color table");
            return false;  // Read failed
        }
    }
    return true;  // ok
}

OIIO_PLUGIN_NAMESPACE_END
<commit_msg>Fix bmp row order (#2776)<commit_after>// Copyright 2008-present Contributors to the OpenImageIO project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md
#include "bmp_pvt.h"

OIIO_PLUGIN_NAMESPACE_BEGIN

using namespace bmp_pvt;

// Obligatory material to make this a recognizeable imageio plugin
OIIO_PLUGIN_EXPORTS_BEGIN

OIIO_EXPORT int bmp_imageio_version = OIIO_PLUGIN_VERSION;

OIIO_EXPORT const char*
bmp_imageio_library_version()
{
    return nullptr;
}

OIIO_EXPORT ImageInput*
bmp_input_imageio_create()
{
    return new BmpInput;
}

OIIO_EXPORT const char* bmp_input_extensions[] = { "bmp", nullptr };

OIIO_PLUGIN_EXPORTS_END

bool
BmpInput::valid_file(const std::string& filename) const
{
    FILE* fd = Filesystem::fopen(filename, "rb");
    if (!fd)
        return false;
    bmp_pvt::BmpFileHeader bmp_header;
    bool ok = bmp_header.read_header(fd) && bmp_header.isBmp();
    fclose(fd);
    return ok;
}

bool
BmpInput::open(const std::string& name, ImageSpec& spec)
{
    // saving 'name' for later use
    m_filename = name;

    m_fd = Filesystem::fopen(m_filename, "rb");
    if (!m_fd) {
        errorf("Could not open file \"%s\"", name);
        return false;
    }

    // we read header of the file that we think is BMP file
    if (!m_bmp_header.read_header(m_fd)) {
        errorf("\"%s\": wrong bmp header size", m_filename);
        close();
        return false;
    }
    if (!m_bmp_header.isBmp()) {
        errorf("\"%s\" is not a BMP file, magic number doesn't match",
               m_filename);
        close();
        return false;
    }
    if (!m_dib_header.read_header(m_fd)) {
        errorf("\"%s\": wrong bitmap header size", m_filename);
        close();
        return false;
    }

    const int nchannels = (m_dib_header.bpp == 32) ? 4 : 3;
    const int height    = (m_dib_header.height >= 0) ? m_dib_header.height
                                                  : -m_dib_header.height;
    m_spec = ImageSpec(m_dib_header.width, height, nchannels, TypeDesc::UINT8);
    m_spec.attribute("XResolution", (int)m_dib_header.hres);
    m_spec.attribute("YResolution", (int)m_dib_header.vres);
    m_spec.attribute("ResolutionUnit", "m");

    // computing size of one scanline - this is the size of one scanline that
    // is stored in the file, not in the memory
    int swidth = 0;
    switch (m_dib_header.bpp) {
    case 32:
    case 24:
        m_padded_scanline_size = ((m_spec.width * m_spec.nchannels) + 3) & ~3;
        break;
    case 16:
        m_padded_scanline_size = ((m_spec.width << 1) + 3) & ~3;
        m_spec.attribute("oiio:BitsPerSample", 4);
        break;
    case 8:
        m_padded_scanline_size = (m_spec.width + 3) & ~3;
        if (!read_color_table())
            return false;
        break;
    case 4:
        swidth                 = (m_spec.width + 1) / 2;
        m_padded_scanline_size = (swidth + 3) & ~3;
        if (!read_color_table())
            return false;
        break;
    case 1:
        swidth                 = (m_spec.width + 7) / 8;
        m_padded_scanline_size = (swidth + 3) & ~3;
        if (!read_color_table())
            return false;
        break;
    }

    // file pointer is set to the beginning of image data
    // we save this position - it will be helpfull in read_native_scanline
    m_image_start = Filesystem::ftell(m_fd);

    spec = m_spec;
    return true;
}

bool
BmpInput::read_native_scanline(int subimage, int miplevel, int y, int /*z*/,
                               void* data)
{
    lock_guard lock(*this);
    if (!seek_subimage(subimage, miplevel))
        return false;

    if (y < 0 || y > m_spec.height)
        return false;

    // if the height is positive scanlines are stored bottom-up
    if (m_dib_header.height >= 0)
        y = m_spec.height - y - 1;
    const int64_t scanline_off = y * m_padded_scanline_size;

    std::unique_ptr<unsigned char[]> fscanline(
        new unsigned char[m_padded_scanline_size]);
    Filesystem::fseek(m_fd, m_image_start + scanline_off, SEEK_SET);
    size_t n = fread(fscanline.get(), 1, m_padded_scanline_size, m_fd);
    if (n != (size_t)m_padded_scanline_size) {
        if (feof(m_fd))
            errorf("Hit end of file unexpectedly");
        else
            errorf("read error");
        return false;  // Read failed
    }

    // in each case we process only first m_spec.scanline_bytes () bytes
    // as only they contain information about pixels. The rest are just
    // because scanline size have to be 32-bit boundary
    if (m_dib_header.bpp == 24 || m_dib_header.bpp == 32) {
        for (unsigned int i = 0; i < m_spec.scanline_bytes();
             i += m_spec.nchannels)
            std::swap(fscanline[i], fscanline[i + 2]);
        memcpy(data, fscanline.get(), m_spec.scanline_bytes());
        return true;
    }

    size_t scanline_bytes = m_spec.scanline_bytes();
    std::unique_ptr<unsigned char[]> mscanline(
        new unsigned char[scanline_bytes]);
    if (m_dib_header.bpp == 16) {
        const uint16_t RED   = 0x7C00;
        const uint16_t GREEN = 0x03E0;
        const uint16_t BLUE  = 0x001F;
        for (unsigned int i = 0, j = 0; j < scanline_bytes; i += 2, j += 3) {
            uint16_t pixel   = (uint16_t) * (&fscanline[i]);
            mscanline[j]     = (uint8_t)((pixel & RED) >> 8);
            mscanline[j + 1] = (uint8_t)((pixel & GREEN) >> 4);
            mscanline[j + 2] = (uint8_t)(pixel & BLUE);
        }
    }
    if (m_dib_header.bpp == 8) {
        for (unsigned int i = 0, j = 0; j < scanline_bytes; ++i, j += 3) {
            mscanline[j]     = m_colortable[fscanline[i]].r;
            mscanline[j + 1] = m_colortable[fscanline[i]].g;
            mscanline[j + 2] = m_colortable[fscanline[i]].b;
        }
    }
    if (m_dib_header.bpp == 4) {
        for (unsigned int i = 0, j = 0; j + 6 < scanline_bytes; ++i, j += 6) {
            uint8_t mask     = 0xF0;
            mscanline[j]     = m_colortable[(fscanline[i] & mask) >> 4].r;
            mscanline[j + 1] = m_colortable[(fscanline[i] & mask) >> 4].g;
            mscanline[j + 2] = m_colortable[(fscanline[i] & mask) >> 4].b;
            mask             = 0x0F;
            mscanline[j + 3] = m_colortable[fscanline[i] & mask].r;
            mscanline[j + 4] = m_colortable[fscanline[i] & mask].g;
            mscanline[j + 5] = m_colortable[fscanline[i] & mask].b;
        }
    }
    if (m_dib_header.bpp == 1) {
        for (int64_t i = 0, k = 0; i < m_padded_scanline_size; ++i) {
            for (int j = 7; j >= 0; --j, k += 3) {
                if (size_t(k + 2) >= scanline_bytes)
                    break;
                int index = 0;
                if (fscanline[i] & (1 << j))
                    index = 1;
                mscanline[k]     = m_colortable[index].r;
                mscanline[k + 1] = m_colortable[index].g;
                mscanline[k + 2] = m_colortable[index].b;
            }
        }
    }
    memcpy(data, &mscanline[0], scanline_bytes);
    return true;
}

bool inline BmpInput::close(void)
{
    if (m_fd) {
        fclose(m_fd);
        m_fd = NULL;
    }
    init();
    return true;
}

bool
BmpInput::read_color_table(void)
{
    // size of color table is defined  by m_dib_header.cpalete
    // if this field is 0 - color table has max colors:
    // pow(2, m_dib_header.cpalete) otherwise color table have
    // m_dib_header.cpalete entries
    const int32_t colors = (m_dib_header.cpalete) ? m_dib_header.cpalete
                                                  : 1 << m_dib_header.bpp;
    size_t entry_size = 4;
    // if the file is OS V2 bitmap color table entr has only 3 bytes, not four
    if (m_dib_header.size == OS2_V1)
        entry_size = 3;
    m_colortable.resize(colors);
    for (int i = 0; i < colors; i++) {
        size_t n = fread(&m_colortable[i], 1, entry_size, m_fd);
        if (n != entry_size) {
            if (feof(m_fd))
                errorf(
                    "Hit end of file unexpectedly while reading color table");
            else
                errorf("read error while reading color table");
            return false;  // Read failed
        }
    }
    return true;  // ok
}

OIIO_PLUGIN_NAMESPACE_END
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* bzflag special common - 1st one */
#include "common.h"

#include <iostream>
#include <string>

#include "ActionBinding.h"
#include "CommandManager.h"
#include "KeyManager.h"

// initialize the singleton
template <>
ActionBinding* Singleton<ActionBinding>::_instance = (ActionBinding*)0;

ActionBinding::ActionBinding() {
  wayToBindActions.insert(std::make_pair(std::string("quit"), press));
  wayToBindActions.insert(std::make_pair(std::string("fire"), both));
  wayToBindActions.insert(std::make_pair(std::string("drop"), press));
  wayToBindActions.insert(std::make_pair(std::string("identify"), press));
  wayToBindActions.insert(std::make_pair(std::string("jump"), both));
  wayToBindActions.insert(std::make_pair(std::string("send all"), press));
  wayToBindActions.insert(std::make_pair(std::string("send team"), press));
  wayToBindActions.insert(std::make_pair(std::string("send nemesis"), press));
  wayToBindActions.insert(std::make_pair(std::string("send recipient"), press));
  wayToBindActions.insert(std::make_pair(std::string("send admin"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayScore"), press));
  wayToBindActions.insert(std::make_pair(std::string("viewZoom toggle"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("viewZoom in"), press));
  wayToBindActions.insert(std::make_pair(std::string("viewZoom out"), press));
  wayToBindActions.insert(std::make_pair(std::string("pause"), press));
  wayToBindActions.insert(std::make_pair(std::string("fullscreen"), press));
  wayToBindActions.insert(std::make_pair(std::string("iconify"), press));
#ifdef SNAPPING
  wayToBindActions.insert(std::make_pair(std::string("screenshot"), press));
#endif
  wayToBindActions.insert(std::make_pair(std::string("time backward"), press));
  wayToBindActions.insert(std::make_pair(std::string("time forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleRadar"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleConsole"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleFlags radar"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleFlags main"), press));
  wayToBindActions.insert(std::make_pair(std::string("silence"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayLabels"), press));
  wayToBindActions.insert(std::make_pair(std::string("destruct"), press));

  // Movement keys
  wayToBindActions.insert(std::make_pair(std::string("turn left"), both));
  wayToBindActions.insert(std::make_pair(std::string("turn right"), both));
  wayToBindActions.insert(std::make_pair(std::string("drive forward"), both));
  wayToBindActions.insert(std::make_pair(std::string("drive reverse"), both));
  // End movement keys

  wayToBindActions.insert(std::make_pair(std::string("roam cycle subject backward"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("roam cycle subject forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("roam cycle type forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom in"), both));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom out"), both));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom normal"), both));
  wayToBindActions.insert(std::make_pair(std::string("servercommand"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayFlagHelp"), press));
  wayToBindActions.insert(std::make_pair(std::string("scrollpanel up"), press));
  wayToBindActions.insert(std::make_pair(std::string("scrollpanel down"), press));
  wayToBindActions.insert(std::make_pair(std::string("radarZoom in"), press));
  wayToBindActions.insert(std::make_pair(std::string("radarZoom out"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 0.25"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 0.5"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 1.0"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle slowKeyboard"), press));
  wayToBindActions.insert(std::make_pair(std::string("hunt"), press));
  wayToBindActions.insert(std::make_pair(std::string("addhunt"), press));
  wayToBindActions.insert(std::make_pair(std::string("restart"), release));
  wayToBindActions.insert(std::make_pair(std::string("autopilot"), press));

  wayToBindActions.insert(std::make_pair(std::string("messagepanel all"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel chat"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel server"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel misc"),
					 press));

  defaultBinding.insert(BindingTable::value_type("F12", "quit"));
  defaultBinding.insert(BindingTable::value_type("Left Mouse", "fire"));
  defaultBinding.insert(BindingTable::value_type("Enter", "fire"));
  defaultBinding.insert(BindingTable::value_type("Middle Mouse", "drop"));
  defaultBinding.insert(BindingTable::value_type("Space", "drop"));
  defaultBinding.insert(BindingTable::value_type("Right Mouse", "identify"));
  defaultBinding.insert(BindingTable::value_type("I", "identify"));
  defaultBinding.insert(BindingTable::value_type("Tab", "jump"));
  defaultBinding.insert(BindingTable::value_type("N", "send all"));
  defaultBinding.insert(BindingTable::value_type("M", "send team"));
  defaultBinding.insert(BindingTable::value_type(",", "send nemesis"));
  defaultBinding.insert(BindingTable::value_type(".", "send recipient"));
  defaultBinding.insert(BindingTable::value_type("Z", "send admin"));
  defaultBinding.insert(BindingTable::value_type("S", "toggle displayScore"));
  defaultBinding.insert(BindingTable::value_type("B", "viewZoom toggle"));
  defaultBinding.insert(BindingTable::value_type("Ctrl+Wheel Up", "viewZoom in"));
  defaultBinding.insert(BindingTable::value_type("Ctrl+Wheel Down", "viewZoom out"));
  defaultBinding.insert(BindingTable::value_type("Pause", "pause"));
  defaultBinding.insert(BindingTable::value_type("P", "pause"));
  defaultBinding.insert(BindingTable::value_type("F1", "fullscreen"));
  defaultBinding.insert(BindingTable::value_type("Q", "toggleRadar"));
  defaultBinding.insert(BindingTable::value_type("W", "toggleConsole"));
  defaultBinding.insert(BindingTable::value_type("F4", "iconify"));
#ifdef SNAPPING
  defaultBinding.insert(BindingTable::value_type("F5", "screenshot"));
#endif
  defaultBinding.insert(BindingTable::value_type("-", "time backward"));
  defaultBinding.insert(BindingTable::value_type("=", "time forward"));
  defaultBinding.insert(BindingTable::value_type("H", "toggleFlags radar"));
  defaultBinding.insert(BindingTable::value_type("J", "toggleFlags main"));
  defaultBinding.insert(BindingTable::value_type("K", "silence"));
  defaultBinding.insert(BindingTable::value_type("L", "toggle displayLabels"));
  defaultBinding.insert(BindingTable::value_type("Delete", "destruct"));

  // Default movement keys
  defaultBinding.insert(BindingTable::value_type("Left Arrow", "turn left"));
  defaultBinding.insert(BindingTable::value_type("Right Arrow", "turn right"));
  defaultBinding.insert(BindingTable::value_type("Up Arrow", "drive forward"));
  defaultBinding.insert(BindingTable::value_type("Down Arrow", "drive reverse"));
  // End default movement keys

  defaultBinding.insert(BindingTable::value_type("Shift+Wheel Up", "radarZoom in"));
  defaultBinding.insert(BindingTable::value_type("Shift+Wheel Down", "radarZoom out"));

  defaultBinding.insert(BindingTable::value_type("F6", "roam cycle subject backward"));
  defaultBinding.insert(BindingTable::value_type("F7", "roam cycle subject forward"));
  defaultBinding.insert(BindingTable::value_type("F8", "roam cycle type forward"));
  defaultBinding.insert(BindingTable::value_type("F9", "roam zoom in"));
  defaultBinding.insert(BindingTable::value_type("F10", "roam zoom out"));
  defaultBinding.insert(BindingTable::value_type("F11", "roam zoom normal"));
  defaultBinding.insert(BindingTable::value_type("O", "servercommand"));
  defaultBinding.insert(BindingTable::value_type("F", "toggle displayFlagHelp"));
  defaultBinding.insert(BindingTable::value_type("Page Up", "scrollpanel up"));
  defaultBinding.insert(BindingTable::value_type("Wheel Up", "scrollpanel up"));
  defaultBinding.insert(BindingTable::value_type("Page Down", "scrollpanel down"));
  defaultBinding.insert(BindingTable::value_type("Wheel Down", "scrollpanel down"));
  defaultBinding.insert(BindingTable::value_type("1", "set displayRadarRange 0.25"));
  defaultBinding.insert(BindingTable::value_type("2", "set displayRadarRange 0.5"));
  defaultBinding.insert(BindingTable::value_type("3", "set displayRadarRange 1.0"));
  defaultBinding.insert(BindingTable::value_type("4", "radarZoom in"));
  defaultBinding.insert(BindingTable::value_type("5", "radarZoom out"));
  defaultBinding.insert(BindingTable::value_type("A", "toggle slowKeyboard"));
  defaultBinding.insert(BindingTable::value_type("U", "hunt"));
  defaultBinding.insert(BindingTable::value_type("7", "addhunt"));
  defaultBinding.insert(BindingTable::value_type("Right Mouse", "restart"));
  defaultBinding.insert(BindingTable::value_type("I", "restart"));
  defaultBinding.insert(BindingTable::value_type("9", "autopilot"));

  defaultBinding.insert(BindingTable::value_type("Shift+F1", "messagepanel all"));
  defaultBinding.insert(BindingTable::value_type("Shift+F2", "messagepanel chat"));
  defaultBinding.insert(BindingTable::value_type("Shift+F3", "messagepanel server"));
  defaultBinding.insert(BindingTable::value_type("Shift+F4", "messagepanel misc"));
}

void ActionBinding::resetBindings() {
  BindingTable::const_iterator index;

  for (index = bindingTable.begin();
       index != bindingTable.end();
       ++index)
    unbind(index->second, index->first);

  bindingTable = defaultBinding;

  for (index = bindingTable.begin();
       index != bindingTable.end();
       ++index)
    bind(index->second, index->first);
}

void ActionBinding::getFromBindings() {
  bindingTable.clear();
  KEYMGR.iterate(&onScanCB, this);
}

void ActionBinding::onScanCB(const std::string& name, bool,
			     const std::string& cmd, void*)
{
  ActionBinding::instance().associate(name, cmd, false);
}

void ActionBinding::associate(std::string key,
			      std::string action,
			      bool	keyBind) {
  BindingTable::iterator index, next;
  if (!wayToBindActions.count(action))
    return;
  PressStatusBind newStatusBind = wayToBindActions[action];
  for (index = bindingTable.lower_bound( key ); index != bindingTable.upper_bound( key ); index = next) {
    next = index;
    ++next;
    if (newStatusBind == both) {
      if (keyBind)
	unbind(index->second, key);
      bindingTable.erase(index);
    } else if (newStatusBind == press) {
      if (wayToBindActions[index->second] != release) {
	if (keyBind)
	  unbind(index->second, key);
	bindingTable.erase(index);
      }
    } else {
      if (wayToBindActions[index->second] != press) {
	if (keyBind)
	  unbind(index->second, key);
	bindingTable.erase(index);
      }
    }
  }
  bindingTable.insert(BindingTable::value_type(key, action));
  if (keyBind)
    bind(action, key);
}

void ActionBinding::deassociate(std::string action) {
  BindingTable::iterator index, next;
  for (index = bindingTable.begin();
       index != bindingTable.end();
       index = next) {
    next = index;
    ++next;
    if (index->second == action) {
      unbind(action, index->first);
      bindingTable.erase(index);
    }
  }
}

void ActionBinding::bind(std::string action, std::string key) {
  PressStatusBind statusBind = wayToBindActions[action];
  std::string command;
  if (statusBind == press || statusBind == both) {
    command = "bind \"" + key + "\" down \"" + action + "\"";
    CMDMGR.run(command);
  };
  if (statusBind == release || statusBind == both) {
    command = "bind \"" + key + "\" up \"" + action + "\"";
    CMDMGR.run(command);
  };
}

void ActionBinding::unbind(std::string action, std::string key) {
  PressStatusBind statusBind = wayToBindActions[action];
  std::string command;
  if (statusBind == press || statusBind == both) {
    command = "unbind \"" + key + "\" down";
    CMDMGR.run(command);
  };
  if (statusBind == release || statusBind == both) {
    command = "unbind \"" + key + "\" up";
    CMDMGR.run(command);
  };
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>whoops, need this too<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* bzflag special common - 1st one */
#include "common.h"

#include <iostream>
#include <string>

#include "ActionBinding.h"
#include "CommandManager.h"
#include "KeyManager.h"

// initialize the singleton
template <>
ActionBinding* Singleton<ActionBinding>::_instance = (ActionBinding*)0;

ActionBinding::ActionBinding() {
  wayToBindActions.insert(std::make_pair(std::string("quit"), press));
  wayToBindActions.insert(std::make_pair(std::string("fire"), both));
  wayToBindActions.insert(std::make_pair(std::string("drop"), press));
  wayToBindActions.insert(std::make_pair(std::string("identify"), press));
  wayToBindActions.insert(std::make_pair(std::string("jump"), both));
  wayToBindActions.insert(std::make_pair(std::string("send all"), press));
  wayToBindActions.insert(std::make_pair(std::string("send team"), press));
  wayToBindActions.insert(std::make_pair(std::string("send nemesis"), press));
  wayToBindActions.insert(std::make_pair(std::string("send recipient"), press));
  wayToBindActions.insert(std::make_pair(std::string("send admin"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayScore"), press));
  wayToBindActions.insert(std::make_pair(std::string("viewZoom toggle"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("viewZoom in"), press));
  wayToBindActions.insert(std::make_pair(std::string("viewZoom out"), press));
  wayToBindActions.insert(std::make_pair(std::string("pause"), press));
  wayToBindActions.insert(std::make_pair(std::string("fullscreen"), press));
  wayToBindActions.insert(std::make_pair(std::string("mousegrab"), press));
  wayToBindActions.insert(std::make_pair(std::string("iconify"), press));
#ifdef SNAPPING
  wayToBindActions.insert(std::make_pair(std::string("screenshot"), press));
#endif
  wayToBindActions.insert(std::make_pair(std::string("time backward"), press));
  wayToBindActions.insert(std::make_pair(std::string("time forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleRadar"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleConsole"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleFlags radar"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggleFlags main"), press));
  wayToBindActions.insert(std::make_pair(std::string("silence"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayLabels"), press));
  wayToBindActions.insert(std::make_pair(std::string("destruct"), press));

  // Movement keys
  wayToBindActions.insert(std::make_pair(std::string("turn left"), both));
  wayToBindActions.insert(std::make_pair(std::string("turn right"), both));
  wayToBindActions.insert(std::make_pair(std::string("drive forward"), both));
  wayToBindActions.insert(std::make_pair(std::string("drive reverse"), both));
  // End movement keys

  wayToBindActions.insert(std::make_pair(std::string("roam cycle subject backward"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("roam cycle subject forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("roam cycle type forward"), press));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom in"), both));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom out"), both));
  wayToBindActions.insert(std::make_pair(std::string("roam zoom normal"), both));
  wayToBindActions.insert(std::make_pair(std::string("servercommand"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle displayFlagHelp"), press));
  wayToBindActions.insert(std::make_pair(std::string("scrollpanel up"), press));
  wayToBindActions.insert(std::make_pair(std::string("scrollpanel down"), press));
  wayToBindActions.insert(std::make_pair(std::string("radarZoom in"), press));
  wayToBindActions.insert(std::make_pair(std::string("radarZoom out"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 0.25"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 0.5"), press));
  wayToBindActions.insert(std::make_pair(std::string("set displayRadarRange 1.0"), press));
  wayToBindActions.insert(std::make_pair(std::string("toggle slowKeyboard"), press));
  wayToBindActions.insert(std::make_pair(std::string("hunt"), press));
  wayToBindActions.insert(std::make_pair(std::string("addhunt"), press));
  wayToBindActions.insert(std::make_pair(std::string("restart"), release));
  wayToBindActions.insert(std::make_pair(std::string("autopilot"), press));

  wayToBindActions.insert(std::make_pair(std::string("messagepanel all"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel chat"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel server"),
					 press));
  wayToBindActions.insert(std::make_pair(std::string("messagepanel misc"),
					 press));

  defaultBinding.insert(BindingTable::value_type("F12", "quit"));
  defaultBinding.insert(BindingTable::value_type("Left Mouse", "fire"));
  defaultBinding.insert(BindingTable::value_type("Enter", "fire"));
  defaultBinding.insert(BindingTable::value_type("Middle Mouse", "drop"));
  defaultBinding.insert(BindingTable::value_type("Space", "drop"));
  defaultBinding.insert(BindingTable::value_type("Right Mouse", "identify"));
  defaultBinding.insert(BindingTable::value_type("I", "identify"));
  defaultBinding.insert(BindingTable::value_type("Tab", "jump"));
  defaultBinding.insert(BindingTable::value_type("N", "send all"));
  defaultBinding.insert(BindingTable::value_type("M", "send team"));
  defaultBinding.insert(BindingTable::value_type(",", "send nemesis"));
  defaultBinding.insert(BindingTable::value_type(".", "send recipient"));
  defaultBinding.insert(BindingTable::value_type("Z", "send admin"));
  defaultBinding.insert(BindingTable::value_type("S", "toggle displayScore"));
  defaultBinding.insert(BindingTable::value_type("B", "viewZoom toggle"));
  defaultBinding.insert(BindingTable::value_type("Ctrl+Wheel Up", "viewZoom in"));
  defaultBinding.insert(BindingTable::value_type("Ctrl+Wheel Down", "viewZoom out"));
  defaultBinding.insert(BindingTable::value_type("Pause", "pause"));
  defaultBinding.insert(BindingTable::value_type("P", "pause"));
  defaultBinding.insert(BindingTable::value_type("F1", "fullscreen"));
  defaultBinding.insert(BindingTable::value_type("Q", "toggleRadar"));
  defaultBinding.insert(BindingTable::value_type("W", "toggleConsole"));
  defaultBinding.insert(BindingTable::value_type("F4", "iconify"));
#ifdef SNAPPING
  defaultBinding.insert(BindingTable::value_type("F5", "screenshot"));
#endif
  defaultBinding.insert(BindingTable::value_type("-", "time backward"));
  defaultBinding.insert(BindingTable::value_type("=", "time forward"));
  defaultBinding.insert(BindingTable::value_type("H", "toggleFlags radar"));
  defaultBinding.insert(BindingTable::value_type("J", "toggleFlags main"));
  defaultBinding.insert(BindingTable::value_type("K", "silence"));
  defaultBinding.insert(BindingTable::value_type("L", "toggle displayLabels"));
  defaultBinding.insert(BindingTable::value_type("Delete", "destruct"));

  // Default movement keys
  defaultBinding.insert(BindingTable::value_type("Left Arrow", "turn left"));
  defaultBinding.insert(BindingTable::value_type("Right Arrow", "turn right"));
  defaultBinding.insert(BindingTable::value_type("Up Arrow", "drive forward"));
  defaultBinding.insert(BindingTable::value_type("Down Arrow", "drive reverse"));
  // End default movement keys

  defaultBinding.insert(BindingTable::value_type("Shift+Wheel Up", "radarZoom in"));
  defaultBinding.insert(BindingTable::value_type("Shift+Wheel Down", "radarZoom out"));

  defaultBinding.insert(BindingTable::value_type("F6", "roam cycle subject backward"));
  defaultBinding.insert(BindingTable::value_type("F7", "roam cycle subject forward"));
  defaultBinding.insert(BindingTable::value_type("F8", "roam cycle type forward"));
  defaultBinding.insert(BindingTable::value_type("F9", "roam zoom in"));
  defaultBinding.insert(BindingTable::value_type("F10", "roam zoom out"));
  defaultBinding.insert(BindingTable::value_type("F11", "roam zoom normal"));
  defaultBinding.insert(BindingTable::value_type("O", "servercommand"));
  defaultBinding.insert(BindingTable::value_type("F", "toggle displayFlagHelp"));
  defaultBinding.insert(BindingTable::value_type("Page Up", "scrollpanel up"));
  defaultBinding.insert(BindingTable::value_type("Wheel Up", "scrollpanel up"));
  defaultBinding.insert(BindingTable::value_type("Page Down", "scrollpanel down"));
  defaultBinding.insert(BindingTable::value_type("Wheel Down", "scrollpanel down"));
  defaultBinding.insert(BindingTable::value_type("1", "set displayRadarRange 0.25"));
  defaultBinding.insert(BindingTable::value_type("2", "set displayRadarRange 0.5"));
  defaultBinding.insert(BindingTable::value_type("3", "set displayRadarRange 1.0"));
  defaultBinding.insert(BindingTable::value_type("4", "radarZoom in"));
  defaultBinding.insert(BindingTable::value_type("5", "radarZoom out"));
  defaultBinding.insert(BindingTable::value_type("A", "toggle slowKeyboard"));
  defaultBinding.insert(BindingTable::value_type("U", "hunt"));
  defaultBinding.insert(BindingTable::value_type("7", "addhunt"));
  defaultBinding.insert(BindingTable::value_type("Right Mouse", "restart"));
  defaultBinding.insert(BindingTable::value_type("I", "restart"));
  defaultBinding.insert(BindingTable::value_type("9", "autopilot"));

  defaultBinding.insert(BindingTable::value_type("Shift+F1", "messagepanel all"));
  defaultBinding.insert(BindingTable::value_type("Shift+F2", "messagepanel chat"));
  defaultBinding.insert(BindingTable::value_type("Shift+F3", "messagepanel server"));
  defaultBinding.insert(BindingTable::value_type("Shift+F4", "messagepanel misc"));
}

void ActionBinding::resetBindings() {
  BindingTable::const_iterator index;

  for (index = bindingTable.begin();
       index != bindingTable.end();
       ++index)
    unbind(index->second, index->first);

  bindingTable = defaultBinding;

  for (index = bindingTable.begin();
       index != bindingTable.end();
       ++index)
    bind(index->second, index->first);
}

void ActionBinding::getFromBindings() {
  bindingTable.clear();
  KEYMGR.iterate(&onScanCB, this);
}

void ActionBinding::onScanCB(const std::string& name, bool,
			     const std::string& cmd, void*)
{
  ActionBinding::instance().associate(name, cmd, false);
}

void ActionBinding::associate(std::string key,
			      std::string action,
			      bool	keyBind) {
  BindingTable::iterator index, next;
  if (!wayToBindActions.count(action))
    return;
  PressStatusBind newStatusBind = wayToBindActions[action];
  for (index = bindingTable.lower_bound( key ); index != bindingTable.upper_bound( key ); index = next) {
    next = index;
    ++next;
    if (newStatusBind == both) {
      if (keyBind)
	unbind(index->second, key);
      bindingTable.erase(index);
    } else if (newStatusBind == press) {
      if (wayToBindActions[index->second] != release) {
	if (keyBind)
	  unbind(index->second, key);
	bindingTable.erase(index);
      }
    } else {
      if (wayToBindActions[index->second] != press) {
	if (keyBind)
	  unbind(index->second, key);
	bindingTable.erase(index);
      }
    }
  }
  bindingTable.insert(BindingTable::value_type(key, action));
  if (keyBind)
    bind(action, key);
}

void ActionBinding::deassociate(std::string action) {
  BindingTable::iterator index, next;
  for (index = bindingTable.begin();
       index != bindingTable.end();
       index = next) {
    next = index;
    ++next;
    if (index->second == action) {
      unbind(action, index->first);
      bindingTable.erase(index);
    }
  }
}

void ActionBinding::bind(std::string action, std::string key) {
  PressStatusBind statusBind = wayToBindActions[action];
  std::string command;
  if (statusBind == press || statusBind == both) {
    command = "bind \"" + key + "\" down \"" + action + "\"";
    CMDMGR.run(command);
  };
  if (statusBind == release || statusBind == both) {
    command = "bind \"" + key + "\" up \"" + action + "\"";
    CMDMGR.run(command);
  };
}

void ActionBinding::unbind(std::string action, std::string key) {
  PressStatusBind statusBind = wayToBindActions[action];
  std::string command;
  if (statusBind == press || statusBind == both) {
    command = "unbind \"" + key + "\" down";
    CMDMGR.run(command);
  };
  if (statusBind == release || statusBind == both) {
    command = "unbind \"" + key + "\" up";
    CMDMGR.run(command);
  };
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file...
#include "TextFileOutputStream.hpp"

#include <sstream>

#if defined(_MSC_VER)
#include "windows.h"
#else
#define INVALID_HANDLE_VALUE 0
#endif

#include <util/Janitor.hpp>
#include <util/XMLString.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>

namespace
{
	const bool			gOnNT = true;
};

const TextFileOutputStream::BufferType::size_type	TextFileOutputStream::s_bufferSize = 8192;

TextFileOutputStream::TextFileOutputStream(const DOMString&		theFileName) :
	TextOutputStream(),
	m_fileName(theFileName),
#if defined(_MSC_VER)
	m_handle(INVALID_HANDLE_VALUE),
#else
	m_handle(0),
#endif
	m_buffer()
{
	m_buffer.reserve(s_bufferSize + 1);

#if defined(_MSC_VER)
    if (gOnNT)
    {
        m_handle = ::CreateFileW(toCharArray(theFileName),
								 GENERIC_WRITE,
								 FILE_SHARE_WRITE,
								 0,
								 CREATE_ALWAYS,
								 FILE_FLAG_SEQUENTIAL_SCAN,
								 0);
    }
    else
    {
        char* const	tmpName = XMLString::transcode(toCharArray(theFileName));

		ArrayJanitor<char> janTmp(tmpName);

        m_handle = ::CreateFileA(tmpName,
								 GENERIC_WRITE,
								 FILE_SHARE_WRITE,
								 0,
								 CREATE_ALWAYS,
								 FILE_FLAG_SEQUENTIAL_SCAN,
								 0);
    }

#else
	char* const	tmpName = XMLString::transcode(toCharArray(theFileName));

	ArrayJanitor<char> janTmp(tmpName);

	m_handle = fopen(tmpName, "wt");
#endif

    if (m_handle == INVALID_HANDLE_VALUE)
	{
		throw TextFileOutputStreamOpenException(theFileName,
												errno);
	}
}

TextFileOutputStream::~TextFileOutputStream()
{
    if (m_handle != INVALID_HANDLE_VALUE)
	{
#if defined(_MSC_VER)
		CloseHandle(m_handle);
#else
		fclose(m_handle);
#endif
	}
}

void
TextFileOutputStream::flush()
{
	flushBuffer();

#if defined(_MSC_VER)
	FlushFileBuffers(m_handle);
#else
	fflush(m_handle);
#endif
}

void
TextFileOutputStream::write(const XMLCh* const	theBuffer)
{
	const BufferType::size_type		theLength =
		static_cast<BufferType::size_type>(length(theBuffer));

	if (theLength + m_buffer.size() > s_bufferSize)
	{
		flushBuffer();
	}

	if (theLength > s_bufferSize)
	{
		doWrite(theBuffer);
	}
	else
	{
		m_buffer.insert(m_buffer.end(),
						theBuffer,
						theBuffer + theLength);
	}
}

void
TextFileOutputStream::write(const char* const	theBuffer)
{
	flushBuffer();

	doWrite(theBuffer,
		    strlen(theBuffer));
}

void
TextFileOutputStream::write(
			const char*		theBuffer,
			unsigned long	theBufferLength)
{
	flushBuffer();

	doWrite(theBuffer,
			theBufferLength);
}

void
TextFileOutputStream::flushBuffer()
{
	if (m_buffer.size() > 0)
	{
		m_buffer.push_back(0);

		doWrite(m_buffer.begin());

		m_buffer.clear();
	}
}

void
TextFileOutputStream::doWrite(const XMLCh*	theBuffer)
{
    char* const	tmpVal = XMLString::transcode(theBuffer);

    ArrayJanitor<char> janTmp(tmpVal);

	doWrite(tmpVal,
			strlen(tmpVal));
}

void
TextFileOutputStream::doWrite(
			const char*		theBuffer,
			unsigned long	theBufferLength)
{
#if defined(_MSC_VER)
	DWORD	theBytesWritten;

	WriteFile(m_handle,
			  theBuffer,
			  theBufferLength,
			  &theBytesWritten,
			  0);

#else
	const size_t	theBytesWritten =
		fwrite(theBuffer,
			   1,
			   theBufferLength,
			   m_handle);
#endif

	if(theBytesWritten != theBufferLength)
	{
		throw TextFileOutputStreamWriteException(m_fileName,
												 errno);
	}
}

TextFileOutputStreamException::TextFileOutputStreamException(
		const DOMString&	theMessage,
		const DOMString&	theType) :
	XercesPlatformSupportException(theMessage,
								theType)
{
}

TextFileOutputStreamException::~TextFileOutputStreamException()
{
}

namespace
{

const DOMString		theOpenExceptionType("TextFileOutputStreamOpenException");
const DOMString		theWriteExceptionType("TextFileOutputStreamWriteException");

DOMString
FormatMessageLocal(
			const DOMString&	theMessage,
			const DOMString&	theFileName,
			int					theErrorCode)
{
	DOMString	theResult(clone(theMessage));

	theResult += theFileName;

	std::stringstream	theFormatter;

	theFormatter << ".  The error code was "
				 << theErrorCode
				 << ".";

	theResult += theFormatter.str().c_str();

	return theResult;
}

};

TextFileOutputStreamOpenException::TextFileOutputStreamOpenException(
		const DOMString&	theFileName,
		int					theErrorCode) :
	TextFileOutputStreamException(FormatMessageLocal("Error opening file: ",
													 theFileName,
													 theErrorCode),
								  theOpenExceptionType)
{
}

TextFileOutputStreamOpenException::~TextFileOutputStreamOpenException()
{
}

TextFileOutputStreamWriteException::TextFileOutputStreamWriteException(
		const DOMString&	theFileName,
		int					theErrorCode) :
	TextFileOutputStreamException(FormatMessageLocal("Error writing file: ",
													 theFileName,
													 theErrorCode),
								  theWriteExceptionType)
{
}

TextFileOutputStreamWriteException::~TextFileOutputStreamWriteException()
{
}

<commit_msg>Add runtime check of Win32 platform so we can fallback correctly on Win95/98 where wide-character paths are not supported.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file...
#include "TextFileOutputStream.hpp"

#include <sstream>

#if defined(_MSC_VER)
#include "windows.h"
#else
#define INVALID_HANDLE_VALUE 0
#endif

#include <util/Janitor.hpp>
#include <util/XMLString.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>

const TextFileOutputStream::BufferType::size_type	TextFileOutputStream::s_bufferSize = 8192;

TextFileOutputStream::TextFileOutputStream(const DOMString&		theFileName) :
	TextOutputStream(),
	m_fileName(theFileName),
#if defined(_MSC_VER)
	m_handle(INVALID_HANDLE_VALUE),
#else
	m_handle(0),
#endif
	m_buffer()
{
	m_buffer.reserve(s_bufferSize + 1);

#if defined(_MSC_VER)

	// check the version.  Only NT allows
	// wide character file paths
	OSVERSIONINFO verInfo;
	verInfo.dwOSVersionInfoSize=sizeof(verInfo);
	::GetVersionEx(&verInfo);

    if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
    {
        m_handle = ::CreateFileW(toCharArray(theFileName),
								 GENERIC_WRITE,
								 FILE_SHARE_WRITE,
								 0,
								 CREATE_ALWAYS,
								 FILE_FLAG_SEQUENTIAL_SCAN,
								 0);
    }
    else
    {
        char* const	tmpName = XMLString::transcode(toCharArray(theFileName));

		ArrayJanitor<char> janTmp(tmpName);

        m_handle = ::CreateFileA(tmpName,
								 GENERIC_WRITE,
								 FILE_SHARE_WRITE,
								 0,
								 CREATE_ALWAYS,
								 FILE_FLAG_SEQUENTIAL_SCAN,
								 0);
    }

#else
	char* const	tmpName = XMLString::transcode(toCharArray(theFileName));

	ArrayJanitor<char> janTmp(tmpName);

	m_handle = fopen(tmpName, "wt");
#endif

    if (m_handle == INVALID_HANDLE_VALUE)
	{
		throw TextFileOutputStreamOpenException(theFileName,
												errno);
	}
}

TextFileOutputStream::~TextFileOutputStream()
{
    if (m_handle != INVALID_HANDLE_VALUE)
	{
#if defined(_MSC_VER)
		CloseHandle(m_handle);
#else
		fclose(m_handle);
#endif
	}
}

void
TextFileOutputStream::flush()
{
	flushBuffer();

#if defined(_MSC_VER)
	FlushFileBuffers(m_handle);
#else
	fflush(m_handle);
#endif
}

void
TextFileOutputStream::write(const XMLCh* const	theBuffer)
{
	const BufferType::size_type		theLength =
		static_cast<BufferType::size_type>(length(theBuffer));

	if (theLength + m_buffer.size() > s_bufferSize)
	{
		flushBuffer();
	}

	if (theLength > s_bufferSize)
	{
		doWrite(theBuffer);
	}
	else
	{
		m_buffer.insert(m_buffer.end(),
						theBuffer,
						theBuffer + theLength);
	}
}

void
TextFileOutputStream::write(const char* const	theBuffer)
{
	flushBuffer();

	doWrite(theBuffer,
		    strlen(theBuffer));
}

void
TextFileOutputStream::write(
			const char*		theBuffer,
			unsigned long	theBufferLength)
{
	flushBuffer();

	doWrite(theBuffer,
			theBufferLength);
}

void
TextFileOutputStream::flushBuffer()
{
	if (m_buffer.size() > 0)
	{
		m_buffer.push_back(0);

		doWrite(m_buffer.begin());

		m_buffer.clear();
	}
}

void
TextFileOutputStream::doWrite(const XMLCh*	theBuffer)
{
    char* const	tmpVal = XMLString::transcode(theBuffer);

    ArrayJanitor<char> janTmp(tmpVal);

	doWrite(tmpVal,
			strlen(tmpVal));
}

void
TextFileOutputStream::doWrite(
			const char*		theBuffer,
			unsigned long	theBufferLength)
{
#if defined(_MSC_VER)
	DWORD	theBytesWritten;

	WriteFile(m_handle,
			  theBuffer,
			  theBufferLength,
			  &theBytesWritten,
			  0);

#else
	const size_t	theBytesWritten =
		fwrite(theBuffer,
			   1,
			   theBufferLength,
			   m_handle);
#endif

	if(theBytesWritten != theBufferLength)
	{
		throw TextFileOutputStreamWriteException(m_fileName,
												 errno);
	}
}

TextFileOutputStreamException::TextFileOutputStreamException(
		const DOMString&	theMessage,
		const DOMString&	theType) :
	XercesPlatformSupportException(theMessage,
								theType)
{
}

TextFileOutputStreamException::~TextFileOutputStreamException()
{
}

namespace
{

const DOMString		theOpenExceptionType("TextFileOutputStreamOpenException");
const DOMString		theWriteExceptionType("TextFileOutputStreamWriteException");

DOMString
FormatMessageLocal(
			const DOMString&	theMessage,
			const DOMString&	theFileName,
			int					theErrorCode)
{
	DOMString	theResult(clone(theMessage));

	theResult += theFileName;

	std::stringstream	theFormatter;

	theFormatter << ".  The error code was "
				 << theErrorCode
				 << ".";

	theResult += theFormatter.str().c_str();

	return theResult;
}

};

TextFileOutputStreamOpenException::TextFileOutputStreamOpenException(
		const DOMString&	theFileName,
		int					theErrorCode) :
	TextFileOutputStreamException(FormatMessageLocal("Error opening file: ",
													 theFileName,
													 theErrorCode),
								  theOpenExceptionType)
{
}

TextFileOutputStreamOpenException::~TextFileOutputStreamOpenException()
{
}

TextFileOutputStreamWriteException::TextFileOutputStreamWriteException(
		const DOMString&	theFileName,
		int					theErrorCode) :
	TextFileOutputStreamException(FormatMessageLocal("Error writing file: ",
													 theFileName,
													 theErrorCode),
								  theWriteExceptionType)
{
}

TextFileOutputStreamWriteException::~TextFileOutputStreamWriteException()
{
}

<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XercesDOMPrintWriter.hpp"

#include <cassert>

#include <XalanDOM/XalanDOMString.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/TextOutputStream.hpp>

XercesDOMPrintWriter::XercesDOMPrintWriter(
			TextOutputStream&	theOutputStream,
			bool				fAutoFlush) :
	PrintWriter(fAutoFlush),
	m_OutputStream(theOutputStream)
{
}

XercesDOMPrintWriter::~XercesDOMPrintWriter()
{
	flush();
}

bool
XercesDOMPrintWriter::checkError() const
{
	return false;
}

void
XercesDOMPrintWriter::close()
{
}

void
XercesDOMPrintWriter::flush()
{
	m_OutputStream.flush();
}

void
XercesDOMPrintWriter::write(
			const char*		s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	write(DOMString(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::write(
			const XMLCh*	s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(length(s) == 0 || theOffset < length(s));

	if (theLength == -1)
	{
		if (theOffset == 0)
		{
			m_OutputStream.write(s);
		}
		else
		{
			m_OutputStream.write(s + theOffset);
		}
	}
	else
	{
		const long	theStopIndex = theOffset + theLength;

		for (long i = theOffset; i < theStopIndex; i++)
		{
			m_OutputStream.write(s[i]);
		}
	}
}

void
XercesDOMPrintWriter::write(XMLCh	c)
{
	m_OutputStream.write(c);
}

void
XercesDOMPrintWriter::write(
			const DOMString&	s,
			unsigned int		theOffset,
			unsigned int		theLength)
{
	write(c_wstr(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::print(bool	b)
{
	if (b == true)
	{
		print(XALAN_STATIC_UCODE_STRING("true"));
	}
	else
	{
		print(XALAN_STATIC_UCODE_STRING("false"));
	}
}

void
XercesDOMPrintWriter::print(char	c)
{
	write(c);
}

void
XercesDOMPrintWriter::print(
			const char*		s,
			unsigned int	theLength)
{
	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(
			const XMLCh*	s,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(theLength >= 0 || theLength == -1);

	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(double	d)
{
	m_OutputStream.write(c_wstr(DoubleToDOMString(d)));
}

void
XercesDOMPrintWriter::print(int	i)
{
	m_OutputStream.write(c_wstr(LongToDOMString(i)));
}

void
XercesDOMPrintWriter::print(long	l)
{
	m_OutputStream.write(c_wstr(LongToDOMString(l)));
}

void
XercesDOMPrintWriter::print(const DOMString&	s)
{
	m_OutputStream.write(c_wstr(s));
}

void
XercesDOMPrintWriter::println()
{
	m_OutputStream.write(c_wstr(XALAN_STATIC_UCODE_STRING("\n")));

	flush();
}

void
XercesDOMPrintWriter::println(bool	b)
{
	print(b);

	println();
}

void
XercesDOMPrintWriter::println(char	c)
{
	print(c);

	println();
}

void
XercesDOMPrintWriter::println(
			const char*		s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(
			const XMLCh*	s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(double	d)
{
	print(d);

	println();
}

void
XercesDOMPrintWriter::println(int		i)
{
	print(i);

	println();
}

void
XercesDOMPrintWriter::println(long	l)
{
	print(l);

	println();
}

void
XercesDOMPrintWriter::println(const DOMString&	s)
{
	print(s);

	println();
}
<commit_msg>Call flush() in close().<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// Class header file.
#include "XercesDOMPrintWriter.hpp"

#include <cassert>

#include <XalanDOM/XalanDOMString.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/TextOutputStream.hpp>

XercesDOMPrintWriter::XercesDOMPrintWriter(
			TextOutputStream&	theOutputStream,
			bool				fAutoFlush) :
	PrintWriter(fAutoFlush),
	m_OutputStream(theOutputStream)
{
}

XercesDOMPrintWriter::~XercesDOMPrintWriter()
{
	flush();
}

bool
XercesDOMPrintWriter::checkError() const
{
	return false;
}

void
XercesDOMPrintWriter::close()
{
	flush();
}

void
XercesDOMPrintWriter::flush()
{
	m_OutputStream.flush();
}

void
XercesDOMPrintWriter::write(
			const char*		s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	write(DOMString(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::write(
			const XMLCh*	s,
			unsigned int	theOffset,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(length(s) == 0 || theOffset < length(s));

	if (theLength == -1)
	{
		if (theOffset == 0)
		{
			m_OutputStream.write(s);
		}
		else
		{
			m_OutputStream.write(s + theOffset);
		}
	}
	else
	{
		const long	theStopIndex = theOffset + theLength;

		for (long i = theOffset; i < theStopIndex; i++)
		{
			m_OutputStream.write(s[i]);
		}
	}
}

void
XercesDOMPrintWriter::write(XMLCh	c)
{
	m_OutputStream.write(c);
}

void
XercesDOMPrintWriter::write(
			const DOMString&	s,
			unsigned int		theOffset,
			unsigned int		theLength)
{
	write(c_wstr(s), theOffset, theLength);
}

void
XercesDOMPrintWriter::print(bool	b)
{
	if (b == true)
	{
		print(XALAN_STATIC_UCODE_STRING("true"));
	}
	else
	{
		print(XALAN_STATIC_UCODE_STRING("false"));
	}
}

void
XercesDOMPrintWriter::print(char	c)
{
	write(c);
}

void
XercesDOMPrintWriter::print(
			const char*		s,
			unsigned int	theLength)
{
	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(
			const XMLCh*	s,
			unsigned int	theLength)
{
	assert(s != 0);
	assert(theLength >= 0 || theLength == -1);

	write(s,
		  0,
		  theLength);
}

void
XercesDOMPrintWriter::print(double	d)
{
	m_OutputStream.write(c_wstr(DoubleToDOMString(d)));
}

void
XercesDOMPrintWriter::print(int	i)
{
	m_OutputStream.write(c_wstr(LongToDOMString(i)));
}

void
XercesDOMPrintWriter::print(long	l)
{
	m_OutputStream.write(c_wstr(LongToDOMString(l)));
}

void
XercesDOMPrintWriter::print(const DOMString&	s)
{
	m_OutputStream.write(c_wstr(s));
}

void
XercesDOMPrintWriter::println()
{
	m_OutputStream.write(c_wstr(XALAN_STATIC_UCODE_STRING("\n")));

	flush();
}

void
XercesDOMPrintWriter::println(bool	b)
{
	print(b);

	println();
}

void
XercesDOMPrintWriter::println(char	c)
{
	print(c);

	println();
}

void
XercesDOMPrintWriter::println(
			const char*		s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(
			const XMLCh*	s,
			unsigned int	theLength)
{
	print(s, theLength);

	println();
}

void
XercesDOMPrintWriter::println(double	d)
{
	print(d);

	println();
}

void
XercesDOMPrintWriter::println(int		i)
{
	print(i);

	println();
}

void
XercesDOMPrintWriter::println(long	l)
{
	print(l);

	println();
}

void
XercesDOMPrintWriter::println(const DOMString&	s)
{
	print(s);

	println();
}
<|endoftext|>


<commit_before>/**********************************************************************
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.osgeo.org
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 * Copyright (C) 2018 Daniel Baston <dbaston@gmail.com>
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/algorithm/locate/IndexedPointInAreaLocator.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/MultiPolygon.h>
#include <geos/geom/LineString.h>
#include <geos/geom/LineSegment.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/util/LinearComponentExtracter.h>
#include <geos/index/intervalrtree/SortedPackedIntervalRTree.h>
#include <geos/util.h>
#include <geos/algorithm/RayCrossingCounter.h>
#include <geos/index/ItemVisitor.h>

#include <algorithm>
#include <typeinfo>

namespace geos {
namespace algorithm {
namespace locate {
//
// private:
//
IndexedPointInAreaLocator::IntervalIndexedGeometry::IntervalIndexedGeometry(const geom::Geometry& g)
    : isEmpty(0)
{
    if (g.isEmpty())
        isEmpty = true;
    else
        init(g);
}

void
IndexedPointInAreaLocator::IntervalIndexedGeometry::init(const geom::Geometry& g)
{
    geom::LineString::ConstVect lines;
    geom::util::LinearComponentExtracter::getLines(g, lines);

    // pre-compute size of segment vector
    size_t nsegs = 0;
    for(const geom::LineString* line : lines) {
        nsegs += line->getCoordinatesRO()->size() - 1;
    }
    segments.reserve(nsegs);

    for(const geom::LineString* line : lines) {
        addLine(line->getCoordinatesRO());
    }

    index = index::intervalrtree::SortedPackedIntervalRTree(segments.size());

    for(geom::LineSegment& seg : segments) {
        index.insert(
            std::min(seg.p0.y, seg.p1.y),
            std::max(seg.p0.y, seg.p1.y),
            &seg);
    }
}

void
IndexedPointInAreaLocator::IntervalIndexedGeometry::addLine(const geom::CoordinateSequence* pts)
{
    for(size_t i = 1, ni = pts->size(); i < ni; i++) {
        segments.emplace_back((*pts)[i - 1], (*pts)[i]);
    }
}

void
IndexedPointInAreaLocator::buildIndex(const geom::Geometry& g)
{
    index = detail::make_unique<IntervalIndexedGeometry>(g);
}

//
// protected:
//

//
// public:
//
IndexedPointInAreaLocator::IndexedPointInAreaLocator(const geom::Geometry& g)
    :	areaGeom(g)
{
    const std::type_info& areaGeomId = typeid(areaGeom);
    if(areaGeomId != typeid(geom::Polygon)
            &&	areaGeomId != typeid(geom::MultiPolygon)
            &&	areaGeomId != typeid(geom::LinearRing)) {
        throw util::IllegalArgumentException("Argument must be Polygonal or LinearRing");
    }

    buildIndex(areaGeom);
}

geom::Location
IndexedPointInAreaLocator::locate(const geom::Coordinate* /*const*/ p)
{
    algorithm::RayCrossingCounter rcc(*p);

    IndexedPointInAreaLocator::SegmentVisitor visitor(&rcc);

    index->query(p->y, p->y, &visitor);

    return rcc.getLocation();
}

void
IndexedPointInAreaLocator::SegmentVisitor::visitItem(void* item)
{
    geom::LineSegment* seg = static_cast<geom::LineSegment*>(item);

    counter->countSegment(seg->p0, seg->p1);
}

void
IndexedPointInAreaLocator::IntervalIndexedGeometry::query(double min, double max, index::ItemVisitor* visitor)
{
    if (isEmpty)
        return;
    index.query(min, max, visitor);
}

} // geos::algorithm::locate
} // geos::algorithm
} // geos
<commit_msg>Lazily build index in IndexedPointInAreaLocator<commit_after>/**********************************************************************
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.osgeo.org
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 * Copyright (C) 2018 Daniel Baston <dbaston@gmail.com>
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/algorithm/locate/IndexedPointInAreaLocator.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/MultiPolygon.h>
#include <geos/geom/LineString.h>
#include <geos/geom/LineSegment.h>
#include <geos/geom/LinearRing.h>
#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/util/LinearComponentExtracter.h>
#include <geos/index/intervalrtree/SortedPackedIntervalRTree.h>
#include <geos/util.h>
#include <geos/algorithm/RayCrossingCounter.h>
#include <geos/index/ItemVisitor.h>

#include <algorithm>
#include <typeinfo>

namespace geos {
namespace algorithm {
namespace locate {
//
// private:
//
IndexedPointInAreaLocator::IntervalIndexedGeometry::IntervalIndexedGeometry(const geom::Geometry& g)
    : isEmpty(0)
{
    if (g.isEmpty())
        isEmpty = true;
    else
        init(g);
}

void
IndexedPointInAreaLocator::IntervalIndexedGeometry::init(const geom::Geometry& g)
{
    geom::LineString::ConstVect lines;
    geom::util::LinearComponentExtracter::getLines(g, lines);

    // pre-compute size of segment vector
    size_t nsegs = 0;
    for(const geom::LineString* line : lines) {
        nsegs += line->getCoordinatesRO()->size() - 1;
    }
    segments.reserve(nsegs);

    for(const geom::LineString* line : lines) {
        addLine(line->getCoordinatesRO());
    }

    index = index::intervalrtree::SortedPackedIntervalRTree(segments.size());

    for(geom::LineSegment& seg : segments) {
        index.insert(
            std::min(seg.p0.y, seg.p1.y),
            std::max(seg.p0.y, seg.p1.y),
            &seg);
    }
}

void
IndexedPointInAreaLocator::IntervalIndexedGeometry::addLine(const geom::CoordinateSequence* pts)
{
    for(size_t i = 1, ni = pts->size(); i < ni; i++) {
        segments.emplace_back((*pts)[i - 1], (*pts)[i]);
    }
}

void
IndexedPointInAreaLocator::buildIndex(const geom::Geometry& g)
{
    index = detail::make_unique<IntervalIndexedGeometry>(g);
}

//
// protected:
//

//
// public:
//
IndexedPointInAreaLocator::IndexedPointInAreaLocator(const geom::Geometry& g)
    :	areaGeom(g)
{
    const std::type_info& areaGeomId = typeid(areaGeom);
    if(areaGeomId != typeid(geom::Polygon)
            &&	areaGeomId != typeid(geom::MultiPolygon)
            &&	areaGeomId != typeid(geom::LinearRing)) {
        throw util::IllegalArgumentException("Argument must be Polygonal or LinearRing");
    }
}

geom::Location
IndexedPointInAreaLocator::locate(const geom::Coordinate* /*const*/ p)
{
    if (index == nullptr) {
        buildIndex(areaGeom);
    }

    algorithm::RayCrossingCounter rcc(*p);

    IndexedPointInAreaLocator::SegmentVisitor visitor(&rcc);

    index->query(p->y, p->y, &visitor);

    return rcc.getLocation();
}

void
IndexedPointInAreaLocator::SegmentVisitor::visitItem(void* item)
{
    geom::LineSegment* seg = static_cast<geom::LineSegment*>(item);

    counter->countSegment(seg->p0, seg->p1);
}

void
IndexedPointInAreaLocator::IntervalIndexedGeometry::query(double min, double max, index::ItemVisitor* visitor)
{
    if (isEmpty)
        return;
    index.query(min, max, visitor);
}

} // geos::algorithm::locate
} // geos::algorithm
} // geos
<|endoftext|>


<commit_before>//
//  rbtree.cpp
//  rbtree
//
//  Created by Sunil on 3/22/17.
//  Copyright © 2017 Sunil. All rights reserved.
//

#include "rbtree.hpp"

#include <tuple>
#include <stack>
#include <list>
#include <iostream>

using namespace std;

rbnode* rbtree::search(rbnode node, int key) {
    return nullptr;
}

rbtree::rbtree() {

}

rbtree::~rbtree() {

}

void rbtree::insert(int key) {

}

void rbtree::remove(int key) {

}

bool rbtree::has_only_red_black_nodes(rbnode* node) {
    if (!node) {
        // no nodes, no color.
        return false;
    }

    // use any tree traversal and check the color

    // everynode has to be red or black.
    if (!node->is_red_node() && !node->is_black_node()) {
        // this node is neither red nor black. It's a invalid rb tree.
        return false;
    }

    // node has red/black color but doesn't have left or right subtree.
    if (!node->left && !node->right) {
        return true;
    }

    // only right subtree is available.
    if (!node->left && node->right) {
        return has_only_red_black_nodes(node->right);
    }

    // only left subtree is available.
    if (!node->right && node->left) {
        return has_only_red_black_nodes(node->left);
    }

    // Both left "and" right subtree should have only red/black nodes.
    return (
        has_only_red_black_nodes(node->left) && has_only_red_black_nodes(node->right)
            );
}

bool rbtree::rednode_has_black_children(rbnode* parent) {
    if (!parent) {
        // no node, no children. Nothing to check
        return false;
    }

    // if node is red, then check it's children
    if (parent->is_red_node()) {

        // if left and right children are null treat them as black.
        if (!parent->left && !parent->right) {
            return true;
        }

        // both left and right are available.
        if ((parent->left && parent->left->is_red_node())
            || (parent->right && parent->right->is_red_node())) {
            return false;
        }

        // left child is not null. make sure its color is black
        if (parent->left && parent->left->is_red_node()) {
            // left child is not black.
            return false;
        }

        // right child is not null. make sure its color is black
        if (parent->right && parent->right->is_red_node()) {
            // right child is not black.
            return false;
        }
    }

    // only right subtree is available.
    if (!parent->left && parent->right) {
        return has_only_red_black_nodes(parent->right);
    }

    // only left subtree is available.
    if (!parent->right && parent->left) {
        return has_only_red_black_nodes(parent->left);
    }

    // Both left "and" right subtree
    return (
            has_only_red_black_nodes(parent->left) && has_only_red_black_nodes(parent->right)
            );
}

bool rbtree::has_equal_black_nodes_all_path(rbnode* parent) {
    // do a depth first search traversal and count the black nodes
    // along all path from root to leaf node.
    if (!parent) {
        // no nodes. return true or false ?
        return true;
    }
    // stack of tuple of (node, count of black nodes) pair.
    stack<tuple<rbnode*, int>> stk;
    list<int> paths;

    // count black nodes initially as 1 because root is black.
    stk.push(make_tuple(parent, 1));

    while (!stk.empty()) {
        auto pair = stk.top();
        stk.pop();

        auto node = std::get<0>(pair);
        auto count = std::get<1>(pair);

        if (node->left) {
            auto left = node->left;
            stk.push(make_tuple(left, count + (left->is_black_node() ? 1 : 0)));
        } else {
            // left child is null. count it as a black node.
            paths.push_front(count + 1);
        }

        if (node->right) {
            auto right = node->right;
            stk.push(make_tuple(right, count + (right->is_black_node() ? 1 : 0)));
        } else {
            // right child is null. count it as a black node.
            paths.push_front(count + 1);
        }
    }

    // now check if black node count on all paths are same.
    auto first = paths.front();

#if DEBUG
    for (auto count : paths) cout << count << "|";
    cout << endl;
#endif

    for (auto count : paths) {
        if (count != first)
            return false;
    }

    return true;
}

bool rbtree::is_valid_rbtree() {
    // rb tree properties:
    //  P.1: every node is red/black.
    //  P.2: root is always black.
    //  P.3: leaf nodes are black.
    //  P.4: red node should have only black children.
    //  P.5: for any node x, # of black nodes along all
    //       paths from x to leaf nodes should be the same.

    if (!root) {
        // no nodes in the tree, is a valid RB tree
        return true;
    }

    // P.1: check if all nodes are red/ black.
    if (!has_only_red_black_nodes(root)) {
        // some nodes are of different color. It's not a red black tree
        return false;
    }

    // P.2: If root is not black then it's invalid.
    if (root->color != rbcolor::black)
        return false;

    // P.3: I take all null nodes to be black.
    // I treat all null nodes as black. So I don't have to
    // check for black null nodes.

    // P.4: all red nodes should have black children.
    if (!rednode_has_black_children(root)) {
        // some/all of red nodes doesn't have a black children
        return false;
    }

    // P.5:  check #black nodes along all possible path from root
    //  to leaf nodes.
    if (!has_equal_black_nodes_all_path(root)) {
        // unequal number of black nodes.
        return false;
    }

    return true;
}

rbnode* rbtree::search(int key) {
    return nullptr;
}

void rbtree::prune(int min, int max) {
    throw new runtime_error("not implemented");
}

void rbtree::bfs() {
    throw new runtime_error("not implemented");
}

void rbtree::dfs() {
    throw new runtime_error("not implemented");
}
<commit_msg>Update rbtree.cpp<commit_after>//
//  rbtree.cpp
//  rbtree
//
//  Created by Sunil on 3/22/17.
//  Copyright © 2017 Sunil. All rights reserved.
//

#include "rbtree.hpp"

#include <tuple>
#include <stack>
#include <list>
#include <iostream>

using namespace std;

rbnode* rbtree::search(rbnode node, int key) {
    return nullptr;
}

rbtree::rbtree() {

}

rbtree::~rbtree() {

}

bool rbtree::violates(bool contraint) {
    // just negate the contraint and return
    return !contraint;
}

void rbtree::insert(int key) {

}

void rbtree::remove(int key) {

}

bool rbtree::has_only_red_black_nodes(rbnode* node) {
    if (!node) {
        // no nodes, no color.
        return false;
    }

    // use any tree traversal and check the color

    // everynode has to be red or black.
    if (!node->is_red_node() && !node->is_black_node()) {
        // this node is neither red nor black. It's a invalid rb tree.
        return false;
    }

    // node has red/black color but doesn't have left or right subtree.
    if (!node->left && !node->right) {
        return true;
    }

    // only right subtree is available.
    if (!node->left && node->right) {
        return has_only_red_black_nodes(node->right);
    }

    // only left subtree is available.
    if (!node->right && node->left) {
        return has_only_red_black_nodes(node->left);
    }

    // Both left "and" right subtree should have only red/black nodes.
    return (
        has_only_red_black_nodes(node->left) && has_only_red_black_nodes(node->right)
            );
}

bool rbtree::rednode_has_black_children(rbnode* parent) {
    if (!parent) {
        // no node, no children. Nothing to check
        return false;
    }

    // if node is red, then check it's children
    if (parent->is_red_node()) {

        // if left and right children are null treat them as black.
        if (!parent->left && !parent->right) {
            return true;
        }

        // both left and right are available.
        if ((parent->left && parent->left->is_red_node())
            || (parent->right && parent->right->is_red_node())) {
            return false;
        }

        // left child is not null. make sure its color is black
        if (parent->left && parent->left->is_red_node()) {
            // left child is not black.
            return false;
        }

        // right child is not null. make sure its color is black
        if (parent->right && parent->right->is_red_node()) {
            // right child is not black.
            return false;
        }
    }

    // only right subtree is available.
    if (!parent->left && parent->right) {
        return has_only_red_black_nodes(parent->right);
    }

    // only left subtree is available.
    if (!parent->right && parent->left) {
        return has_only_red_black_nodes(parent->left);
    }

    // Both left "and" right subtree
    return (
            has_only_red_black_nodes(parent->left) && has_only_red_black_nodes(parent->right)
            );
}

bool rbtree::has_equal_black_nodes_all_path(rbnode* parent) {
    // do a depth first search traversal and count the black nodes
    // along all path from root to leaf node.
    if (!parent) {
        // no nodes. return true or false ?
        return true;
    }
    // stack of tuple of (node, count of black nodes) pair.
    stack<tuple<rbnode*, int>> stk;
    list<int> paths;

    // count black nodes initially as 1 because root is black.
    stk.push(make_tuple(parent, 1));

    while (!stk.empty()) {
        auto pair = stk.top();
        stk.pop();

        auto node = std::get<0>(pair);
        auto count = std::get<1>(pair);

        if (node->left) {
            auto left = node->left;
            stk.push(make_tuple(left, count + (left->is_black_node() ? 1 : 0)));
        } else {
            // left child is null. count it as a black node.
            paths.push_front(count + 1);
        }

        if (node->right) {
            auto right = node->right;
            stk.push(make_tuple(right, count + (right->is_black_node() ? 1 : 0)));
        } else {
            // right child is null. count it as a black node.
            paths.push_front(count + 1);
        }
    }

    // now check if black node count on all paths are same.
    auto first = paths.front();

#if DEBUG
    for (auto count : paths) cout << count << "|";
    cout << endl;
#endif

    for (auto count : paths) {
        if (count != first)
            return false;
    }

    return true;
}

bool rbtree::is_valid_rbtree() {
    // rb tree properties:
    //  P.1: every node is red/black.
    //  P.2: root is always black.
    //  P.3: leaf nodes are black.
    //  P.4: red node should have only black children.
    //  P.5: for any node x, # of black nodes along all
    //       paths from x to leaf nodes should be the same.

    if (!root) {
        // no nodes in the tree, is a valid RB tree
        return true;
    }

    // P.1: check if all nodes are red/ black.
    if (violates(has_only_red_black_nodes(root))) {
        // some nodes are of different color. It's not a red black tree
        return false;
    }

    // P.2: If root is not black then it's invalid.
    if (violates(root->is_black_node()))
        return false;

    // P.3: I take all null nodes to be black.
    // I treat all null nodes as black. So I don't have to
    // check for black null nodes.

    // P.4: all red nodes should have black children.
    if (violates(rednode_has_black_children(root))) {
        // some/all of red nodes doesn't have a black children
        return false;
    }

    // P.5:  check #black nodes along all possible path from root
    //  to leaf nodes.
    if (violates(has_equal_black_nodes_all_path(root))) {
        // unequal number of black nodes.
        return false;
    }

    return true;
}

rbnode* rbtree::search(int key) {
    return nullptr;
}

void rbtree::prune(int min, int max) {
    throw new runtime_error("not implemented");
}

void rbtree::bfs() {
    throw new runtime_error("not implemented");
}

void rbtree::dfs() {
    throw new runtime_error("not implemented");
}
<|endoftext|>


<commit_before>/*
 * This file was generated by dbusidl2cpp version 0.4
 * when processing input file org.kde.Phonon.AudioOutput.xml
 *
 * dbusidl2cpp is Copyright (C) 2006 Trolltech AS. All rights reserved.
 *
 * This is an auto-generated file.
 */

#include "audiooutputadaptor.h"
#include "audiooutput.h"
#include <QtCore/QArgument>
#include <QtCore/QByteRef>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include "phononnamespace_p.h"

/*
 * Implementation of adaptor class AudioOutputAdaptor
 */

AudioOutputAdaptor::AudioOutputAdaptor(QObject *parent)
   : QDBusAbstractAdaptor(parent)
{
    // constructor
    setAutoRelaySignals(true);
}

AudioOutputAdaptor::~AudioOutputAdaptor()
{
    // destructor
}

double AudioOutputAdaptor::volume() const
{
    // get the value of property volume
    return qvariant_cast<qreal>(parent()->property("volume"));
}

void AudioOutputAdaptor::setVolume(double value)
{
    // set the value of property volume
    parent()->setProperty("volume", QVariant::fromValue(static_cast<qreal>(value)));
}

bool AudioOutputAdaptor::muted() const
{
    return parent()->property("muted").toBool();
}

void AudioOutputAdaptor::setMuted(bool value)
{
    parent()->setProperty("muted", value);
}

QString AudioOutputAdaptor::category()
{
    // handle method call org.kde.Phonon.AudioOutput.category
    return Phonon::categoryToString(static_cast<Phonon::AudioOutput *>(parent())->category());
}

QString AudioOutputAdaptor::name()
{
    // handle method call org.kde.Phonon.AudioOutput.name
    QString name;
    //QMetaObject::invokeMethod(parent(), "name", Q_RETURN_ARG(QString, name));

    // Alternative:
    name = static_cast<Phonon::AudioOutput *>(parent())->name();
    return name;
}

#include "moc_audiooutputadaptor.cpp"
<commit_msg>Fix compile<commit_after>/*
 * This file was generated by dbusidl2cpp version 0.4
 * when processing input file org.kde.Phonon.AudioOutput.xml
 *
 * dbusidl2cpp is Copyright (C) 2006 Trolltech AS. All rights reserved.
 *
 * This is an auto-generated file.
 */

#include "audiooutputadaptor.h"
#include "audiooutput.h"
#include <QtCore/QArgument>
#include <QtCore/QByteRef>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include "phononnamespace_p.h"

/*
 * Implementation of adaptor class AudioOutputAdaptor
 */

AudioOutputAdaptor::AudioOutputAdaptor(QObject *parent)
   : QDBusAbstractAdaptor(parent)
{
    // constructor
    setAutoRelaySignals(true);
}

AudioOutputAdaptor::~AudioOutputAdaptor()
{
    // destructor
}

double AudioOutputAdaptor::volume() const
{
    // get the value of property volume
    return qvariant_cast<qreal>(parent()->property("volume"));
}

void AudioOutputAdaptor::setVolume(double value)
{
    // set the value of property volume
    parent()->setProperty("volume", QVariant::fromValue(static_cast<qreal>(value)));
}

bool AudioOutputAdaptor::muted() const
{
    return parent()->property("muted").toBool();
}

void AudioOutputAdaptor::setMuted(bool value)
{
    parent()->setProperty("muted", value);
}

QString AudioOutputAdaptor::category()
{
    // handle method call org.kde.Phonon.AudioOutput.category
    return Phonon::categoryToString(static_cast<Phonon::AudioOutput *>(parent())->category());
}

QString AudioOutputAdaptor::name()
{
    // handle method call org.kde.Phonon.AudioOutput.name
    QString name;
    //QMetaObject::invokeMethod(parent(), "name", Q_RETURN_ARG(QString, name));

    // Alternative:
    name = static_cast<Phonon::AudioOutput *>(parent())->name();
    return name;
}

#include "audiooutputadaptor.moc"
<|endoftext|>


<commit_before>#include <iostream>
#include <algorithm>
#include <ctime>
#include <vector>

#include "TMath.h"
#include "TRandom2.h"

using namespace std;

const int maxint = 20;
const int minsize = 20;
const int maxsize = 500;

#ifndef ROOT_TMath

template<typename T>
struct CompareDesc {

   CompareDesc(T d) : fData(d) {}

   bool operator()(int i1, int i2) {
      return *(fData + i1) > *(fData + i2);
   }

   T fData;
};

template<typename T>
struct CompareAsc {

   CompareAsc(T d) : fData(d) {}

   bool operator()(int i1, int i2) {
      return *(fData + i1) < *(fData + i2);
   }

   T fData;
};

#endif

template <typename T> bool testSort(const int n)
{
   vector<T> k(n);
   vector<T> indexM(n);
   vector<T> indexS(n);

   bool equals = true;

   TRandom2 r( time( 0 ) );

   cout << "k: ";
   for ( Int_t i = 0; i < n; i++) {
      k[i] = (T) r.Integer( maxint );
      cout << k[i] << ' ';
   }
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexM[i] = i; }
   TMath::Sort(n,&k[0],&indexM[0],kTRUE);

   cout << "TMath[kTRUE]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexM[i]] << ' ';
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexS[i] = i; }
   std::sort(&indexS[0],&indexS[n], CompareDesc<const T*>(&k[0]) );

   cout << "std::sort[CompareDesc]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexS[i]] << ' ';
   cout << endl;

   equals &= std::equal(indexM.begin(), indexM.end(), indexS.begin());
   cout << "Equals? " << (char*) (equals?"OK":"FAILED") << endl;

   for(Int_t i = 0; i < n; i++) { indexM[i] = i; }
   TMath::Sort(n,&k[0],&indexM[0],kFALSE);

   cout << "TMath[kFALSE]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexM[i]] << ' ';
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexS[i] = i; }
   std::sort(&indexS[0],&indexS[n], CompareAsc<const T*>(&k[0]) );

   cout << "std::sort[CompareAsc]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexS[i]] << ' ';
   cout << endl;

   equals &= std::equal(indexM.begin(), indexM.end(), indexS.begin());
   cout << "Equals? " << (char*) (equals?"OK":"FAILED") << endl;

   return equals;
}

bool stdsort()
{
   return testSort<Int_t>(20);
}

int main(int /* argc */ , char ** /* argv */ )
{
   bool equals = stdsort();

   if ( !equals )
      return 1;
   else
      return 0;
}
<commit_msg>More suppression of warnings in tests<commit_after>#include <iostream>
#include <algorithm>
#include <ctime>
#include <vector>

#include "TMath.h"
#include "TRandom2.h"

using namespace std;

const int maxint = 20;

#ifndef ROOT_TMath

template<typename T>
struct CompareDesc {

   CompareDesc(T d) : fData(d) {}

   bool operator()(int i1, int i2) {
      return *(fData + i1) > *(fData + i2);
   }

   T fData;
};

template<typename T>
struct CompareAsc {

   CompareAsc(T d) : fData(d) {}

   bool operator()(int i1, int i2) {
      return *(fData + i1) < *(fData + i2);
   }

   T fData;
};

#endif

template <typename T> bool testSort(const int n)
{
   vector<T> k(n);
   vector<T> indexM(n);
   vector<T> indexS(n);

   bool equals = true;

   TRandom2 r( time( 0 ) );

   cout << "k: ";
   for ( Int_t i = 0; i < n; i++) {
      k[i] = (T) r.Integer( maxint );
      cout << k[i] << ' ';
   }
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexM[i] = i; }
   TMath::Sort(n,&k[0],&indexM[0],kTRUE);

   cout << "TMath[kTRUE]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexM[i]] << ' ';
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexS[i] = i; }
   std::sort(&indexS[0],&indexS[n], CompareDesc<const T*>(&k[0]) );

   cout << "std::sort[CompareDesc]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexS[i]] << ' ';
   cout << endl;

   equals &= std::equal(indexM.begin(), indexM.end(), indexS.begin());
   cout << "Equals? " << (char*) (equals?"OK":"FAILED") << endl;

   for(Int_t i = 0; i < n; i++) { indexM[i] = i; }
   TMath::Sort(n,&k[0],&indexM[0],kFALSE);

   cout << "TMath[kFALSE]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexM[i]] << ' ';
   cout << endl;

   for(Int_t i = 0; i < n; i++) { indexS[i] = i; }
   std::sort(&indexS[0],&indexS[n], CompareAsc<const T*>(&k[0]) );

   cout << "std::sort[CompareAsc]\n\tindex = ";
   for ( Int_t i = 0; i < n; ++i )
      cout << k[indexS[i]] << ' ';
   cout << endl;

   equals &= std::equal(indexM.begin(), indexM.end(), indexS.begin());
   cout << "Equals? " << (char*) (equals?"OK":"FAILED") << endl;

   return equals;
}

bool stdsort()
{
   return testSort<Int_t>(20);
}

int main(int /* argc */ , char ** /* argv */ )
{
   bool equals = stdsort();

   if ( !equals )
      return 1;
   else
      return 0;
}
<|endoftext|>