<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2020 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include <memory>
#include <string>

#include "tests/utils/Gtest.h"
#include "tests/utils/Gmock.h"

#include "joynr/Settings.h"
#include "joynr/LibjoynrSettings.h"
#include "joynr/system/RoutingProxy.h"
#include "joynr/serializer/Serializer.h"

#include "tests/JoynrTest.h"
#include "tests/mock/MockTransportMessageReceiver.h"
#include "tests/mock/MockTransportMessageSender.h"
#include "tests/mock/TestJoynrClusterControllerRuntime.h"
#include "tests/utils/PtrUtils.h"

using namespace joynr;
using ::testing::Mock;

class SystemServicesRoutingTest : public ::testing::Test
{
public:
    SystemServicesRoutingTest()
            : settingsFilename("test-resources/SystemServicesRoutingTest.settings"),
              settings(std::make_unique<Settings>(settingsFilename)),
              routingDomain(),
              routingProviderParticipantId(),
              runtime(nullptr),
              mockMessageReceiverMqtt(std::make_shared<MockTransportMessageReceiver>()),
              discoveryQos(),
              routingProxyBuilder(nullptr),
              routingProxy(nullptr),
              globalMqttTopic("mqtt_SystemServicesRoutingTest.topic"),
              globalMqttBrokerUrl("mqtt_SystemServicesRoutingTest.brokerUrl"),
              mqttGlobalAddress()
    {
        SystemServicesSettings systemSettings(*settings);
        systemSettings.printSettings();
        routingDomain = systemSettings.getDomain();
        routingProviderParticipantId = systemSettings.getCcRoutingProviderParticipantId();

        discoveryQos.setCacheMaxAgeMs(1000);
        discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
        discoveryQos.addCustomParameter("fixedParticipantId", routingProviderParticipantId);
        discoveryQos.setDiscoveryTimeoutMs(50);

        std::string serializedMqttAddress = joynr::serializer::serializeToJson(mqttGlobalAddress);

        EXPECT_CALL(*(std::dynamic_pointer_cast<MockTransportMessageReceiver>(
                              mockMessageReceiverMqtt).get()),
                    getSerializedGlobalClusterControllerAddress())
                .WillRepeatedly(::testing::Return(serializedMqttAddress));
        EXPECT_CALL(*(std::dynamic_pointer_cast<MockTransportMessageReceiver>(
                              mockMessageReceiverMqtt).get()),
                    getGlobalClusterControllerAddress())
                .WillRepeatedly(::testing::ReturnRef(mqttGlobalAddress));

        // runtime can only be created, after MockMessageReceiver has been told to return
        // a channelId for getReceiveChannelId.
        runtime = std::make_unique<TestJoynrClusterControllerRuntime>(
                std::move(settings), failOnFatalRuntimeError, nullptr, nullptr);
        // routing provider is normally registered in JoynrClusterControllerRuntime::create
        runtime->init();
    }

    ~SystemServicesRoutingTest()
    {
        runtime->stopExternalCommunication();
        runtime->shutdown();
        runtime.reset();

        EXPECT_TRUE(Mock::VerifyAndClearExpectations(
                std::dynamic_pointer_cast<MockTransportMessageReceiver>(mockMessageReceiverMqtt)
                        .get()));

        test::util::resetAndWaitUntilDestroyed(runtime);
        test::util::resetAndWaitUntilDestroyed(mockMessageReceiverMqtt);

        std::remove(settingsFilename.c_str());

        // Delete persisted files
        std::remove(ClusterControllerSettings::
                            DEFAULT_LOCAL_CAPABILITIES_DIRECTORY_PERSISTENCE_FILENAME().c_str());
        std::remove(LibjoynrSettings::DEFAULT_PARTICIPANT_IDS_PERSISTENCE_FILENAME().c_str());
    }

    void SetUp()
    {
        participantId = util::createUuid();
        isGloballyVisible = true;
        routingProxyBuilder =
                runtime->createProxyBuilder<joynr::system::RoutingProxy>(routingDomain);
    }

protected:
    std::string settingsFilename;
    std::unique_ptr<Settings> settings;
    std::string routingDomain;
    std::string routingProviderParticipantId;
    std::shared_ptr<TestJoynrClusterControllerRuntime> runtime;
    std::shared_ptr<ITransportMessageReceiver> mockMessageReceiverMqtt;
    DiscoveryQos discoveryQos;
    std::shared_ptr<ProxyBuilder<joynr::system::RoutingProxy>> routingProxyBuilder;
    std::shared_ptr<joynr::system::RoutingProxy> routingProxy;
    std::string participantId;
    bool isGloballyVisible;

private:
    DISALLOW_COPY_AND_ASSIGN(SystemServicesRoutingTest);
    const std::string globalMqttTopic;
    const std::string globalMqttBrokerUrl;
    const system::RoutingTypes::MqttAddress mqttGlobalAddress;
};

TEST_F(SystemServicesRoutingTest, routingProviderIsAvailable)
{
    JOYNR_EXPECT_NO_THROW(routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(5000))
                                                 ->setDiscoveryQos(discoveryQos)
                                                 ->build());
}

TEST_F(SystemServicesRoutingTest, unknowParticipantIsNotResolvable)
{
    routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(5000))
                           ->setDiscoveryQos(discoveryQos)
                           ->build();

    bool isResolvable = false;
    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_FALSE(isResolvable);
}

TEST_F(SystemServicesRoutingTest, addNextHopMqtt)
{
    routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(5000))
                           ->setDiscoveryQos(discoveryQos)
                           ->build();

    joynr::system::RoutingTypes::MqttAddress address(
            "brokerUri", "SystemServicesRoutingTest.ChanneldId.A");
    bool isResolvable = false;

    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_FALSE(isResolvable);

    try {
        routingProxy->addNextHop(participantId, address, isGloballyVisible);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "addNextHop was not successful";
    }
    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_TRUE(isResolvable);
}

TEST_F(SystemServicesRoutingTest, removeNextHopMqtt)
{
    routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(5000))
                           ->setDiscoveryQos(discoveryQos)
                           ->build();

    joynr::system::RoutingTypes::MqttAddress address(
            "brokerUri", "SystemServicesRoutingTest.ChanneldId.A");
    bool isResolvable = false;

    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_FALSE(isResolvable);

    try {
        routingProxy->addNextHop(participantId, address, isGloballyVisible);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "addNextHop was not successful";
    }
    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_TRUE(isResolvable);

    try {
        routingProxy->removeNextHop(participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "removeNextHop was not successful";
    }
    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_FALSE(isResolvable);
}
<commit_msg>[C++] Fixed SystemServicesRoutingTest<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2020 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
#include <memory>
#include <string>

#include "tests/utils/Gtest.h"
#include "tests/utils/Gmock.h"

#include "joynr/Settings.h"
#include "joynr/LibjoynrSettings.h"
#include "joynr/system/RoutingProxy.h"
#include "joynr/serializer/Serializer.h"

#include "tests/JoynrTest.h"
#include "tests/mock/MockTransportMessageReceiver.h"
#include "tests/mock/MockTransportMessageSender.h"
#include "tests/mock/TestJoynrClusterControllerRuntime.h"
#include "tests/utils/PtrUtils.h"

using namespace joynr;
using ::testing::Mock;

class SystemServicesRoutingTest : public ::testing::Test
{
public:
    SystemServicesRoutingTest()
            : settingsFilename("test-resources/SystemServicesRoutingTest.settings"),
              settings(std::make_unique<Settings>(settingsFilename)),
              routingDomain(),
              routingProviderParticipantId(),
              runtime(nullptr),
              mockMessageReceiverMqtt(std::make_shared<MockTransportMessageReceiver>()),
              discoveryQos(),
              routingProxyBuilder(nullptr),
              routingProxy(nullptr),
              globalMqttTopic("mqtt_SystemServicesRoutingTest.topic"),
              globalMqttBrokerUrl("mqtt_SystemServicesRoutingTest.brokerUrl"),
              mqttGlobalAddress()
    {
        SystemServicesSettings systemSettings(*settings);
        systemSettings.printSettings();
        routingDomain = systemSettings.getDomain();
        routingProviderParticipantId = systemSettings.getCcRoutingProviderParticipantId();

        discoveryQos.setCacheMaxAgeMs(1000);
        discoveryQos.setArbitrationStrategy(DiscoveryQos::ArbitrationStrategy::FIXED_PARTICIPANT);
        discoveryQos.addCustomParameter("fixedParticipantId", routingProviderParticipantId);
        discoveryQos.setDiscoveryTimeoutMs(1000);

        std::string serializedMqttAddress = joynr::serializer::serializeToJson(mqttGlobalAddress);

        EXPECT_CALL(*(std::dynamic_pointer_cast<MockTransportMessageReceiver>(
                              mockMessageReceiverMqtt).get()),
                    getSerializedGlobalClusterControllerAddress())
                .WillRepeatedly(::testing::Return(serializedMqttAddress));
        EXPECT_CALL(*(std::dynamic_pointer_cast<MockTransportMessageReceiver>(
                              mockMessageReceiverMqtt).get()),
                    getGlobalClusterControllerAddress())
                .WillRepeatedly(::testing::ReturnRef(mqttGlobalAddress));

        // runtime can only be created, after MockMessageReceiver has been told to return
        // a channelId for getReceiveChannelId.
        runtime = std::make_unique<TestJoynrClusterControllerRuntime>(
                std::move(settings), failOnFatalRuntimeError, nullptr, nullptr);
        // routing provider is normally registered in JoynrClusterControllerRuntime::create
        runtime->init();
    }

    ~SystemServicesRoutingTest()
    {
        runtime->stopExternalCommunication();
        runtime->shutdown();
        runtime.reset();

        EXPECT_TRUE(Mock::VerifyAndClearExpectations(
                std::dynamic_pointer_cast<MockTransportMessageReceiver>(mockMessageReceiverMqtt)
                        .get()));

        test::util::resetAndWaitUntilDestroyed(runtime);
        test::util::resetAndWaitUntilDestroyed(mockMessageReceiverMqtt);

        std::remove(settingsFilename.c_str());

        // Delete persisted files
        std::remove(ClusterControllerSettings::
                            DEFAULT_LOCAL_CAPABILITIES_DIRECTORY_PERSISTENCE_FILENAME().c_str());
        std::remove(LibjoynrSettings::DEFAULT_PARTICIPANT_IDS_PERSISTENCE_FILENAME().c_str());
    }

    void SetUp()
    {
        participantId = util::createUuid();
        isGloballyVisible = true;
        routingProxyBuilder =
                runtime->createProxyBuilder<joynr::system::RoutingProxy>(routingDomain);
    }

protected:
    std::string settingsFilename;
    std::unique_ptr<Settings> settings;
    std::string routingDomain;
    std::string routingProviderParticipantId;
    std::shared_ptr<TestJoynrClusterControllerRuntime> runtime;
    std::shared_ptr<ITransportMessageReceiver> mockMessageReceiverMqtt;
    DiscoveryQos discoveryQos;
    std::shared_ptr<ProxyBuilder<joynr::system::RoutingProxy>> routingProxyBuilder;
    std::shared_ptr<joynr::system::RoutingProxy> routingProxy;
    std::string participantId;
    bool isGloballyVisible;

private:
    DISALLOW_COPY_AND_ASSIGN(SystemServicesRoutingTest);
    const std::string globalMqttTopic;
    const std::string globalMqttBrokerUrl;
    const system::RoutingTypes::MqttAddress mqttGlobalAddress;
};

TEST_F(SystemServicesRoutingTest, routingProviderIsAvailable)
{
    JOYNR_EXPECT_NO_THROW(routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(5000))
                                                 ->setDiscoveryQos(discoveryQos)
                                                 ->build());
}

TEST_F(SystemServicesRoutingTest, unknowParticipantIsNotResolvable)
{
    routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(5000))
                           ->setDiscoveryQos(discoveryQos)
                           ->build();

    bool isResolvable = false;
    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_FALSE(isResolvable);
}

TEST_F(SystemServicesRoutingTest, addNextHopMqtt)
{
    routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(5000))
                           ->setDiscoveryQos(discoveryQos)
                           ->build();

    joynr::system::RoutingTypes::MqttAddress address(
            "brokerUri", "SystemServicesRoutingTest.ChanneldId.A");
    bool isResolvable = false;

    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_FALSE(isResolvable);

    try {
        routingProxy->addNextHop(participantId, address, isGloballyVisible);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "addNextHop was not successful";
    }
    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_TRUE(isResolvable);
}

TEST_F(SystemServicesRoutingTest, removeNextHopMqtt)
{
    routingProxy = routingProxyBuilder->setMessagingQos(MessagingQos(5000))
                           ->setDiscoveryQos(discoveryQos)
                           ->build();

    joynr::system::RoutingTypes::MqttAddress address(
            "brokerUri", "SystemServicesRoutingTest.ChanneldId.A");
    bool isResolvable = false;

    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_FALSE(isResolvable);

    try {
        routingProxy->addNextHop(participantId, address, isGloballyVisible);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "addNextHop was not successful";
    }
    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_TRUE(isResolvable);

    try {
        routingProxy->removeNextHop(participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "removeNextHop was not successful";
    }
    try {
        routingProxy->resolveNextHop(isResolvable, participantId);
    } catch (const exceptions::JoynrException& e) {
        ADD_FAILURE() << "resolveNextHop was not successful";
    }
    EXPECT_FALSE(isResolvable);
}
<|endoftext|>


<commit_before>/*
    Copyright (C) 1998, 1999 by Jorrit Tyberghein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "soundraw.h"

IMPLEMENT_IBASE(csSoundDataRaw);
  IMPLEMENTS_INTERFACE(iSoundData);
IMPLEMENT_IBASE_END;

csSoundDataRaw::csSoundDataRaw(iBase *iParent, void *d, long n,
    csSoundFormat f) {
  CONSTRUCT_IBASE(iParent);
  Data = d;
  NumSamples = n;
  Format = f;
}

csSoundDataRaw::~csSoundDataRaw() {
  unsigned char* const p = (unsigned char*)Data;
  delete[] p;
}

long csSoundDataRaw::GetNumSamples() {
  return NumSamples;
}

const csSoundFormat *csSoundDataRaw::GetFormat() {
  return &Format;
}

iSoundStream *csSoundDataRaw::CreateStream() {
  return new csSoundStreamRaw(this);
}

#define REPLACE_DATA(x) {                        \
  unsigned char* const p = (unsigned char*)Data; \
  delete[] p;                                    \
  Data = x;                                      \
}

void *ConvertBuffer8To16Bit(void *buf, unsigned long Num) {
  unsigned char *in=(unsigned char *)buf;
  short *out=new short[Num];
  for (unsigned long i=0;i<Num;i++) {
    out[i]=((short)in[i]-128)*256;
  }
  return out;
}

void *ConvertBuffer16To8Bit(void *buf, unsigned long Num) {
  short *in=(short *)buf;
  unsigned char *out=new unsigned char[Num];
  for (unsigned long i=0;i<Num;i++) {
    out[i]=(in[i]/256)+128;
  }
  return out;
}

#define CONVERT_CHANNELS_TYPE(Type) {               \
  Type *OldData=(Type*)d;                           \
  if (newfmt->Channels==1) {                        \
    Type *NewData=new Type[NumSamples];             \
    for (long i=0;i<NumSamples;i++) {      \
      NewData[i]=(OldData[2*i]+OldData[2*i+1])/2;   \
    }                                               \
    return NewData;                                 \
  } else {                                          \
    Type *NewData=new Type[NumSamples*2];           \
    for (long i=0;i<NumSamples;i++) {      \
      NewData[2*i]=NewData[2*i+1]=OldData[i];       \
    }                                               \
    return NewData;                                 \
  }                                                 \
}

void *ConvertChannels(void *d, const csSoundFormat *oldfmt,
  const csSoundFormat *newfmt, long NumSamples) {
  if (oldfmt->Bits == 8) {
    CONVERT_CHANNELS_TYPE(unsigned char);
  } else {
    CONVERT_CHANNELS_TYPE(short);
  }
}

// @@@ ConvertFreq() : quality loss! Need to use a filter.

#define CONVERT_FREQ_TYPE(Type,Channels) {                      \
  Type *NewData=new Type[NewNumSamples*Channels];               \
  Type *OldData=(Type*)d;                                       \
  for (unsigned long i=0;i<NewNumSamples;i++) {                 \
    int samppos = (int)(i/Factor);                              \
    if (Channels==1) {                                          \
      NewData[i]=OldData[samppos];                              \
    } else {                                                    \
      NewData[2*i]=OldData[2*samppos];                          \
      NewData[2*i+1]=OldData[2*samppos+1];                      \
    }                                                           \
  }                                                             \
  NumSamples = NewNumSamples;                                   \
  return NewData;                                               \
}

void *ConvertFreq(void *d, const csSoundFormat *oldfmt,
  const csSoundFormat *newfmt, long &NumSamples) {
  float Factor=newfmt->Freq/oldfmt->Freq;
  unsigned long NewNumSamples=(unsigned long)(NumSamples*Factor);
  if (oldfmt->Bits==16) {
    CONVERT_FREQ_TYPE(short,oldfmt->Channels);
  } else {
    CONVERT_FREQ_TYPE(unsigned char,oldfmt->Channels);
  }
}

void csSoundDataRaw::Convert(const csSoundFormat *RequestFormat) {
  if (Format.Bits==16 && RequestFormat->Bits==8) {
    REPLACE_DATA(ConvertBuffer16To8Bit(Data, NumSamples * Format.Channels));
    Format.Bits = 8;
  } else if (Format.Bits==8 && RequestFormat->Bits==16) {
    REPLACE_DATA(ConvertBuffer8To16Bit(Data, NumSamples * Format.Channels));
    Format.Bits = 16;
  }

  if (Format.Channels != RequestFormat->Channels && RequestFormat->Channels != -1) {
    REPLACE_DATA(ConvertChannels(Data, &Format, RequestFormat, NumSamples));
    Format.Channels = RequestFormat->Channels;
  }

  if (RequestFormat->Freq != Format.Freq && RequestFormat->Freq != -1) {
    REPLACE_DATA(ConvertFreq(Data, &Format, RequestFormat, NumSamples));
    Format.Freq = RequestFormat->Freq;
  }
}

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

IMPLEMENT_IBASE(csSoundStreamRaw)
  IMPLEMENTS_INTERFACE(iSoundStream)
IMPLEMENT_IBASE_END

csSoundStreamRaw::csSoundStreamRaw(csSoundDataRaw *sd) {
  CONSTRUCT_IBASE(NULL);
  Data=sd;
  Data->IncRef();
  Position=0;
}

csSoundStreamRaw::~csSoundStreamRaw() {
  Data->DecRef();
}

const csSoundFormat *csSoundStreamRaw::GetFormat() {
  return &Data->Format;
}

bool csSoundStreamRaw::MayPrecache() {
  return true;
}

void csSoundStreamRaw::Restart() {
  Position=0;
}

void *csSoundStreamRaw::Read(long &Num) {
  // test if we should return as much data as possible
  if (Num == -1) Num = Data->NumSamples - Position;
  // decrease size of data if we reached the end of the sound
  if (Position + Num > Data->NumSamples) Num = Data->NumSamples-Position;
  // set up return data
  void *d;
  if (Data->Format.Bits==16) {
    d=(short*)Data->Data+Position*Data->Format.Channels;
  } else {
    d=(unsigned char *)Data->Data+Position*Data->Format.Channels;
  }
  Position+=Num;
  // the data buffer is like another reference to this stream
  IncRef();
  return d;
}

void csSoundStreamRaw::DiscardBuffer(void *buf) {
  (void)buf;
  DecRef();
}
<commit_msg>fixed a bug in the sound loader<commit_after>/*
    Copyright (C) 1998, 1999 by Jorrit Tyberghein

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"
#include "soundraw.h"

IMPLEMENT_IBASE(csSoundDataRaw);
  IMPLEMENTS_INTERFACE(iSoundData);
IMPLEMENT_IBASE_END;

csSoundDataRaw::csSoundDataRaw(iBase *iParent, void *d, long n,
    csSoundFormat f) {
  CONSTRUCT_IBASE(iParent);
  Data = d;
  NumSamples = n;
  Format = f;
}

csSoundDataRaw::~csSoundDataRaw() {
  unsigned char* const p = (unsigned char*)Data;
  delete[] p;
}

long csSoundDataRaw::GetNumSamples() {
  return NumSamples;
}

const csSoundFormat *csSoundDataRaw::GetFormat() {
  return &Format;
}

iSoundStream *csSoundDataRaw::CreateStream() {
  return new csSoundStreamRaw(this);
}

#define REPLACE_DATA(x) {                        \
  unsigned char* const p = (unsigned char*)Data; \
  Data = x;                                      \
  delete[] p;                                    \
}

void *ConvertBuffer8To16Bit(void *buf, unsigned long Num) {
  unsigned char *in=(unsigned char *)buf;
  short *out=new short[Num];
  for (unsigned long i=0;i<Num;i++) {
    out[i]=((short)in[i]-128)*256;
  }
  return out;
}

void *ConvertBuffer16To8Bit(void *buf, unsigned long Num) {
  short *in=(short *)buf;
  unsigned char *out=new unsigned char[Num];
  for (unsigned long i=0;i<Num;i++) {
    out[i]=(in[i]/256)+128;
  }
  return out;
}

#define CONVERT_CHANNELS_TYPE(Type) {               \
  Type *OldData=(Type*)d;                           \
  if (newfmt->Channels==1) {                        \
    Type *NewData=new Type[NumSamples];             \
    for (long i=0;i<NumSamples;i++) {      \
      NewData[i]=(OldData[2*i]+OldData[2*i+1])/2;   \
    }                                               \
    return NewData;                                 \
  } else {                                          \
    Type *NewData=new Type[NumSamples*2];           \
    for (long i=0;i<NumSamples;i++) {      \
      NewData[2*i]=NewData[2*i+1]=OldData[i];       \
    }                                               \
    return NewData;                                 \
  }                                                 \
}

void *ConvertChannels(void *d, const csSoundFormat *oldfmt,
  const csSoundFormat *newfmt, long NumSamples) {
  if (oldfmt->Bits == 8) {
    CONVERT_CHANNELS_TYPE(unsigned char);
  } else {
    CONVERT_CHANNELS_TYPE(short);
  }
}

// @@@ ConvertFreq() : quality loss! Need to use a filter.

#define CONVERT_FREQ_TYPE(Type,Channels) {                      \
  Type *NewData=new Type[NewNumSamples*Channels];               \
  Type *OldData=(Type*)d;                                       \
  for (unsigned long i=0;i<NewNumSamples;i++) {                 \
    int samppos = (int)(i/Factor);                              \
    if (Channels==1) {                                          \
      NewData[i]=OldData[samppos];                              \
    } else {                                                    \
      NewData[2*i]=OldData[2*samppos];                          \
      NewData[2*i+1]=OldData[2*samppos+1];                      \
    }                                                           \
  }                                                             \
  NumSamples = NewNumSamples;                                   \
  return NewData;                                               \
}

void *ConvertFreq(void *d, const csSoundFormat *oldfmt,
  const csSoundFormat *newfmt, long &NumSamples) {
  float Factor=newfmt->Freq/oldfmt->Freq;
  unsigned long NewNumSamples=(unsigned long)(NumSamples*Factor);
  if (oldfmt->Bits==16) {
    CONVERT_FREQ_TYPE(short,oldfmt->Channels);
  } else {
    CONVERT_FREQ_TYPE(unsigned char,oldfmt->Channels);
  }
}

void csSoundDataRaw::Convert(const csSoundFormat *RequestFormat) {
  if (Format.Bits==16 && RequestFormat->Bits==8) {
    REPLACE_DATA(ConvertBuffer16To8Bit(Data, NumSamples * Format.Channels));
    Format.Bits = 8;
  } else if (Format.Bits==8 && RequestFormat->Bits==16) {
    REPLACE_DATA(ConvertBuffer8To16Bit(Data, NumSamples * Format.Channels));
    Format.Bits = 16;
  }

  if (Format.Channels != RequestFormat->Channels && RequestFormat->Channels != -1) {
    REPLACE_DATA(ConvertChannels(Data, &Format, RequestFormat, NumSamples));
    Format.Channels = RequestFormat->Channels;
  }

  if (RequestFormat->Freq != Format.Freq && RequestFormat->Freq != -1) {
    REPLACE_DATA(ConvertFreq(Data, &Format, RequestFormat, NumSamples));
    Format.Freq = RequestFormat->Freq;
  }
}

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

IMPLEMENT_IBASE(csSoundStreamRaw)
  IMPLEMENTS_INTERFACE(iSoundStream)
IMPLEMENT_IBASE_END

csSoundStreamRaw::csSoundStreamRaw(csSoundDataRaw *sd) {
  CONSTRUCT_IBASE(NULL);
  Data=sd;
  Data->IncRef();
  Position=0;
}

csSoundStreamRaw::~csSoundStreamRaw() {
  Data->DecRef();
}

const csSoundFormat *csSoundStreamRaw::GetFormat() {
  return &Data->Format;
}

bool csSoundStreamRaw::MayPrecache() {
  return true;
}

void csSoundStreamRaw::Restart() {
  Position=0;
}

void *csSoundStreamRaw::Read(long &Num) {
  // test if we should return as much data as possible
  if (Num == -1) Num = Data->NumSamples - Position;
  // decrease size of data if we reached the end of the sound
  if (Position + Num > Data->NumSamples) Num = Data->NumSamples-Position;
  // set up return data
  void *d;
  if (Data->Format.Bits==16) {
    d=(short*)Data->Data+Position*Data->Format.Channels;
  } else {
    d=(unsigned char *)Data->Data+Position*Data->Format.Channels;
  }
  Position+=Num;
  // the data buffer is like another reference to this stream
  IncRef();
  return d;
}

void csSoundStreamRaw::DiscardBuffer(void *buf) {
  (void)buf;
  DecRef();
}
<|endoftext|>


<commit_before>#ifndef ORM_ATTR_HPP
#define ORM_ATTR_HPP

#include <ostream>
#include <utility>
#include <string>

#include <ORM/fields/private/VAttr.hpp>

namespace orm
{
    class Query;

    /**
     * \brief Store a value ass database row
     **/
    template<typename T>
    class Attr : public VAttr
    {
        public:
            /**
             * \brief Make a Attr
             *
             * \param value value to store
             * \param column Column in bdd
             **/
            Attr(const T& value,const std::string& column);

            /**
             * \brief Make a Attr
             *
             * \param column Column in bdd
             **/
            Attr(const std::string& column);

            Attr(const Attr&) = delete;

            typedef T type; ///< type of stored object
            T value; ///< value stored

            /**
             * \brief assignement operator
             *
             * \param v value to copy
             *
             * \return value
             **/
            template<typename U> T& operator=(const U& v){value=v;modify=true;return value;};

            /**
             * \brief assignement operator
             *
             * \param v value to copy
             *
             * \return *this
             **/
            Attr<T>& operator=(const Attr<T>& v) {value=v.value;modify=true;return*this;};

            /**
             * \brief addition operator
             *
             * \param v value to add
             *
             * \return value+v
             **/
            template<typename U> auto operator+(const U& v) -> decltype(value+v) const {return value+v;};

            /**
             * \brief sub operator
             *
             * \param v value to sub
             *
             * \return value-v
             **/
            template<typename U> auto operator-(const U& v) -> decltype(value-v) const {return value-v;};

            /**
             * \brief  multiply operator
             *
             * \param v value to multiply by
             *
             * \return value*v
             **/
            template<typename U> auto operator*(const U& v) -> decltype(value*v) const {return value*v;};

            /**
             * \brief div operator
             *
             * \param v value to div by
             *
             * \return value/v
             **/
            template<typename U> auto operator/(const U& v) -> decltype(value/v) const {return value/v;};

            /**
             * \brief mod operator
             *
             * \param v value to mod by
             *
             * \return v%value
             **/
            template<typename U> auto operator%(const U& v) -> decltype(value%v) const {return value%v;};

            /**
             * \brief post increment operator
             *
             * \return *this
             **/
            Attr<T>& operator++(){++value;modify=true;return *this;};

            /**
             * \brief pre increment operator
             *
             * \return *this
             **/
            Attr<T>& operator++(int){value++;modify=true;return*this;};

            /**
             * \brief post deincrement operator
             *
             * \return *this
             **/
            Attr<T>& operator--(){--value;modify=true;return*this;};

            /**
             * \brief pre deincrement operator
             *
             * \return *this
             **/
            Attr<T>& operator--(int){value--;modify=true;return*this;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value == v
             **/
            template<typename U> auto operator==(const U& v) -> decltype(value==v) const {return value==v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value != v
             **/
            template<typename U> auto operator!=(const U& v) -> decltype(value!=v)  const {return value!=v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value > v
             **/
            template<typename U> auto operator>(const U& v) -> decltype(value>v) const {return value>v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value < v
             **/
            template<typename U> auto operator<(const U& v) -> decltype(value<v) const {return value<v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value >= v
             **/
            template<typename U> auto operator>=(const U& v) -> decltype(value>=v)  const {return value>=v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value <= v
             **/
            template<typename U> auto operator<=(const U& v) -> decltype(value<=v)  const {return value<=v;};

            /**
             * \brief negation operator
             *
             * \return !value
             **/
            bool operator!()const {return !value;};

            /**
             * \brief addition operator
             *
             * \param v value to add
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator+=(const U& v) {value+=v;modify=true;return*this;};

            /**
             * \brief sub operator
             *
             * \param v value to sub
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator-=(const U& v) {value-=v;modify=true;return*this;};

            /**
             * \brief multiply operator
             *
             * \param v value to multiply
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator*=(const U& v) {value*=v;modify=true;return*this;};

            /**
             * \brief div operator
             *
             * \param v value to div
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator/=(const U& v) {value/=v;modify=true;return*this;};

            /**
             * \brief mod operator
             *
             * \param v value to mod
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator%=(const U& v) {value%=v;modify=true;return*this;};

            /**
             * \brief cast operator
             *
             * \cast this in value
             **/
            //operator T() {return value;};

            /**
             * \brief cast operator
             *
             * \cast this in value
             **/
            operator T()const {return value;};

            /**
             * \brief addition operator
             *
             * \param v value to add
             *
             * \return value+v.value
             **/
            T operator+(const Attr<T>& v) const {return value+v.value;};

            /**
             * \brief sub operator
             *
             * \param v value to sub
             *
             * \return value-v.value
             **/
            T operator-(const Attr<T>& v) const {return value-v.value;};

            /**
             * \brief multiply operator
             *
             * \param v value to multiply
             *
             * \return value*v.value
             **/
            T operator*(const Attr<T>& v) const {return value*v.value;};

            /**
             * \brief div operator
             *
             * \param v value to div
             *
             * \return value/v.value
             **/
            T operator/(const Attr<T>& v) const {return value/v.value;};

            /**
             * \brief mod operator
             *
             * \param v value to mod
             *
             * \return value%v.value
             **/
            T operator%(const Attr<T>& v) const {return value%v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value == v.value
             **/
            template<typename U> bool operator==(const Attr<U>& v)const {return value==v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value != v.value
             **/
            template<typename U> bool operator!=(const Attr<U>& v)const {return value!=v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value > v.value
             **/
            template<typename U> bool operator>(const Attr<U>& v)const {return value>v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value < v.value
             **/
            template<typename U> bool operator<(const Attr<U>& v)const {return value<v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value >= v.value
             **/
            template<typename U> bool operator>=(const Attr<U>& v)const {return value>=v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value <= v.value
             **/
            template<typename U> bool operator<=(const Attr<U>& v)const {return value<=v.value;};

            /**
             * \brief addition operator
             *
             * \param v value to add
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator+=(const Attr<U>& v) {value+=v.value;modify=true;return*this;};

            /**
             * \brief sub operator
             *
             * \param v value to sub
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator-=(const Attr<U>& v) {value-=v.value;modify=true;return*this;};

            /**
             * \brief multiply operator
             *
             * \param v value to multiply
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator*=(const Attr<U>& v) {value*=v.value;modify=true;return*this;};

            /**
             * \brief div operator
             *
             * \param v value to div
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator/=(const Attr<U>& v) {value/=v.value;modify=true;return*this;};

            /**
             * \brief mod operator
             *
             * \param v value to mod
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator%=(const Attr<U>& v) {value%=v.value;modify=true;return*this;};

            /**
             * \brief print the stored value
             *
             * \param output print in this stream
             *
             * \return output
             **/
            virtual std::ostream& print_value(std::ostream& output)const;

        protected:
            /**
             * \brief print the stored value
             *
             * \param output print in this stream
             **/
            virtual void print(std::ostream& output) const;

            /**
             * \brief Set the value in the query (use for dispatch
             *
             * \param query Query to set in
             * \param column culum number to set
             *
             * \return false if fail
             */
            virtual bool set(Query& query,const unsigned int& column);

            /**
             * \brief Extracte the value from the query row
             *
             * \param query executed query
             * \param prefix column number to get
             * \param max_depth max depth of construction recurtion
             *
             * \return false if fail
             **/
            virtual bool get(const Query& query,int& prefix,int max_depth);
    };

    // define more common type
    using IntegerField = Attr<int>;
    using BooleanField = Attr<bool>;
    using PositiveIntegerField = Attr<unsigned int>;
    using BigIntegerField = Attr<long long int>;
    using FloatField = Attr<float>;
    using DoubleField = Attr<double>;
    using BigDoubleField = Attr<long double>;
    using TextField = Attr<std::string>;

    template<size_t max_length>
    using CharField = Attr<std::string>;

    /*template<bool auto_increment>
    using AutoField = Attr<int>;*/

};
#include <ORM/fields/Attr.tpl>

#endif
<commit_msg>add mysql type on attr to add<commit_after>#ifndef ORM_ATTR_HPP
#define ORM_ATTR_HPP

#include <ostream>
#include <utility>
#include <string>

#include <ORM/fields/private/VAttr.hpp>

namespace orm
{
    class Query;

    /**
     * \brief Store a value ass database row
     **/
    template<typename T>
    class Attr : public VAttr
    {
        public:
            /**
             * \brief Make a Attr
             *
             * \param value value to store
             * \param column Column in bdd
             **/
            Attr(const T& value,const std::string& column);

            /**
             * \brief Make a Attr
             *
             * \param column Column in bdd
             **/
            Attr(const std::string& column);

            Attr(const Attr&) = delete;

            typedef T type; ///< type of stored object
            T value; ///< value stored

            /**
             * \brief assignement operator
             *
             * \param v value to copy
             *
             * \return value
             **/
            template<typename U> T& operator=(const U& v){value=v;modify=true;return value;};

            /**
             * \brief assignement operator
             *
             * \param v value to copy
             *
             * \return *this
             **/
            Attr<T>& operator=(const Attr<T>& v) {value=v.value;modify=true;return*this;};

            /**
             * \brief addition operator
             *
             * \param v value to add
             *
             * \return value+v
             **/
            template<typename U> auto operator+(const U& v) -> decltype(value+v) const {return value+v;};

            /**
             * \brief sub operator
             *
             * \param v value to sub
             *
             * \return value-v
             **/
            template<typename U> auto operator-(const U& v) -> decltype(value-v) const {return value-v;};

            /**
             * \brief  multiply operator
             *
             * \param v value to multiply by
             *
             * \return value*v
             **/
            template<typename U> auto operator*(const U& v) -> decltype(value*v) const {return value*v;};

            /**
             * \brief div operator
             *
             * \param v value to div by
             *
             * \return value/v
             **/
            template<typename U> auto operator/(const U& v) -> decltype(value/v) const {return value/v;};

            /**
             * \brief mod operator
             *
             * \param v value to mod by
             *
             * \return v%value
             **/
            template<typename U> auto operator%(const U& v) -> decltype(value%v) const {return value%v;};

            /**
             * \brief post increment operator
             *
             * \return *this
             **/
            Attr<T>& operator++(){++value;modify=true;return *this;};

            /**
             * \brief pre increment operator
             *
             * \return *this
             **/
            Attr<T>& operator++(int){value++;modify=true;return*this;};

            /**
             * \brief post deincrement operator
             *
             * \return *this
             **/
            Attr<T>& operator--(){--value;modify=true;return*this;};

            /**
             * \brief pre deincrement operator
             *
             * \return *this
             **/
            Attr<T>& operator--(int){value--;modify=true;return*this;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value == v
             **/
            template<typename U> auto operator==(const U& v) -> decltype(value==v) const {return value==v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value != v
             **/
            template<typename U> auto operator!=(const U& v) -> decltype(value!=v)  const {return value!=v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value > v
             **/
            template<typename U> auto operator>(const U& v) -> decltype(value>v) const {return value>v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value < v
             **/
            template<typename U> auto operator<(const U& v) -> decltype(value<v) const {return value<v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value >= v
             **/
            template<typename U> auto operator>=(const U& v) -> decltype(value>=v)  const {return value>=v;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value <= v
             **/
            template<typename U> auto operator<=(const U& v) -> decltype(value<=v)  const {return value<=v;};

            /**
             * \brief negation operator
             *
             * \return !value
             **/
            bool operator!()const {return !value;};

            /**
             * \brief addition operator
             *
             * \param v value to add
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator+=(const U& v) {value+=v;modify=true;return*this;};

            /**
             * \brief sub operator
             *
             * \param v value to sub
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator-=(const U& v) {value-=v;modify=true;return*this;};

            /**
             * \brief multiply operator
             *
             * \param v value to multiply
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator*=(const U& v) {value*=v;modify=true;return*this;};

            /**
             * \brief div operator
             *
             * \param v value to div
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator/=(const U& v) {value/=v;modify=true;return*this;};

            /**
             * \brief mod operator
             *
             * \param v value to mod
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator%=(const U& v) {value%=v;modify=true;return*this;};

            /**
             * \brief cast operator
             *
             * \cast this in value
             **/
            //operator T() {return value;};

            /**
             * \brief cast operator
             *
             * \cast this in value
             **/
            operator T()const {return value;};

            /**
             * \brief addition operator
             *
             * \param v value to add
             *
             * \return value+v.value
             **/
            T operator+(const Attr<T>& v) const {return value+v.value;};

            /**
             * \brief sub operator
             *
             * \param v value to sub
             *
             * \return value-v.value
             **/
            T operator-(const Attr<T>& v) const {return value-v.value;};

            /**
             * \brief multiply operator
             *
             * \param v value to multiply
             *
             * \return value*v.value
             **/
            T operator*(const Attr<T>& v) const {return value*v.value;};

            /**
             * \brief div operator
             *
             * \param v value to div
             *
             * \return value/v.value
             **/
            T operator/(const Attr<T>& v) const {return value/v.value;};

            /**
             * \brief mod operator
             *
             * \param v value to mod
             *
             * \return value%v.value
             **/
            T operator%(const Attr<T>& v) const {return value%v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value == v.value
             **/
            template<typename U> bool operator==(const Attr<U>& v)const {return value==v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value != v.value
             **/
            template<typename U> bool operator!=(const Attr<U>& v)const {return value!=v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value > v.value
             **/
            template<typename U> bool operator>(const Attr<U>& v)const {return value>v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value < v.value
             **/
            template<typename U> bool operator<(const Attr<U>& v)const {return value<v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value >= v.value
             **/
            template<typename U> bool operator>=(const Attr<U>& v)const {return value>=v.value;};

            /**
             * \brief Comparaison operator
             *
             * \param v value to compare with
             *
             * \return value <= v.value
             **/
            template<typename U> bool operator<=(const Attr<U>& v)const {return value<=v.value;};

            /**
             * \brief addition operator
             *
             * \param v value to add
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator+=(const Attr<U>& v) {value+=v.value;modify=true;return*this;};

            /**
             * \brief sub operator
             *
             * \param v value to sub
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator-=(const Attr<U>& v) {value-=v.value;modify=true;return*this;};

            /**
             * \brief multiply operator
             *
             * \param v value to multiply
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator*=(const Attr<U>& v) {value*=v.value;modify=true;return*this;};

            /**
             * \brief div operator
             *
             * \param v value to div
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator/=(const Attr<U>& v) {value/=v.value;modify=true;return*this;};

            /**
             * \brief mod operator
             *
             * \param v value to mod
             *
             * \return *this
             **/
            template<typename U> Attr<T>& operator%=(const Attr<U>& v) {value%=v.value;modify=true;return*this;};

            /**
             * \brief print the stored value
             *
             * \param output print in this stream
             *
             * \return output
             **/
            virtual std::ostream& print_value(std::ostream& output)const;

        protected:
            /**
             * \brief print the stored value
             *
             * \param output print in this stream
             **/
            virtual void print(std::ostream& output) const;

            /**
             * \brief Set the value in the query (use for dispatch
             *
             * \param query Query to set in
             * \param column culum number to set
             *
             * \return false if fail
             */
            virtual bool set(Query& query,const unsigned int& column);

            /**
             * \brief Extracte the value from the query row
             *
             * \param query executed query
             * \param prefix column number to get
             * \param max_depth max depth of construction recurtion
             *
             * \return false if fail
             **/
            virtual bool get(const Query& query,int& prefix,int max_depth);
    };

    // define more common type
    using IntegerField = Attr<int>;
    using BooleanField = Attr<bool>;
    using PositiveIntegerField = Attr<unsigned int>;
    using BigIntegerField = Attr<long long int>;
    using FloatField = Attr<float>;
    using DoubleField = Attr<double>;
    using BigDoubleField = Attr<long double>;
    using TextField = Attr<std::string>;

    template<size_t max_length>
    using CharField = Attr<std::string>;

    /*template<bool auto_increment>
    using AutoField = Attr<int>;*/

  /*      TINYINT[(length)] [UNSIGNED] [ZEROFILL]
  | SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
  | MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
  | INT[(length)] [UNSIGNED] [ZEROFILL]
  | INTEGER[(length)] [UNSIGNED] [ZEROFILL]
  | BIGINT[(length)] [UNSIGNED] [ZEROFILL]
  | REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
  | DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
  | NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
  | DATE
  | TIME
  | TIMESTAMP
  | DATETIME
  | CHAR(length) [BINARY | ASCII | UNICODE]
  | VARCHAR(length) [BINARY]
  | TINYBLOB
  | BLOB
  | MEDIUMBLOB
  | LONGBLOB
  | TINYTEXT
  | TEXT
  | spatial_type*/

};
#include <ORM/fields/Attr.tpl>

#endif
<|endoftext|>


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

#define UNICODE

#include <windows.h>
#include <msiquery.h>
#include <string.h>
#include <malloc.h>

#define CHART_COMPONENT 1
#define DRAW_COMPONENT 2
#define IMPRESS_COMPONENT 4
#define CALC_COMPONENT 8
#define WRITER_COMPONENT 16

typedef int ( __stdcall * DllNativeProc ) ( int, BOOL );

BOOL UnicodeEquals( wchar_t* pStr1, wchar_t* pStr2 )
{
    if ( pStr1 == NULL && pStr2 == NULL )
        return TRUE;
    else if ( pStr1 == NULL || pStr2 == NULL )
        return FALSE;

    while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
        pStr1++, pStr2++;

    return ( *pStr1 == 0 && *pStr2 == 0 );
}

//----------------------------------------------------------
char* UnicodeToAnsiString( wchar_t* pUniString )
{
    int len = WideCharToMultiByte(
        CP_ACP, 0, pUniString, -1, 0, 0, 0, 0 );

    char* buff = reinterpret_cast<char*>( malloc( len ) );

    WideCharToMultiByte(
        CP_ACP, 0, pUniString, -1, buff, len, 0, 0 );

    return buff;
}

//----------------------------------------------------------
void RegisterActiveXNative( const char* pActiveXPath, int nMode, BOOL InstallForAllUser )
{
    HINSTANCE hModule = LoadLibraryExA( pActiveXPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
    if( !( hModule <= ( HINSTANCE )HINSTANCE_ERROR ) )
    {
        DllNativeProc pNativeProc = ( DllNativeProc )GetProcAddress( hModule, "DllRegisterServerNative" );
        if( pNativeProc!=NULL )
            ( *pNativeProc )( nMode, InstallForAllUser );

        FreeLibrary( hModule );
    }
}

//----------------------------------------------------------
void UnregisterActiveXNative( const char* pActiveXPath, int nMode, BOOL InstallForAllUser )
{
    HINSTANCE hModule = LoadLibraryExA( pActiveXPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
    if( !( hModule <= ( HINSTANCE )HINSTANCE_ERROR ) )
    {
        DllNativeProc pNativeProc = ( DllNativeProc )GetProcAddress( hModule, "DllUnregisterServerNative" );
        if( pNativeProc!=NULL )
            ( *pNativeProc )( nMode, InstallForAllUser );

        FreeLibrary( hModule );
    }
}

//----------------------------------------------------------
BOOL GetMsiProp( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
{
    DWORD sz = 0;
       if ( MsiGetProperty( hMSI, pPropName, L"", &sz ) == ERROR_MORE_DATA )
       {
           sz++;
           DWORD nbytes = sz * sizeof( wchar_t );
           wchar_t* buff = reinterpret_cast<wchar_t*>( malloc( nbytes ) );
           ZeroMemory( buff, nbytes );
           MsiGetProperty( hMSI, pPropName, buff, &sz );
           *ppValue = buff;

        return TRUE;
    }

    return FALSE;
}

//----------------------------------------------------------
BOOL GetActiveXControlPath( MSIHANDLE hMSI, char** ppActiveXPath )
{
    wchar_t* pProgPath = NULL;
    if ( GetMsiProp( hMSI, L"OfficeFolder", &pProgPath ) && pProgPath )
       {
        char* pCharProgPath = UnicodeToAnsiString( pProgPath );
        if ( pCharProgPath )
        {
            int nLen = strlen( pCharProgPath );
            *ppActiveXPath = reinterpret_cast<char*>( malloc( nLen + 23 ) );
            strncpy( *ppActiveXPath, pCharProgPath, nLen );
            strncpy( (*ppActiveXPath) + nLen, "program\\so_activex.dll", 22 );
            (*ppActiveXPath)[nLen+22] = 0;

            free( pCharProgPath );

            return TRUE;
        }

        free( pProgPath );
    }

    return FALSE;
}

//----------------------------------------------------------
BOOL GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDeinstallMode )
{
    // for now the chart is always installed
    nOldInstallMode = CHART_COMPONENT;
    nInstallMode = CHART_COMPONENT;
    nDeinstallMode = 0;

    INSTALLSTATE current_state;
       INSTALLSTATE future_state;

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Wrt_Bin", &current_state, &future_state ) )
    {
        // analyze writer installation mode
        if ( current_state == INSTALLSTATE_LOCAL )
            nOldInstallMode |= WRITER_COMPONENT;

        if ( future_state == INSTALLSTATE_LOCAL )
            nInstallMode |= WRITER_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= WRITER_COMPONENT;
    }
    else
    {
        // assert( FALSE );
    }

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Calc_Bin", &current_state, &future_state ) )
    {
        // analyze calc installation mode
        if ( current_state == INSTALLSTATE_LOCAL )
            nOldInstallMode |= CALC_COMPONENT;

        if ( future_state == INSTALLSTATE_LOCAL )
            nInstallMode |= CALC_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= CALC_COMPONENT;
    }
    else
    {
        // assert( FALSE );
    }

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Draw_Bin", &current_state, &future_state ) )
    {
        // analyze draw installation mode
        if ( current_state == INSTALLSTATE_LOCAL )
            nOldInstallMode |= DRAW_COMPONENT;

        if ( future_state == INSTALLSTATE_LOCAL )
            nInstallMode |= DRAW_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= DRAW_COMPONENT;
    }
    else
    {
        // assert( FALSE );
    }

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Impress_Bin", &current_state, &future_state ) )
    {
        // analyze impress installation mode
        if ( current_state == INSTALLSTATE_LOCAL )
            nOldInstallMode |= IMPRESS_COMPONENT;

        if ( future_state == INSTALLSTATE_LOCAL )
            nInstallMode |= IMPRESS_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= IMPRESS_COMPONENT;
    }
    else
    {
        // assert( FALSE );
    }

    return TRUE;
}

//----------------------------------------------------------
BOOL MakeInstallForAllUsers( MSIHANDLE hMSI )
{
    BOOL bResult = FALSE;
    wchar_t* pVal = NULL;
    if ( GetMsiProp( hMSI, L"ALLUSERS", &pVal ) && pVal )
    {
        bResult = UnicodeEquals( pVal , L"1" );
        free( pVal );
    }

    return bResult;
}

//----------------------------------------------------------
extern "C" UINT __stdcall InstallActiveXControl( MSIHANDLE hMSI )
{
    int nOldInstallMode = 0;
    int nInstallMode = 0;
    int nDeinstallMode = 0;

    // MessageBox(NULL, L"InstallActiveXControl", L"Information", MB_OK | MB_ICONINFORMATION);

    INSTALLSTATE current_state;
    INSTALLSTATE future_state;

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
    {
        BOOL bInstallForAllUser = MakeInstallForAllUsers( hMSI );
        char* pActiveXPath = NULL;
        if ( GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath
        && GetDelta( hMSI, nOldInstallMode, nInstallMode, nDeinstallMode ) )
        {
            if ( future_state == INSTALLSTATE_LOCAL )
            {
                // the control is installed in the new selected configuration

                if ( current_state == INSTALLSTATE_LOCAL && nDeinstallMode )
                    UnregisterActiveXNative( pActiveXPath, nInstallMode, bInstallForAllUser );

                if ( nInstallMode )
                    RegisterActiveXNative( pActiveXPath, nInstallMode, bInstallForAllUser );
            }
            else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            {
                if ( nOldInstallMode )
                    UnregisterActiveXNative( pActiveXPath, nOldInstallMode, bInstallForAllUser );
            }
        }

        if ( pActiveXPath )
            free( pActiveXPath );
    }
    else
    {
        // assert( FALSE );
    }

    return ERROR_SUCCESS;
}

//----------------------------------------------------------
extern "C" __stdcall UINT DeinstallActiveXControl( MSIHANDLE hMSI )
{
    INSTALLSTATE current_state;
    INSTALLSTATE future_state;

    // MessageBox(NULL, L"DeinstallActiveXControl", L"Information", MB_OK | MB_ICONINFORMATION);

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
    {
        char* pActiveXPath = NULL;
        if ( current_state == INSTALLSTATE_LOCAL && GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath )
        {
            BOOL bInstallForAllUser = MakeInstallForAllUsers( hMSI );

            wchar_t* rm = NULL;
            if ( GetMsiProp( hMSI, L"REMOVE", &rm ) && rm && UnicodeEquals( rm, L"ALL" ) )
            {
                UnregisterActiveXNative( pActiveXPath,
                                        CHART_COMPONENT
                                        | DRAW_COMPONENT
                                        | IMPRESS_COMPONENT
                                        | CALC_COMPONENT
                                        | WRITER_COMPONENT,
                                        bInstallForAllUser );
            }

            if ( rm )
                free( rm );

            free( pActiveXPath );
        }
    }

    return ERROR_SUCCESS;
}

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

#define UNICODE

#include <windows.h>
#include <msiquery.h>
#include <string.h>
#include <malloc.h>

#define CHART_COMPONENT 1
#define DRAW_COMPONENT 2
#define IMPRESS_COMPONENT 4
#define CALC_COMPONENT 8
#define WRITER_COMPONENT 16

typedef int ( __stdcall * DllNativeProc ) ( int, BOOL );

BOOL UnicodeEquals( wchar_t* pStr1, wchar_t* pStr2 )
{
    if ( pStr1 == NULL && pStr2 == NULL )
        return TRUE;
    else if ( pStr1 == NULL || pStr2 == NULL )
        return FALSE;

    while( *pStr1 == *pStr2 && *pStr1 && *pStr2 )
        pStr1++, pStr2++;

    return ( *pStr1 == 0 && *pStr2 == 0 );
}

//----------------------------------------------------------
char* UnicodeToAnsiString( wchar_t* pUniString )
{
    int len = WideCharToMultiByte(
        CP_ACP, 0, pUniString, -1, 0, 0, 0, 0 );

    char* buff = reinterpret_cast<char*>( malloc( len ) );

    WideCharToMultiByte(
        CP_ACP, 0, pUniString, -1, buff, len, 0, 0 );

    return buff;
}

//----------------------------------------------------------
void RegisterActiveXNative( const char* pActiveXPath, int nMode, BOOL InstallForAllUser )
{
    HINSTANCE hModule = LoadLibraryExA( pActiveXPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
    if( !( hModule <= ( HINSTANCE )HINSTANCE_ERROR ) )
    {
        DllNativeProc pNativeProc = ( DllNativeProc )GetProcAddress( hModule, "DllRegisterServerNative" );
        if( pNativeProc!=NULL )
            ( *pNativeProc )( nMode, InstallForAllUser );

        FreeLibrary( hModule );
    }
}

//----------------------------------------------------------
void UnregisterActiveXNative( const char* pActiveXPath, int nMode, BOOL InstallForAllUser )
{
    HINSTANCE hModule = LoadLibraryExA( pActiveXPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
    if( !( hModule <= ( HINSTANCE )HINSTANCE_ERROR ) )
    {
        DllNativeProc pNativeProc = ( DllNativeProc )GetProcAddress( hModule, "DllUnregisterServerNative" );
        if( pNativeProc!=NULL )
            ( *pNativeProc )( nMode, InstallForAllUser );

        FreeLibrary( hModule );
    }
}

//----------------------------------------------------------
BOOL GetMsiProp( MSIHANDLE hMSI, const wchar_t* pPropName, wchar_t** ppValue )
{
    DWORD sz = 0;
       if ( MsiGetProperty( hMSI, pPropName, L"", &sz ) == ERROR_MORE_DATA )
       {
           sz++;
           DWORD nbytes = sz * sizeof( wchar_t );
           wchar_t* buff = reinterpret_cast<wchar_t*>( malloc( nbytes ) );
           ZeroMemory( buff, nbytes );
           MsiGetProperty( hMSI, pPropName, buff, &sz );
           *ppValue = buff;

        return TRUE;
    }

    return FALSE;
}

//----------------------------------------------------------
BOOL GetActiveXControlPath( MSIHANDLE hMSI, char** ppActiveXPath )
{
    wchar_t* pProgPath = NULL;
    if ( GetMsiProp( hMSI, L"INSTALLLOCATION", &pProgPath ) && pProgPath )
       {
        char* pCharProgPath = UnicodeToAnsiString( pProgPath );
        if ( pCharProgPath )
        {
            int nLen = strlen( pCharProgPath );
            *ppActiveXPath = reinterpret_cast<char*>( malloc( nLen + 23 ) );
            strncpy( *ppActiveXPath, pCharProgPath, nLen );
            strncpy( (*ppActiveXPath) + nLen, "program\\so_activex.dll", 22 );
            (*ppActiveXPath)[nLen+22] = 0;

            free( pCharProgPath );

            return TRUE;
        }

        free( pProgPath );
    }

    return FALSE;
}

//----------------------------------------------------------
BOOL GetDelta( MSIHANDLE hMSI, int& nOldInstallMode, int& nInstallMode, int& nDeinstallMode )
{
    // for now the chart is always installed
    nOldInstallMode = CHART_COMPONENT;
    nInstallMode = CHART_COMPONENT;
    nDeinstallMode = 0;

    INSTALLSTATE current_state;
       INSTALLSTATE future_state;

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Wrt_Bin", &current_state, &future_state ) )
    {
        // analyze writer installation mode
        if ( current_state == INSTALLSTATE_LOCAL )
            nOldInstallMode |= WRITER_COMPONENT;

        if ( future_state == INSTALLSTATE_LOCAL )
            nInstallMode |= WRITER_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= WRITER_COMPONENT;
    }
    else
    {
        // assert( FALSE );
    }

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Calc_Bin", &current_state, &future_state ) )
    {
        // analyze calc installation mode
        if ( current_state == INSTALLSTATE_LOCAL )
            nOldInstallMode |= CALC_COMPONENT;

        if ( future_state == INSTALLSTATE_LOCAL )
            nInstallMode |= CALC_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= CALC_COMPONENT;
    }
    else
    {
        // assert( FALSE );
    }

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Draw_Bin", &current_state, &future_state ) )
    {
        // analyze draw installation mode
        if ( current_state == INSTALLSTATE_LOCAL )
            nOldInstallMode |= DRAW_COMPONENT;

        if ( future_state == INSTALLSTATE_LOCAL )
            nInstallMode |= DRAW_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= DRAW_COMPONENT;
    }
    else
    {
        // assert( FALSE );
    }

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_p_Impress_Bin", &current_state, &future_state ) )
    {
        // analyze impress installation mode
        if ( current_state == INSTALLSTATE_LOCAL )
            nOldInstallMode |= IMPRESS_COMPONENT;

        if ( future_state == INSTALLSTATE_LOCAL )
            nInstallMode |= IMPRESS_COMPONENT;
           else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            nDeinstallMode |= IMPRESS_COMPONENT;
    }
    else
    {
        // assert( FALSE );
    }

    return TRUE;
}

//----------------------------------------------------------
BOOL MakeInstallForAllUsers( MSIHANDLE hMSI )
{
    BOOL bResult = FALSE;
    wchar_t* pVal = NULL;
    if ( GetMsiProp( hMSI, L"ALLUSERS", &pVal ) && pVal )
    {
        bResult = UnicodeEquals( pVal , L"1" );
        free( pVal );
    }

    return bResult;
}

//----------------------------------------------------------
extern "C" UINT __stdcall InstallActiveXControl( MSIHANDLE hMSI )
{
    int nOldInstallMode = 0;
    int nInstallMode = 0;
    int nDeinstallMode = 0;

    // MessageBox(NULL, L"InstallActiveXControl", L"Information", MB_OK | MB_ICONINFORMATION);

    INSTALLSTATE current_state;
    INSTALLSTATE future_state;

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
    {
        BOOL bInstallForAllUser = MakeInstallForAllUsers( hMSI );
        char* pActiveXPath = NULL;
        if ( GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath
        && GetDelta( hMSI, nOldInstallMode, nInstallMode, nDeinstallMode ) )
        {
            if ( future_state == INSTALLSTATE_LOCAL )
            {
                // the control is installed in the new selected configuration

                if ( current_state == INSTALLSTATE_LOCAL && nDeinstallMode )
                    UnregisterActiveXNative( pActiveXPath, nInstallMode, bInstallForAllUser );

                if ( nInstallMode )
                    RegisterActiveXNative( pActiveXPath, nInstallMode, bInstallForAllUser );
            }
            else if ( current_state == INSTALLSTATE_LOCAL && future_state == INSTALLSTATE_ABSENT )
            {
                if ( nOldInstallMode )
                    UnregisterActiveXNative( pActiveXPath, nOldInstallMode, bInstallForAllUser );
            }
        }

        if ( pActiveXPath )
            free( pActiveXPath );
    }
    else
    {
        // assert( FALSE );
    }

    return ERROR_SUCCESS;
}

//----------------------------------------------------------
extern "C" __stdcall UINT DeinstallActiveXControl( MSIHANDLE hMSI )
{
    INSTALLSTATE current_state;
    INSTALLSTATE future_state;

    // MessageBox(NULL, L"DeinstallActiveXControl", L"Information", MB_OK | MB_ICONINFORMATION);

    if ( ERROR_SUCCESS == MsiGetFeatureState( hMSI, L"gm_o_Activexcontrol", &current_state, &future_state ) )
    {
        char* pActiveXPath = NULL;
        if ( current_state == INSTALLSTATE_LOCAL && GetActiveXControlPath( hMSI, &pActiveXPath ) && pActiveXPath )
        {
            BOOL bInstallForAllUser = MakeInstallForAllUsers( hMSI );

            wchar_t* rm = NULL;
            if ( GetMsiProp( hMSI, L"REMOVE", &rm ) && rm && UnicodeEquals( rm, L"ALL" ) )
            {
                UnregisterActiveXNative( pActiveXPath,
                                        CHART_COMPONENT
                                        | DRAW_COMPONENT
                                        | IMPRESS_COMPONENT
                                        | CALC_COMPONENT
                                        | WRITER_COMPONENT,
                                        bInstallForAllUser );
            }

            if ( rm )
                free( rm );

            free( pActiveXPath );
        }
    }

    return ERROR_SUCCESS;
}

<|endoftext|>