<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

#include "modules/prediction/common/feature_output.h"

#include <vector>

#include "cyber/common/file.h"
#include "modules/common/util/string_util.h"
#include "modules/prediction/common/prediction_system_gflags.h"

namespace apollo {
namespace prediction {

using apollo::common::util::StrCat;

Features FeatureOutput::features_;
ListDataForLearning FeatureOutput::list_data_for_learning_;
ListPredictionResult FeatureOutput::list_prediction_result_;
ListFrameEnv FeatureOutput::list_frame_env_;
ListDataForTuning FeatureOutput::list_data_for_tuning_;
std::size_t FeatureOutput::idx_feature_ = 0;
std::size_t FeatureOutput::idx_learning_ = 0;
std::size_t FeatureOutput::idx_prediction_result_ = 0;
std::size_t FeatureOutput::idx_frame_env_ = 0;
std::size_t FeatureOutput::idx_tuning_ = 0;

void FeatureOutput::Close() {
  ADEBUG << "Close feature output";
  switch (FLAGS_prediction_offline_mode) {
    case 1: {
      WriteFeatureProto();
      break;
    }
    case 2: {
      WriteDataForLearning();
      break;
    }
    case 3: {
      WritePredictionResult();
      break;
    }
    case 4: {
      WriteFrameEnv();
      break;
    }
    case 5: {
      WriteDataForTuning();
      break;
    }
    default: {
      // No data dump
      break;
    }
  }
  Clear();
}

void FeatureOutput::Clear() {
  idx_feature_ = 0;
  idx_learning_ = 0;
  features_.Clear();
  list_data_for_learning_.Clear();
}

bool FeatureOutput::Ready() {
  Clear();
  return true;
}

void FeatureOutput::InsertFeatureProto(const Feature& feature) {
  features_.add_feature()->CopyFrom(feature);
}

void FeatureOutput::InsertDataForLearning(
    const Feature& feature, const std::vector<double>& feature_values,
    const std::string& category, const LaneSequence* lane_sequence_ptr) {
  DataForLearning* data_for_learning =
      list_data_for_learning_.add_data_for_learning();
  data_for_learning->set_id(feature.id());
  data_for_learning->set_timestamp(feature.timestamp());
  for (size_t i = 0; i < feature_values.size(); ++i) {
    data_for_learning->add_features_for_learning(feature_values[i]);
  }
  data_for_learning->set_category(category);
  ADEBUG << "Insert [" << category
         << "] data for learning with size = " << feature_values.size();
  if (lane_sequence_ptr != nullptr) {
    data_for_learning->set_lane_sequence_id(
        lane_sequence_ptr->lane_sequence_id());
  }
}

void FeatureOutput::InsertPredictionResult(
    const int obstacle_id, const PredictionObstacle& prediction_obstacle) {
  PredictionResult* prediction_result =
      list_prediction_result_.add_prediction_result();
  prediction_result->set_id(obstacle_id);
  prediction_result->set_timestamp(prediction_obstacle.timestamp());
  for (int i = 0; i < prediction_obstacle.trajectory_size(); ++i) {
    prediction_result->add_trajectory()->CopyFrom(
        prediction_obstacle.trajectory(i));
  }
}

void FeatureOutput::InsertFrameEnv(const FrameEnv& frame_env) {
  list_frame_env_.add_frame_env()->CopyFrom(frame_env);
}

void FeatureOutput::InsertDataForTuning(
    const Feature& feature, const std::vector<double>& feature_values,
    const std::string& category) {
  DataForTuning* data_for_tuning =
      list_data_for_tuning_.add_data_for_tuning();
  data_for_tuning->set_id(feature.id());
  data_for_tuning->set_timestamp(feature.timestamp());
  for (size_t i = 0; i < feature_values.size(); ++i) {
    data_for_tuning->add_values_for_tuning(feature_values[i]);
  }
  data_for_tuning->set_category(category);
  ADEBUG << "Insert [" << category
         << "] data for tuning with size = " << feature_values.size();
}

void FeatureOutput::WriteFeatureProto() {
  if (features_.feature_size() <= 0) {
    ADEBUG << "Skip writing empty feature.";
  } else {
    const std::string file_name = StrCat(FLAGS_prediction_data_dir, "/feature.",
                                         std::to_string(idx_feature_), ".bin");
    cyber::common::SetProtoToBinaryFile(features_, file_name);
    features_.Clear();
    ++idx_feature_;
  }
}

void FeatureOutput::WriteDataForLearning() {
  if (list_data_for_learning_.data_for_learning().empty()) {
    ADEBUG << "Skip writing empty data_for_learning.";
  } else {
    const std::string file_name =
        StrCat(FLAGS_prediction_data_dir, "/datalearn.",
               std::to_string(idx_learning_), ".bin");
    cyber::common::SetProtoToBinaryFile(list_data_for_learning_, file_name);
    list_data_for_learning_.Clear();
    ++idx_learning_;
  }
}

void FeatureOutput::WritePredictionResult() {
  if (list_prediction_result_.prediction_result().empty()) {
    ADEBUG << "Skip writing empty prediction_result.";
  } else {
    const std::string file_name =
        StrCat(FLAGS_prediction_data_dir, "/prediction_result.",
               std::to_string(idx_prediction_result_), ".bin");
    cyber::common::SetProtoToBinaryFile(list_prediction_result_, file_name);
    list_prediction_result_.Clear();
    ++idx_prediction_result_;
  }
}

void FeatureOutput::WriteFrameEnv() {
  if (list_frame_env_.frame_env().empty()) {
    ADEBUG << "Skip writing empty prediction_result.";
  } else {
    const std::string file_name =
        StrCat(FLAGS_prediction_data_dir, "/frame_env.",
               std::to_string(idx_frame_env_), ".bin");
    cyber::common::SetProtoToBinaryFile(list_frame_env_, file_name);
    list_frame_env_.Clear();
    ++idx_frame_env_;
  }
}

void FeatureOutput::WriteDataForTuning() {
  if (list_data_for_tuning_.data_for_tuning().empty()) {
    ADEBUG << "Skip writing empty data_for_tuning.";
    return;
  }
  const std::string file_name =
      StrCat(FLAGS_prediction_data_dir, "/datatuning.",
             std::to_string(idx_tuning_), ".bin");
  cyber::common::SetProtoToBinaryFile(list_data_for_tuning_, file_name);
  list_data_for_tuning_.Clear();
  ++idx_tuning_;
}

int FeatureOutput::Size() { return features_.feature_size(); }

int FeatureOutput::SizeOfDataForLearning() {
  return list_data_for_learning_.data_for_learning_size();
}

int FeatureOutput::SizeOfPredictionResult() {
  return list_prediction_result_.prediction_result_size();
}

int FeatureOutput::SizeOfFrameEnv() { return list_frame_env_.frame_env_size(); }

int FeatureOutput::SizeOfDataForTuning() {
  return list_data_for_tuning_.data_for_tuning_size();
}

}  // namespace prediction
}  // namespace apollo
<commit_msg>Update feature_output.cc<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

#include "modules/prediction/common/feature_output.h"

#include <vector>

#include "cyber/common/file.h"
#include "modules/common/util/string_util.h"
#include "modules/prediction/common/prediction_system_gflags.h"

namespace apollo {
namespace prediction {

using apollo::common::util::StrCat;

Features FeatureOutput::features_;
ListDataForLearning FeatureOutput::list_data_for_learning_;
ListPredictionResult FeatureOutput::list_prediction_result_;
ListFrameEnv FeatureOutput::list_frame_env_;
ListDataForTuning FeatureOutput::list_data_for_tuning_;
std::size_t FeatureOutput::idx_feature_ = 0;
std::size_t FeatureOutput::idx_learning_ = 0;
std::size_t FeatureOutput::idx_prediction_result_ = 0;
std::size_t FeatureOutput::idx_frame_env_ = 0;
std::size_t FeatureOutput::idx_tuning_ = 0;

void FeatureOutput::Close() {
  ADEBUG << "Close feature output";
  switch (FLAGS_prediction_offline_mode) {
    case 1: {
      WriteFeatureProto();
      break;
    }
    case 2: {
      WriteDataForLearning();
      break;
    }
    case 3: {
      WritePredictionResult();
      break;
    }
    case 4: {
      WriteFrameEnv();
      break;
    }
    case 5: {
      WriteDataForTuning();
      break;
    }
    default: {
      // No data dump
      break;
    }
  }
  Clear();
}

void FeatureOutput::Clear() {
  idx_feature_ = 0;
  idx_learning_ = 0;
  features_.Clear();
  list_data_for_learning_.Clear();
}

bool FeatureOutput::Ready() {
  Clear();
  return true;
}

void FeatureOutput::InsertFeatureProto(const Feature& feature) {
  features_.add_feature()->CopyFrom(feature);
}

void FeatureOutput::InsertDataForLearning(
    const Feature& feature, const std::vector<double>& feature_values,
    const std::string& category, const LaneSequence* lane_sequence_ptr) {
  DataForLearning* data_for_learning =
      list_data_for_learning_.add_data_for_learning();
  data_for_learning->set_id(feature.id());
  data_for_learning->set_timestamp(feature.timestamp());
  for (size_t i = 0; i < feature_values.size(); ++i) {
    data_for_learning->add_features_for_learning(feature_values[i]);
  }
  data_for_learning->set_category(category);
  ADEBUG << "Insert [" << category
         << "] data for learning with size = " << feature_values.size();
  if (lane_sequence_ptr != nullptr) {
    data_for_learning->set_lane_sequence_id(
        lane_sequence_ptr->lane_sequence_id());
  }
}

void FeatureOutput::InsertPredictionResult(
    const int obstacle_id, const PredictionObstacle& prediction_obstacle) {
  PredictionResult* prediction_result =
      list_prediction_result_.add_prediction_result();
  prediction_result->set_id(obstacle_id);
  prediction_result->set_timestamp(prediction_obstacle.timestamp());
  for (int i = 0; i < prediction_obstacle.trajectory_size(); ++i) {
    prediction_result->add_trajectory()->CopyFrom(
        prediction_obstacle.trajectory(i));
  }
}

void FeatureOutput::InsertFrameEnv(const FrameEnv& frame_env) {
  list_frame_env_.add_frame_env()->CopyFrom(frame_env);
}

void FeatureOutput::InsertDataForTuning(
    const Feature& feature, const std::vector<double>& feature_values,
    const std::string& category) {
  DataForTuning* data_for_tuning =
      list_data_for_tuning_.add_data_for_tuning();
  data_for_tuning->set_id(feature.id());
  data_for_tuning->set_timestamp(feature.timestamp());
  *data_for_tuning->mutable_values_for_tuning() =
      {feature_values.begin(), feature_values.end()};
  data_for_tuning->set_category(category);
  ADEBUG << "Insert [" << category
         << "] data for tuning with size = " << feature_values.size();
}

void FeatureOutput::WriteFeatureProto() {
  if (features_.feature_size() <= 0) {
    ADEBUG << "Skip writing empty feature.";
  } else {
    const std::string file_name = StrCat(FLAGS_prediction_data_dir, "/feature.",
                                         std::to_string(idx_feature_), ".bin");
    cyber::common::SetProtoToBinaryFile(features_, file_name);
    features_.Clear();
    ++idx_feature_;
  }
}

void FeatureOutput::WriteDataForLearning() {
  if (list_data_for_learning_.data_for_learning().empty()) {
    ADEBUG << "Skip writing empty data_for_learning.";
  } else {
    const std::string file_name =
        StrCat(FLAGS_prediction_data_dir, "/datalearn.",
               std::to_string(idx_learning_), ".bin");
    cyber::common::SetProtoToBinaryFile(list_data_for_learning_, file_name);
    list_data_for_learning_.Clear();
    ++idx_learning_;
  }
}

void FeatureOutput::WritePredictionResult() {
  if (list_prediction_result_.prediction_result().empty()) {
    ADEBUG << "Skip writing empty prediction_result.";
  } else {
    const std::string file_name =
        StrCat(FLAGS_prediction_data_dir, "/prediction_result.",
               std::to_string(idx_prediction_result_), ".bin");
    cyber::common::SetProtoToBinaryFile(list_prediction_result_, file_name);
    list_prediction_result_.Clear();
    ++idx_prediction_result_;
  }
}

void FeatureOutput::WriteFrameEnv() {
  if (list_frame_env_.frame_env().empty()) {
    ADEBUG << "Skip writing empty prediction_result.";
  } else {
    const std::string file_name =
        StrCat(FLAGS_prediction_data_dir, "/frame_env.",
               std::to_string(idx_frame_env_), ".bin");
    cyber::common::SetProtoToBinaryFile(list_frame_env_, file_name);
    list_frame_env_.Clear();
    ++idx_frame_env_;
  }
}

void FeatureOutput::WriteDataForTuning() {
  if (list_data_for_tuning_.data_for_tuning().empty()) {
    ADEBUG << "Skip writing empty data_for_tuning.";
    return;
  }
  const std::string file_name =
      StrCat(FLAGS_prediction_data_dir, "/datatuning.",
             std::to_string(idx_tuning_), ".bin");
  cyber::common::SetProtoToBinaryFile(list_data_for_tuning_, file_name);
  list_data_for_tuning_.Clear();
  ++idx_tuning_;
}

int FeatureOutput::Size() { return features_.feature_size(); }

int FeatureOutput::SizeOfDataForLearning() {
  return list_data_for_learning_.data_for_learning_size();
}

int FeatureOutput::SizeOfPredictionResult() {
  return list_prediction_result_.prediction_result_size();
}

int FeatureOutput::SizeOfFrameEnv() { return list_frame_env_.frame_env_size(); }

int FeatureOutput::SizeOfDataForTuning() {
  return list_data_for_tuning_.data_for_tuning_size();
}

}  // namespace prediction
}  // namespace apollo
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: svdotxln.cxx,v $
 * $Revision: 1.17 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#include <unotools/ucbstreamhelper.hxx>
#include <unotools/localfilehelper.hxx>

#ifndef _UCBHELPER_CONTENT_HXX_
#include <ucbhelper/content.hxx>
#endif
#ifndef _UCBHELPER_CONTENTBROKER_HXX_
#include <ucbhelper/contentbroker.hxx>
#endif
#include <unotools/datetime.hxx>

#include <svx/svdotext.hxx>
#include "svditext.hxx"
#include <svx/svdmodel.hxx>
#include <svx/editdata.hxx>

#ifndef SVX_LIGHT
#ifndef _LNKBASE_HXX //autogen
#include <sfx2/lnkbase.hxx>
#endif
#endif
#include <linkmgr.hxx>
#include <tools/urlobj.hxx>

#include <svtools/urihelper.hxx>

// #90477#
#include <tools/tenccvt.hxx>

#ifndef SVX_LIGHT
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  @@@@  @@@@@  @@@@@@  @@@@@@ @@@@@@ @@  @@ @@@@@@  @@    @@ @@  @@ @@  @@
// @@  @@ @@  @@     @@    @@   @@      @@@@    @@    @@    @@ @@@ @@ @@ @@
// @@  @@ @@@@@      @@    @@   @@@@@    @@     @@    @@    @@ @@@@@@ @@@@
// @@  @@ @@  @@ @@  @@    @@   @@      @@@@    @@    @@    @@ @@ @@@ @@ @@
//  @@@@  @@@@@   @@@@     @@   @@@@@@ @@  @@   @@    @@@@@ @@ @@  @@ @@  @@
//
// ImpSdrObjTextLink zur Verbindung von SdrTextObj und LinkManager
//
// Einem solchen Link merke ich mir als SdrObjUserData am Objekt. Im Gegensatz
// zum Grafik-Link werden die ObjektDaten jedoch kopiert (fuer Paint, etc.).
// Die Information ob das Objekt ein Link ist besteht genau darin, dass dem
// Objekt ein entsprechender UserData-Record angehaengt ist oder nicht.
//
////////////////////////////////////////////////////////////////////////////////////////////////////

class ImpSdrObjTextLink: public ::sfx2::SvBaseLink
{
    SdrTextObj*                 pSdrObj;

public:
    ImpSdrObjTextLink( SdrTextObj* pObj1 )
        : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, FORMAT_FILE ),
            pSdrObj( pObj1 )
    {}
    virtual ~ImpSdrObjTextLink();

    virtual void Closed();
    virtual void DataChanged( const String& rMimeType,
                                const ::com::sun::star::uno::Any & rValue );

    BOOL Connect() { return 0 != SvBaseLink::GetRealObject(); }
};

ImpSdrObjTextLink::~ImpSdrObjTextLink()
{
}

void ImpSdrObjTextLink::Closed()
{
    if (pSdrObj )
    {
        // pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird.
        ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
        if (pData!=NULL) pData->pLink=NULL;
        pSdrObj->ReleaseTextLink();
    }
    SvBaseLink::Closed();
}

void ImpSdrObjTextLink::DataChanged( const String& /*rMimeType*/,
                                const ::com::sun::star::uno::Any & /*rValue */)
{
    FASTBOOL bForceReload=FALSE;
    SdrModel* pModel = pSdrObj ? pSdrObj->GetModel() : 0;
    SvxLinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0;
    if( pLinkManager )
    {
        ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
        if( pData )
        {
            String aFile;
            String aFilter;
            pLinkManager->GetDisplayNames( this, 0,&aFile, 0, &aFilter );

            if( !pData->aFileName.Equals( aFile ) ||
                !pData->aFilterName.Equals( aFilter ))
            {
                pData->aFileName = aFile;
                pData->aFilterName = aFilter;
                pSdrObj->SetChanged();
                bForceReload = TRUE;
            }
        }
    }
    if (pSdrObj )
        pSdrObj->ReloadLinkedText( bForceReload );
}
#endif // SVX_LIGHT

////////////////////////////////////////////////////////////////////////////////////////////////////
//
// @@    @@ @@  @@ @@  @@  @@  @@  @@@@@ @@@@@@ @@@@@   @@@@@   @@@@  @@@@@@  @@@@
// @@    @@ @@@ @@ @@ @@   @@  @@ @@     @@     @@  @@  @@  @@ @@  @@   @@   @@  @@
// @@    @@ @@@@@@ @@@@    @@  @@  @@@@  @@@@@  @@@@@   @@  @@ @@@@@@   @@   @@@@@@
// @@    @@ @@ @@@ @@@@@   @@  @@     @@ @@     @@  @@  @@  @@ @@  @@   @@   @@  @@
// @@@@@ @@ @@  @@ @@  @@   @@@@  @@@@@  @@@@@@ @@  @@  @@@@@  @@  @@   @@   @@  @@
//
////////////////////////////////////////////////////////////////////////////////////////////////////

TYPEINIT1(ImpSdrObjTextLinkUserData,SdrObjUserData);

ImpSdrObjTextLinkUserData::ImpSdrObjTextLinkUserData(SdrTextObj* pObj1):
    SdrObjUserData(SdrInventor,SDRUSERDATA_OBJTEXTLINK,0),
    pObj(pObj1),
    pLink(NULL),
    eCharSet(RTL_TEXTENCODING_DONTKNOW)
{
}

ImpSdrObjTextLinkUserData::~ImpSdrObjTextLinkUserData()
{
#ifndef SVX_LIGHT
    delete pLink;
#endif
}

SdrObjUserData* ImpSdrObjTextLinkUserData::Clone(SdrObject* pObj1) const
{
    ImpSdrObjTextLinkUserData* pData=new ImpSdrObjTextLinkUserData((SdrTextObj*)pObj1);
    pData->aFileName  =aFileName;
    pData->aFilterName=aFilterName;
    pData->aFileDate0 =aFileDate0;
    pData->eCharSet   =eCharSet;
    pData->pLink=NULL;
    return pData;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  @@@@@@ @@@@@ @@   @@ @@@@@@  @@@@  @@@@@  @@@@@@
//    @@   @@    @@@ @@@   @@   @@  @@ @@  @@     @@
//    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
//    @@   @@@@    @@@     @@   @@  @@ @@@@@      @@
//    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
//    @@   @@    @@@ @@@   @@   @@  @@ @@  @@ @@  @@
//    @@   @@@@@ @@   @@   @@    @@@@  @@@@@   @@@@
//
////////////////////////////////////////////////////////////////////////////////////////////////////

void SdrTextObj::SetTextLink(const String& rFileName, const String& rFilterName, rtl_TextEncoding eCharSet)
{
    if(eCharSet == RTL_TEXTENCODING_DONTKNOW)
        eCharSet = gsl_getSystemTextEncoding();

    ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
    if (pData!=NULL) {
        ReleaseTextLink();
    }
    pData=new ImpSdrObjTextLinkUserData(this);
    pData->aFileName=rFileName;
    pData->aFilterName=rFilterName;
    pData->eCharSet=eCharSet;
    InsertUserData(pData);
    ImpLinkAnmeldung();
}

void SdrTextObj::ReleaseTextLink()
{
    ImpLinkAbmeldung();
    USHORT nAnz=GetUserDataCount();
    for (USHORT nNum=nAnz; nNum>0;) {
        nNum--;
        SdrObjUserData* pData=GetUserData(nNum);
        if (pData->GetInventor()==SdrInventor && pData->GetId()==SDRUSERDATA_OBJTEXTLINK) {
            DeleteUserData(nNum);
        }
    }
}

FASTBOOL SdrTextObj::ReloadLinkedText( FASTBOOL bForceLoad)
{
    ImpSdrObjTextLinkUserData*  pData = GetLinkUserData();
    FASTBOOL                    bRet = TRUE;

    if( pData )
    {
        ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
        DateTime                    aFileDT;
        BOOL                        bExists = FALSE, bLoad = FALSE;

        if( pBroker )
        {
            bExists = TRUE;

            try
            {
                INetURLObject aURL( pData->aFileName );
                DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );

                ::ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
                ::com::sun::star::uno::Any aAny( aCnt.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ) ) );
                ::com::sun::star::util::DateTime aDateTime;

                aAny >>= aDateTime;
                ::utl::typeConvert( aDateTime, aFileDT );
            }
            catch( ... )
            {
                bExists = FALSE;
            }
        }

        if( bExists )
        {
            if( bForceLoad )
                bLoad = TRUE;
            else
                bLoad = ( aFileDT > pData->aFileDate0 );

            if( bLoad )
            {
                bRet = LoadText( pData->aFileName, pData->aFilterName, pData->eCharSet );
            }

            pData->aFileDate0 = aFileDT;
        }
    }

    return bRet;
}

FASTBOOL SdrTextObj::LoadText(const String& rFileName, const String& /*rFilterName*/, rtl_TextEncoding eCharSet)
{
    INetURLObject   aFileURL( rFileName );
    BOOL            bRet = FALSE;

    if( aFileURL.GetProtocol() == INET_PROT_NOT_VALID )
    {
        String aFileURLStr;

        if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFileName, aFileURLStr ) )
            aFileURL = INetURLObject( aFileURLStr );
        else
            aFileURL.SetSmartURL( rFileName );
    }

    DBG_ASSERT( aFileURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );

    SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );

    if( pIStm )
    {
        // #90477# pIStm->SetStreamCharSet( eCharSet );
        pIStm->SetStreamCharSet(GetSOLoadTextEncoding(eCharSet, (sal_uInt16)pIStm->GetVersion()));

        char cRTF[5];
        cRTF[4] = 0;
        pIStm->Read(cRTF, 5);

        BOOL bRTF = cRTF[0] == '{' && cRTF[1] == '\\' && cRTF[2] == 'r' && cRTF[3] == 't' && cRTF[4] == 'f';

        pIStm->Seek(0);

        if( !pIStm->GetError() )
        {
            SetText( *pIStm, aFileURL.GetMainURL( INetURLObject::NO_DECODE ), sal::static_int_cast< USHORT >( bRTF ? EE_FORMAT_RTF : EE_FORMAT_TEXT ) );
            bRet = TRUE;
        }

        delete pIStm;
    }

    return bRet;
}

ImpSdrObjTextLinkUserData* SdrTextObj::GetLinkUserData() const
{
    ImpSdrObjTextLinkUserData* pData=NULL;
    USHORT nAnz=GetUserDataCount();
    for (USHORT nNum=nAnz; nNum>0 && pData==NULL;) {
        nNum--;
        pData=(ImpSdrObjTextLinkUserData*)GetUserData(nNum);
        if (pData->GetInventor()!=SdrInventor || pData->GetId()!=SDRUSERDATA_OBJTEXTLINK) {
            pData=NULL;
        }
    }
    return pData;
}

void SdrTextObj::ImpLinkAnmeldung()
{
#ifndef SVX_LIGHT
    ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
    SvxLinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
    if (pLinkManager!=NULL && pData!=NULL && pData->pLink==NULL) { // Nicht 2x Anmelden
        pData->pLink=new ImpSdrObjTextLink(this);
#ifdef GCC
        pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
                                     pData->aFilterName.Len() ?
                                      &pData->aFilterName : (const String *)NULL,
                                     (const String *)NULL);
#else
        pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
                                     pData->aFilterName.Len() ? &pData->aFilterName : NULL,NULL);
#endif
        pData->pLink->Connect();
    }
#endif // SVX_LIGHT
}

void SdrTextObj::ImpLinkAbmeldung()
{
#ifndef SVX_LIGHT
    ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
    SvxLinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
    if (pLinkManager!=NULL && pData!=NULL && pData->pLink!=NULL) { // Nicht 2x Abmelden
        // Bei Remove wird *pLink implizit deleted
        pLinkManager->Remove( pData->pLink );
        pData->pLink=NULL;
    }
#endif // SVX_LIGHT
}

<commit_msg>INTEGRATION: CWS aw033 (1.17.58); FILE MERGED 2008/05/27 14:50:03 aw 1.17.58.1: #i39532# changes DEV300 m12 resync corrections<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: svdotxln.cxx,v $
 * $Revision: 1.18 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"

#include <unotools/ucbstreamhelper.hxx>
#include <unotools/localfilehelper.hxx>

#include <ucbhelper/content.hxx>
#include <ucbhelper/contentbroker.hxx>
#include <unotools/datetime.hxx>

#include <svx/svdotext.hxx>
#include "svditext.hxx"
#include <svx/svdmodel.hxx>
#include <svx/editdata.hxx>

#ifndef SVX_LIGHT
#ifndef _LNKBASE_HXX //autogen
#include <sfx2/lnkbase.hxx>
#endif
#endif
#include <linkmgr.hxx>
#include <tools/urlobj.hxx>

#include <svtools/urihelper.hxx>

// #90477#
#include <tools/tenccvt.hxx>

#ifndef SVX_LIGHT
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  @@@@  @@@@@  @@@@@@  @@@@@@ @@@@@@ @@  @@ @@@@@@  @@    @@ @@  @@ @@  @@
// @@  @@ @@  @@     @@    @@   @@      @@@@    @@    @@    @@ @@@ @@ @@ @@
// @@  @@ @@@@@      @@    @@   @@@@@    @@     @@    @@    @@ @@@@@@ @@@@
// @@  @@ @@  @@ @@  @@    @@   @@      @@@@    @@    @@    @@ @@ @@@ @@ @@
//  @@@@  @@@@@   @@@@     @@   @@@@@@ @@  @@   @@    @@@@@ @@ @@  @@ @@  @@
//
// ImpSdrObjTextLink zur Verbindung von SdrTextObj und LinkManager
//
// Einem solchen Link merke ich mir als SdrObjUserData am Objekt. Im Gegensatz
// zum Grafik-Link werden die ObjektDaten jedoch kopiert (fuer Paint, etc.).
// Die Information ob das Objekt ein Link ist besteht genau darin, dass dem
// Objekt ein entsprechender UserData-Record angehaengt ist oder nicht.
//
////////////////////////////////////////////////////////////////////////////////////////////////////

class ImpSdrObjTextLink: public ::sfx2::SvBaseLink
{
    SdrTextObj*                 pSdrObj;

public:
    ImpSdrObjTextLink( SdrTextObj* pObj1 )
        : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, FORMAT_FILE ),
            pSdrObj( pObj1 )
    {}
    virtual ~ImpSdrObjTextLink();

    virtual void Closed();
    virtual void DataChanged( const String& rMimeType,
                                const ::com::sun::star::uno::Any & rValue );

    BOOL Connect() { return 0 != SvBaseLink::GetRealObject(); }
};

ImpSdrObjTextLink::~ImpSdrObjTextLink()
{
}

void ImpSdrObjTextLink::Closed()
{
    if (pSdrObj )
    {
        // pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird.
        ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
        if (pData!=NULL) pData->pLink=NULL;
        pSdrObj->ReleaseTextLink();
    }
    SvBaseLink::Closed();
}

void ImpSdrObjTextLink::DataChanged( const String& /*rMimeType*/,
                                const ::com::sun::star::uno::Any & /*rValue */)
{
    FASTBOOL bForceReload=FALSE;
    SdrModel* pModel = pSdrObj ? pSdrObj->GetModel() : 0;
    SvxLinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0;
    if( pLinkManager )
    {
        ImpSdrObjTextLinkUserData* pData=pSdrObj->GetLinkUserData();
        if( pData )
        {
            String aFile;
            String aFilter;
            pLinkManager->GetDisplayNames( this, 0,&aFile, 0, &aFilter );

            if( !pData->aFileName.Equals( aFile ) ||
                !pData->aFilterName.Equals( aFilter ))
            {
                pData->aFileName = aFile;
                pData->aFilterName = aFilter;
                pSdrObj->SetChanged();
                bForceReload = TRUE;
            }
        }
    }
    if (pSdrObj )
        pSdrObj->ReloadLinkedText( bForceReload );
}
#endif // SVX_LIGHT

////////////////////////////////////////////////////////////////////////////////////////////////////
//
// @@    @@ @@  @@ @@  @@  @@  @@  @@@@@ @@@@@@ @@@@@   @@@@@   @@@@  @@@@@@  @@@@
// @@    @@ @@@ @@ @@ @@   @@  @@ @@     @@     @@  @@  @@  @@ @@  @@   @@   @@  @@
// @@    @@ @@@@@@ @@@@    @@  @@  @@@@  @@@@@  @@@@@   @@  @@ @@@@@@   @@   @@@@@@
// @@    @@ @@ @@@ @@@@@   @@  @@     @@ @@     @@  @@  @@  @@ @@  @@   @@   @@  @@
// @@@@@ @@ @@  @@ @@  @@   @@@@  @@@@@  @@@@@@ @@  @@  @@@@@  @@  @@   @@   @@  @@
//
////////////////////////////////////////////////////////////////////////////////////////////////////

TYPEINIT1(ImpSdrObjTextLinkUserData,SdrObjUserData);

ImpSdrObjTextLinkUserData::ImpSdrObjTextLinkUserData(SdrTextObj* pObj1):
    SdrObjUserData(SdrInventor,SDRUSERDATA_OBJTEXTLINK,0),
    pObj(pObj1),
    pLink(NULL),
    eCharSet(RTL_TEXTENCODING_DONTKNOW)
{
}

ImpSdrObjTextLinkUserData::~ImpSdrObjTextLinkUserData()
{
#ifndef SVX_LIGHT
    delete pLink;
#endif
}

SdrObjUserData* ImpSdrObjTextLinkUserData::Clone(SdrObject* pObj1) const
{
    ImpSdrObjTextLinkUserData* pData=new ImpSdrObjTextLinkUserData((SdrTextObj*)pObj1);
    pData->aFileName  =aFileName;
    pData->aFilterName=aFilterName;
    pData->aFileDate0 =aFileDate0;
    pData->eCharSet   =eCharSet;
    pData->pLink=NULL;
    return pData;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//
//  @@@@@@ @@@@@ @@   @@ @@@@@@  @@@@  @@@@@  @@@@@@
//    @@   @@    @@@ @@@   @@   @@  @@ @@  @@     @@
//    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
//    @@   @@@@    @@@     @@   @@  @@ @@@@@      @@
//    @@   @@     @@@@@    @@   @@  @@ @@  @@     @@
//    @@   @@    @@@ @@@   @@   @@  @@ @@  @@ @@  @@
//    @@   @@@@@ @@   @@   @@    @@@@  @@@@@   @@@@
//
////////////////////////////////////////////////////////////////////////////////////////////////////

void SdrTextObj::SetTextLink(const String& rFileName, const String& rFilterName, rtl_TextEncoding eCharSet)
{
    if(eCharSet == RTL_TEXTENCODING_DONTKNOW)
        eCharSet = gsl_getSystemTextEncoding();

    ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
    if (pData!=NULL) {
        ReleaseTextLink();
    }
    pData=new ImpSdrObjTextLinkUserData(this);
    pData->aFileName=rFileName;
    pData->aFilterName=rFilterName;
    pData->eCharSet=eCharSet;
    InsertUserData(pData);
    ImpLinkAnmeldung();
}

void SdrTextObj::ReleaseTextLink()
{
    ImpLinkAbmeldung();
    USHORT nAnz=GetUserDataCount();
    for (USHORT nNum=nAnz; nNum>0;) {
        nNum--;
        SdrObjUserData* pData=GetUserData(nNum);
        if (pData->GetInventor()==SdrInventor && pData->GetId()==SDRUSERDATA_OBJTEXTLINK) {
            DeleteUserData(nNum);
        }
    }
}

FASTBOOL SdrTextObj::ReloadLinkedText( FASTBOOL bForceLoad)
{
    ImpSdrObjTextLinkUserData*  pData = GetLinkUserData();
    FASTBOOL                    bRet = TRUE;

    if( pData )
    {
        ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
        DateTime                    aFileDT;
        BOOL                        bExists = FALSE, bLoad = FALSE;

        if( pBroker )
        {
            bExists = TRUE;

            try
            {
                INetURLObject aURL( pData->aFileName );
                DBG_ASSERT( aURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );

                ::ucbhelper::Content aCnt( aURL.GetMainURL( INetURLObject::NO_DECODE ), ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
                ::com::sun::star::uno::Any aAny( aCnt.getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DateModified" ) ) ) );
                ::com::sun::star::util::DateTime aDateTime;

                aAny >>= aDateTime;
                ::utl::typeConvert( aDateTime, aFileDT );
            }
            catch( ... )
            {
                bExists = FALSE;
            }
        }

        if( bExists )
        {
            if( bForceLoad )
                bLoad = TRUE;
            else
                bLoad = ( aFileDT > pData->aFileDate0 );

            if( bLoad )
            {
                bRet = LoadText( pData->aFileName, pData->aFilterName, pData->eCharSet );
            }

            pData->aFileDate0 = aFileDT;
        }
    }

    return bRet;
}

FASTBOOL SdrTextObj::LoadText(const String& rFileName, const String& /*rFilterName*/, rtl_TextEncoding eCharSet)
{
    INetURLObject   aFileURL( rFileName );
    BOOL            bRet = FALSE;

    if( aFileURL.GetProtocol() == INET_PROT_NOT_VALID )
    {
        String aFileURLStr;

        if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( rFileName, aFileURLStr ) )
            aFileURL = INetURLObject( aFileURLStr );
        else
            aFileURL.SetSmartURL( rFileName );
    }

    DBG_ASSERT( aFileURL.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" );

    SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aFileURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ );

    if( pIStm )
    {
        // #90477# pIStm->SetStreamCharSet( eCharSet );
        pIStm->SetStreamCharSet(GetSOLoadTextEncoding(eCharSet, (sal_uInt16)pIStm->GetVersion()));

        char cRTF[5];
        cRTF[4] = 0;
        pIStm->Read(cRTF, 5);

        BOOL bRTF = cRTF[0] == '{' && cRTF[1] == '\\' && cRTF[2] == 'r' && cRTF[3] == 't' && cRTF[4] == 'f';

        pIStm->Seek(0);

        if( !pIStm->GetError() )
        {
            SetText( *pIStm, aFileURL.GetMainURL( INetURLObject::NO_DECODE ), sal::static_int_cast< USHORT >( bRTF ? EE_FORMAT_RTF : EE_FORMAT_TEXT ) );
            bRet = TRUE;
        }

        delete pIStm;
    }

    return bRet;
}

ImpSdrObjTextLinkUserData* SdrTextObj::GetLinkUserData() const
{
    ImpSdrObjTextLinkUserData* pData=NULL;
    USHORT nAnz=GetUserDataCount();
    for (USHORT nNum=nAnz; nNum>0 && pData==NULL;) {
        nNum--;
        pData=(ImpSdrObjTextLinkUserData*)GetUserData(nNum);
        if (pData->GetInventor()!=SdrInventor || pData->GetId()!=SDRUSERDATA_OBJTEXTLINK) {
            pData=NULL;
        }
    }
    return pData;
}

void SdrTextObj::ImpLinkAnmeldung()
{
#ifndef SVX_LIGHT
    ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
    SvxLinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
    if (pLinkManager!=NULL && pData!=NULL && pData->pLink==NULL) { // Nicht 2x Anmelden
        pData->pLink=new ImpSdrObjTextLink(this);
#ifdef GCC
        pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
                                     pData->aFilterName.Len() ?
                                      &pData->aFilterName : (const String *)NULL,
                                     (const String *)NULL);
#else
        pLinkManager->InsertFileLink(*pData->pLink,OBJECT_CLIENT_FILE,pData->aFileName,
                                     pData->aFilterName.Len() ? &pData->aFilterName : NULL,NULL);
#endif
        pData->pLink->Connect();
    }
#endif // SVX_LIGHT
}

void SdrTextObj::ImpLinkAbmeldung()
{
#ifndef SVX_LIGHT
    ImpSdrObjTextLinkUserData* pData=GetLinkUserData();
    SvxLinkManager* pLinkManager=pModel!=NULL ? pModel->GetLinkManager() : NULL;
    if (pLinkManager!=NULL && pData!=NULL && pData->pLink!=NULL) { // Nicht 2x Abmelden
        // Bei Remove wird *pLink implizit deleted
        pLinkManager->Remove( pData->pLink );
        pData->pLink=NULL;
    }
#endif // SVX_LIGHT
}

<|endoftext|>


<commit_before>#include "geoJson.h"
#include "platform.h"

void GeoJson::extractPoint(const Json::Value& _in, Point& _out, const MapTile& _tile) {

    glm::dvec2 tmp = _tile.getProjection()->LonLatToMeters(glm::dvec2(_in[0].asDouble(), _in[1].asDouble()));
    _out.x = (tmp.x - _tile.getOrigin().x) * _tile.getInverseScale();
    _out.y = (tmp.y - _tile.getOrigin().y) * _tile.getInverseScale();

}

void GeoJson::extractLine(const Json::Value& _in, Line& _out, const MapTile& _tile) {

    for (auto& point : _in) {
        _out.emplace_back();
        extractPoint(point, _out.back(), _tile);
    }

}

void GeoJson::extractPoly(const Json::Value& _in, Polygon& _out, const MapTile& _tile) {

    for (auto& line : _in) {
        _out.emplace_back();
        extractLine(line, _out.back(), _tile);
    }

}

void GeoJson::extractFeature(const Json::Value& _in, Feature& _out, const MapTile& _tile) {

    // Copy properties into tile data

    const Json::Value& properties = _in["properties"];

    for (auto& member : properties.getMemberNames()) {

        const Json::Value& prop = properties[member];

        // height and minheight need to be handled separately so that their dimensions are normalized
        if (member.compare("height") == 0) {
            _out.props.numericProps[member] = prop.asFloat() * _tile.getInverseScale();
            continue;
        }

        if (member.compare("min_height") == 0) {
            _out.props.numericProps[member] = prop.asFloat() * _tile.getInverseScale();
            continue;
        }

        if (prop.isNumeric()) {
            _out.props.numericProps[member] = prop.asFloat();
        } else if (prop.isString()) {
            _out.props.stringProps[member] = prop.asString();
        }

    }

    // Copy geometry into tile data

    const Json::Value& geometry = _in["geometry"];
    const Json::Value& coords = geometry["coordinates"];
    const std::string& geometryType = geometry["type"].asString();

    if (geometryType.compare("Point") == 0) {

        _out.geometryType = GeometryType::POINTS;
        _out.points.emplace_back();
        extractPoint(coords, _out.points.back(), _tile);

    } else if (geometryType.compare("MultiPoint") == 0) {

        _out.geometryType= GeometryType::POINTS;
        for (const auto& pointCoords : coords) {
            _out.points.emplace_back();
            extractPoint(pointCoords, _out.points.back(), _tile);
        }

    } else if (geometryType.compare("Line") == 0) {
        logMsg("\t\t***Testing\n");
        _out.geometryType = GeometryType::LINES;
        _out.lines.emplace_back();
        extractLine(coords, _out.lines.back(), _tile);

    } else if (geometryType.compare("MultiLine") == 0) {
        logMsg("\t\t***Testing\n");
        _out.geometryType = GeometryType::LINES;
        for (const auto& lineCoords : coords) {
            _out.lines.emplace_back();
            extractLine(lineCoords, _out.lines.back(), _tile);
        }

    } else if (geometryType.compare("Polygon") == 0) {

        _out.geometryType = GeometryType::POLYGONS;
        _out.polygons.emplace_back();
        extractPoly(coords, _out.polygons.back(), _tile);

    } else if (geometryType.compare("MultiPolygon") == 0) {

        _out.geometryType = GeometryType::POLYGONS;
        for (const auto& polyCoords : coords) {
            _out.polygons.emplace_back();
            extractPoly(polyCoords, _out.polygons.back(), _tile);
        }

    }

}

void GeoJson::extractLayer(const Json::Value& _in, Layer& _out, const MapTile& _tile) {

    const Json::Value& features = _in["features"];

    for (const auto& featureJson : features) {
        _out.features.emplace_back();
        extractFeature(featureJson, _out.features.back(), _tile);
    }

}
<commit_msg>Fixed LineString and MultiLineString parsing<commit_after>#include "geoJson.h"
#include "platform.h"

void GeoJson::extractPoint(const Json::Value& _in, Point& _out, const MapTile& _tile) {

    glm::dvec2 tmp = _tile.getProjection()->LonLatToMeters(glm::dvec2(_in[0].asDouble(), _in[1].asDouble()));
    _out.x = (tmp.x - _tile.getOrigin().x) * _tile.getInverseScale();
    _out.y = (tmp.y - _tile.getOrigin().y) * _tile.getInverseScale();

}

void GeoJson::extractLine(const Json::Value& _in, Line& _out, const MapTile& _tile) {

    for (auto& point : _in) {
        _out.emplace_back();
        extractPoint(point, _out.back(), _tile);
    }

}

void GeoJson::extractPoly(const Json::Value& _in, Polygon& _out, const MapTile& _tile) {

    for (auto& line : _in) {
        _out.emplace_back();
        extractLine(line, _out.back(), _tile);
    }

}

void GeoJson::extractFeature(const Json::Value& _in, Feature& _out, const MapTile& _tile) {

    // Copy properties into tile data

    const Json::Value& properties = _in["properties"];

    for (auto& member : properties.getMemberNames()) {

        const Json::Value& prop = properties[member];

        // height and minheight need to be handled separately so that their dimensions are normalized
        if (member.compare("height") == 0) {
            _out.props.numericProps[member] = prop.asFloat() * _tile.getInverseScale();
            continue;
        }

        if (member.compare("min_height") == 0) {
            _out.props.numericProps[member] = prop.asFloat() * _tile.getInverseScale();
            continue;
        }

        if (prop.isNumeric()) {
            _out.props.numericProps[member] = prop.asFloat();
        } else if (prop.isString()) {
            _out.props.stringProps[member] = prop.asString();
        }

    }

    // Copy geometry into tile data

    const Json::Value& geometry = _in["geometry"];
    const Json::Value& coords = geometry["coordinates"];
    const std::string& geometryType = geometry["type"].asString();

    if (geometryType.compare("Point") == 0) {

        _out.geometryType = GeometryType::POINTS;
        _out.points.emplace_back();
        extractPoint(coords, _out.points.back(), _tile);

    } else if (geometryType.compare("MultiPoint") == 0) {

        _out.geometryType= GeometryType::POINTS;
        for (const auto& pointCoords : coords) {
            _out.points.emplace_back();
            extractPoint(pointCoords, _out.points.back(), _tile);
        }

    } else if (geometryType.compare("LineString") == 0) {
        _out.geometryType = GeometryType::LINES;
        _out.lines.emplace_back();
        extractLine(coords, _out.lines.back(), _tile);

    } else if (geometryType.compare("MultiLineString") == 0) {
        _out.geometryType = GeometryType::LINES;
        for (const auto& lineCoords : coords) {
            _out.lines.emplace_back();
            extractLine(lineCoords, _out.lines.back(), _tile);
        }

    } else if (geometryType.compare("Polygon") == 0) {

        _out.geometryType = GeometryType::POLYGONS;
        _out.polygons.emplace_back();
        extractPoly(coords, _out.polygons.back(), _tile);

    } else if (geometryType.compare("MultiPolygon") == 0) {

        _out.geometryType = GeometryType::POLYGONS;
        for (const auto& polyCoords : coords) {
            _out.polygons.emplace_back();
            extractPoly(polyCoords, _out.polygons.back(), _tile);
        }

    }

}

void GeoJson::extractLayer(const Json::Value& _in, Layer& _out, const MapTile& _tile) {

    const Json::Value& features = _in["features"];

    for (const auto& featureJson : features) {
        _out.features.emplace_back();
        extractFeature(featureJson, _out.features.back(), _tile);
    }

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: drawdev.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 03:45:35 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _DRAWDEV_HXX
#define _DRAWDEV_HXX

#include "swrect.hxx"

#ifndef _OUTDEV_HXX //autogen
#include <vcl/outdev.hxx>
#endif

/*************************************************************************
 *                          class SwDrawDev
 *
 * Alle Draw-Methoden werden um den Offset *pPos verschoben.
 *************************************************************************/

class SwDrawDev
{
    OutputDevice  *pOut;
    const Point *pPos;

public:
    inline SwDrawDev( OutputDevice *pOut, const Point *pPos )
        :pOut(pOut), pPos(pPos) { }

    inline OutputDevice *GetOut() { return pOut; }

    // Ausgabemethoden
    inline void DrawText( const Point& rStart, const String& rTxt,
                          const USHORT nIdx = 0,
                          const USHORT nLen = STRING_LEN );
    inline void DrawStretchText( const Point& rStart, USHORT nWidth,
                          const String& rTxt,
                          const USHORT nIdx = 0,
                          const USHORT nLen = STRING_LEN );
    inline void DrawTextArray( const Point& rStart,
                          const String& rTxt,
                          long *pKernArray = 0,
                          const USHORT nIdx = 0,
                          const USHORT nLen = STRING_LEN);
    inline void DrawLine( const Point& rStart, const Point& rEnd );
    inline void DrawRect( const SwRect& rRect,
                          const USHORT nHorzRount = 0,
                          const USHORT nVertRound = 0 );

    inline const Point *GetOrigin() const {return pPos; }
};

/*************************************************************************
 *                      SwDrawDev::DrawText
 *************************************************************************/

inline void SwDrawDev::DrawText( const Point& rStart, const String& rTxt,
                                 const USHORT nIdx, const USHORT nLen )
{
    if( !pPos )
        pOut->DrawText( rStart, rTxt, nIdx, nLen );
    else
        pOut->DrawText( rStart - *pPos, rTxt, nIdx, nLen );
}

/*************************************************************************
 *                      SwDrawDev::DrawStretchText
 *************************************************************************/

inline void SwDrawDev::DrawStretchText( const Point& rStart, USHORT nWidth,
       const String& rTxt, const USHORT nIdx, const USHORT nLen )
{
    if( !pPos )
        pOut->DrawStretchText( rStart, nWidth, rTxt, nIdx, nLen );
    else
        pOut->DrawStretchText( rStart - *pPos, nWidth, rTxt, nIdx, nLen );
}

/*************************************************************************
 *                      SwDrawDev::DrawTextArray
 *************************************************************************/

inline void SwDrawDev::DrawTextArray( const Point& rStart, const String& rTxt,
            long *pKernArray, const USHORT nIdx, const USHORT nLen )
{
    if( !pPos )
        pOut->DrawTextArray( rStart, rTxt, pKernArray, nIdx, nLen );
    else
        pOut->DrawTextArray( rStart - *pPos, rTxt, pKernArray, nIdx, nLen );
}

/*************************************************************************
 *                      SwDrawDev::DrawLine
 *************************************************************************/

inline void SwDrawDev::DrawLine( const Point& rStart, const Point& rEnd )
{
    if( !pPos )
        pOut->DrawLine( rStart, rEnd );
    else
        pOut->DrawLine( rStart - *pPos, rEnd - *pPos );
}

/*************************************************************************
 *                      SwDrawDev::DrawRect
 *************************************************************************/

inline void SwDrawDev::DrawRect( const SwRect& rRect,
                      const USHORT nHorzRound, const USHORT nVertRound )
{
    SwRect aRect( rRect );
    if( pPos )
        aRect.Pos() -= *pPos;
    pOut->DrawRect( aRect.SVRect(), nHorzRound, nVertRound );
}

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

#ifndef _DRAWDEV_HXX
#define _DRAWDEV_HXX

#include "swrect.hxx"

#ifndef _OUTDEV_HXX //autogen
#include <vcl/outdev.hxx>
#endif

/*************************************************************************
 *                          class SwDrawDev
 *
 * Alle Draw-Methoden werden um den Offset *pPos verschoben.
 *************************************************************************/

class SwDrawDev
{
    OutputDevice  *pOut;
    const Point *pPos;

public:
    inline SwDrawDev( OutputDevice *pOutDev, const Point *pPosition )
        :pOut(pOutDev), pPos(pPosition) { }

    inline OutputDevice *GetOut() { return pOut; }

    // Ausgabemethoden
    inline void DrawText( const Point& rStart, const String& rTxt,
                          const USHORT nIdx = 0,
                          const USHORT nLen = STRING_LEN );
    inline void DrawStretchText( const Point& rStart, USHORT nWidth,
                          const String& rTxt,
                          const USHORT nIdx = 0,
                          const USHORT nLen = STRING_LEN );
    inline void DrawTextArray( const Point& rStart,
                          const String& rTxt,
                          long *pKernArray = 0,
                          const USHORT nIdx = 0,
                          const USHORT nLen = STRING_LEN);
    inline void DrawLine( const Point& rStart, const Point& rEnd );
    inline void DrawRect( const SwRect& rRect,
                          const USHORT nHorzRount = 0,
                          const USHORT nVertRound = 0 );

    inline const Point *GetOrigin() const {return pPos; }
};

/*************************************************************************
 *                      SwDrawDev::DrawText
 *************************************************************************/

inline void SwDrawDev::DrawText( const Point& rStart, const String& rTxt,
                                 const USHORT nIdx, const USHORT nLen )
{
    if( !pPos )
        pOut->DrawText( rStart, rTxt, nIdx, nLen );
    else
        pOut->DrawText( rStart - *pPos, rTxt, nIdx, nLen );
}

/*************************************************************************
 *                      SwDrawDev::DrawStretchText
 *************************************************************************/

inline void SwDrawDev::DrawStretchText( const Point& rStart, USHORT nWidth,
       const String& rTxt, const USHORT nIdx, const USHORT nLen )
{
    if( !pPos )
        pOut->DrawStretchText( rStart, nWidth, rTxt, nIdx, nLen );
    else
        pOut->DrawStretchText( rStart - *pPos, nWidth, rTxt, nIdx, nLen );
}

/*************************************************************************
 *                      SwDrawDev::DrawTextArray
 *************************************************************************/

inline void SwDrawDev::DrawTextArray( const Point& rStart, const String& rTxt,
            long *pKernArray, const USHORT nIdx, const USHORT nLen )
{
    if( !pPos )
        pOut->DrawTextArray( rStart, rTxt, pKernArray, nIdx, nLen );
    else
        pOut->DrawTextArray( rStart - *pPos, rTxt, pKernArray, nIdx, nLen );
}

/*************************************************************************
 *                      SwDrawDev::DrawLine
 *************************************************************************/

inline void SwDrawDev::DrawLine( const Point& rStart, const Point& rEnd )
{
    if( !pPos )
        pOut->DrawLine( rStart, rEnd );
    else
        pOut->DrawLine( rStart - *pPos, rEnd - *pPos );
}

/*************************************************************************
 *                      SwDrawDev::DrawRect
 *************************************************************************/

inline void SwDrawDev::DrawRect( const SwRect& rRect,
                      const USHORT nHorzRound, const USHORT nVertRound )
{
    SwRect aRect( rRect );
    if( pPos )
        aRect.Pos() -= *pPos;
    pOut->DrawRect( aRect.SVRect(), nHorzRound, nVertRound );
}

#endif
<|endoftext|>


<commit_before>/*
	kopetemessagemanager.cpp - Manages all chats

	Copyright   : (c) 2002 by Martijn Klingens <klingens@kde.org>
                      (c) 2002 by Duncan Mac-Vicar Prett <duncan@kde.org>
		      (c) 2002 by Daniel Stone <dstone@kde.org>

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

#include "kopetemessagemanager.h"
#include "kopetechatwindow.h"
#include "kopeteevent.h"
#include "kopete.h"

#include "messagelog.h"

#include <kdebug.h>
#include <klocale.h>

#include <qstylesheet.h>

KopeteMessageManager::KopeteMessageManager( const KopeteContact *user, KopeteContactList others,
		KopeteProtocol *protocol, QString logFile, int widget, int capabilities,
		QObject *parent, const char *name) : QObject( parent, name)
{

	mContactList = others;
	mUser = user;
	mChatWindow = 0L;
	mUnreadMessageEvent = 0L;
	mProtocol = protocol;
	mWidget = widget;
	mCapabilities = capabilities;

	readModeChanged();
	connect(kopeteapp->appearance(), SIGNAL(queueChanged()), this, SLOT(readModeChanged()));

	if (!logFile.isEmpty())
	{
		QString logFileName = "kopete/" + logFile;
		mLogger = new KopeteMessageLog(logFileName, this);
	}
	else
	{
		mLogger = 0L;
	}
}

KopeteMessageManager::~KopeteMessageManager()
{
	emit dying(this);
}

void KopeteMessageManager::newChatWindow() {
	mChatWindow = new KopeteChatWindow(mCapabilities);
	if (mContactList.first() != 0L)
		mChatWindow->setCaption(mContactList.first()->name()); //TODO: add multi-user support
	for (KopeteContact *it = mContactList.first(); it; it = mContactList.next()) {
		for (QStringList::Iterator it2 = (resources[it]).begin(); it2 != (resources[it]).end(); it2++) {
			mChatWindow->addResource(it, *it2);
		}
	}
	/* When the window is shown, we have to delete this contact event */
	kdDebug() << "[KopeteMessageManager] Connecting message box shown() to event killer" << endl;
	connect (mChatWindow, SIGNAL(shown()), this, SLOT(cancelUnreadMessageEvent()));
	connect (mChatWindow, SIGNAL(sendMessage(const QString &)), this, SLOT(messageSentFromWindow(const QString &)));
	connect (mChatWindow, SIGNAL(closeClicked()), this, SLOT(chatWindowClosing()));
}

void KopeteMessageManager::setReadMode(int mode)
{
	if ((mode == Queued) || (mode == Popup))
	{
		mReadMode = mode;
	}
	else
	{
		kdDebug() << "[KopeteMessageManager] ERROR: unknown reading method, setting to default" << endl;
		mReadMode = Queued;
	}
}

void KopeteMessageManager::readMessages()
{
	if (mWidget == WIDGET_OLDSCHOOL) {
		if (mChatWindow == 0L) {
			kdDebug() << "[KopeteMessageManager] mChatWindow just doesn't exist" << endl;
			newChatWindow();
		}
		if (mChatWindow->isMinimized())
			kdDebug() << "[KopeteMessageManager] mChatWindow is minimized" << endl;
		if (mChatWindow->isHidden())
			kdDebug() << "[KopeteMessageManager] mChatWindow is hidden" << endl;
		mChatWindow->raise();	// make it top window
		for (KopeteMessageList::Iterator it = mMessageQueue.begin(); it != mMessageQueue.end(); it++)
		{
			kdDebug() << "[KopeteMessageManager] Inserting message from " << (*it).from()->name() << endl;
			mChatWindow->messageReceived((*it));
		}
		mChatWindow->show();	// show message window again
	}
	else {
		kdDebug() << "[KopeteMessageManager] Widget is non-oldschool: " << mWidget << endl;
	}

	mMessageQueue.clear();
}

void KopeteMessageManager::slotReadMessages()
{
	readMessages();
}

void KopeteMessageManager::messageSentFromWindow(const QString &message)
{
	QString body = message;
	KopeteMessage tmpmessage(mUser, mContactList, QStyleSheet::escape(body), KopeteMessage::Outbound);
	emit messageSent(tmpmessage);
	readMessages();
}

void KopeteMessageManager::chatWindowClosing()
{
	kdDebug() << "[KopeteMessageManager] Chat Window closed, now 0L" << endl;
	mChatWindow = 0L;
}

void KopeteMessageManager::cancelUnreadMessageEvent()
{
	if (mUnreadMessageEvent == 0L)
	{
		kdDebug() << "[KopeteMessageManager] No event to delete" << endl;
	}
	else
	{
		kdDebug() << "[KopeteMessageManager] cancelUnreadMessageEvent Deleting Event" << endl;
		delete mUnreadMessageEvent;
		mUnreadMessageEvent = 0L;
		kdDebug() << "[KopeteMessageManager] cancelUnreadMessageEvent Event Deleted" << endl;
	}
}

void KopeteMessageManager::slotEventDeleted(KopeteEvent *e)
{
	kdDebug() << "[KopeteMessageManager] Event done(), now 0L" << endl;
	if ( e == mUnreadMessageEvent)
		mUnreadMessageEvent = 0L;
}

void KopeteMessageManager::appendMessage( const KopeteMessage &msg )
{
	bool isvisible = false;

	mMessageQueue.append(msg);

	if( mLogger )
	{
		mLogger->append( msg );
	}

	if (mReadMode == Popup)
	{
    	readMessages();
	}
	else if ( mReadMode == Queued )
	{
    	/* First stage, see what to do */
		if ( mChatWindow == 0L )
		{
			isvisible = false;
		}
		else if (  (mChatWindow != 0L) && ( mChatWindow->isHidden() || mChatWindow->isMinimized()) )
        {
			isvisible = false;
		}
		else
		{
			isvisible = true;
		}

		/* Second stage, do it */
		if ( isvisible )
		{
			readMessages();
		}
		else
		{
			/* Create an event if a prevoius one not exist */
			if ( (mUnreadMessageEvent == 0L) && (msg.direction() == KopeteMessage::Inbound) )
			{
		 		mUnreadMessageEvent = new KopeteEvent( i18n("Message from %1").arg(msg.from()->name()), "kopete/pics/newmsg.png", this, SLOT(slotReadMessages()));
				connect(mUnreadMessageEvent, SIGNAL(done(KopeteEvent *)), this, SLOT(slotEventDeleted(KopeteEvent *)));
				kopeteapp->notifyEvent( mUnreadMessageEvent );
			}
		}
	}

}
void KopeteMessageManager::addContact( const KopeteContact *c )
{
	KopeteContact *tmp;

	for ( tmp = mContactList.first(); tmp; tmp = mContactList.next() )
	{
		if ( tmp == c )
		{
			kdDebug() << "[KopeteMessageManager] Contact already exists" <<endl;
			return;
		}
	}

	kdDebug() << "[KopeteMessageManager] Contact Joined session" <<endl;
	mContactList.append(c);
}

void KopeteMessageManager::removeContact( const KopeteContact *c )
{
	mContactList.take( mContactList.find(c) );
}

void KopeteMessageManager::readModeChanged()
{
	if ( kopeteapp->appearance()->useQueue() )
	{
		mReadMode = Queued;
	}
	else
	{
		mReadMode = Popup;
	}
}

void KopeteMessageManager::addResource(const KopeteContact *c, QString resource)
{
	if (mWidget == WIDGET_OLDSCHOOL) {
		kdDebug() << "[KopeteMessageManager] Adding new resource to KCW: " << resource << endl;
		if (mChatWindow != 0L) {
			kdDebug() << "[KopeteMessageManager] mChatWindow != 0L!" << endl;
			mChatWindow->addResource(c, resource);
		}
		(resources[c]).append(resource);
	}
	else {
		kdDebug() << "[KopeteMessageManager] Adding new resource to other widget: " << resource << endl;
		(resources[c]).append(resource);
	}
}

void KopeteMessageManager::removeResource(const KopeteContact *c, QString resource) {
	if (mWidget == WIDGET_OLDSCHOOL) {
		kdDebug() << "[KopeteMessageManager] Removing resource from KCW: " << resource << endl;
		if (mChatWindow != 0L) {
			mChatWindow->removeResource(c, resource);
		}
		(resources[c]).remove(resource);
	}
	else {
		kdDebug() << "[KopeteMessageManager] Removing resource from other widget: " << resource << endl;
	}
}

bool KopeteMessageManager::serverChecked()
{
	return	mChatWindow->cbServer->isChecked();
}

void KopeteMessageManager::checkServer(bool check)
{
	mChatWindow->cbServer->setChecked(check);
}

// vim: set noet ts=4 sts=4 sw=4:
#include "kopetemessagemanager.moc"
<commit_msg>Fix for a wrong readMessages that caused chat window to popup when you send a message<commit_after>/*
	kopetemessagemanager.cpp - Manages all chats

	Copyright   : (c) 2002 by Martijn Klingens <klingens@kde.org>
                      (c) 2002 by Duncan Mac-Vicar Prett <duncan@kde.org>
		      (c) 2002 by Daniel Stone <dstone@kde.org>

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

#include "kopetemessagemanager.h"
#include "kopetechatwindow.h"
#include "kopeteevent.h"
#include "kopete.h"

#include "messagelog.h"

#include <kdebug.h>
#include <klocale.h>

#include <qstylesheet.h>

KopeteMessageManager::KopeteMessageManager( const KopeteContact *user, KopeteContactList others,
		KopeteProtocol *protocol, QString logFile, int widget, int capabilities,
		QObject *parent, const char *name) : QObject( parent, name)
{

	mContactList = others;
	mUser = user;
	mChatWindow = 0L;
	mUnreadMessageEvent = 0L;
	mProtocol = protocol;
	mWidget = widget;
	mCapabilities = capabilities;

	readModeChanged();
	connect(kopeteapp->appearance(), SIGNAL(queueChanged()), this, SLOT(readModeChanged()));

	if (!logFile.isEmpty())
	{
		QString logFileName = "kopete/" + logFile;
		mLogger = new KopeteMessageLog(logFileName, this);
	}
	else
	{
		mLogger = 0L;
	}
}

KopeteMessageManager::~KopeteMessageManager()
{
	emit dying(this);
}

void KopeteMessageManager::newChatWindow() {
	mChatWindow = new KopeteChatWindow(mCapabilities);
	if (mContactList.first() != 0L)
		mChatWindow->setCaption(mContactList.first()->name()); //TODO: add multi-user support
	for (KopeteContact *it = mContactList.first(); it; it = mContactList.next()) {
		for (QStringList::Iterator it2 = (resources[it]).begin(); it2 != (resources[it]).end(); it2++) {
			mChatWindow->addResource(it, *it2);
		}
	}
	/* When the window is shown, we have to delete this contact event */
	kdDebug() << "[KopeteMessageManager] Connecting message box shown() to event killer" << endl;
	connect (mChatWindow, SIGNAL(shown()), this, SLOT(cancelUnreadMessageEvent()));
	connect (mChatWindow, SIGNAL(sendMessage(const QString &)), this, SLOT(messageSentFromWindow(const QString &)));
	connect (mChatWindow, SIGNAL(closeClicked()), this, SLOT(chatWindowClosing()));
}

void KopeteMessageManager::setReadMode(int mode)
{
	if ((mode == Queued) || (mode == Popup))
	{
		mReadMode = mode;
	}
	else
	{
		kdDebug() << "[KopeteMessageManager] ERROR: unknown reading method, setting to default" << endl;
		mReadMode = Queued;
	}
}

void KopeteMessageManager::readMessages()
{
	if (mWidget == WIDGET_OLDSCHOOL) {
		if (mChatWindow == 0L) {
			kdDebug() << "[KopeteMessageManager] mChatWindow just doesn't exist" << endl;
			newChatWindow();
		}
		if (mChatWindow->isMinimized())
			kdDebug() << "[KopeteMessageManager] mChatWindow is minimized" << endl;
		if (mChatWindow->isHidden())
			kdDebug() << "[KopeteMessageManager] mChatWindow is hidden" << endl;
		mChatWindow->raise();	// make it top window
		for (KopeteMessageList::Iterator it = mMessageQueue.begin(); it != mMessageQueue.end(); it++)
		{
			kdDebug() << "[KopeteMessageManager] Inserting message from " << (*it).from()->name() << endl;
			mChatWindow->messageReceived((*it));
		}
		mChatWindow->show();	// show message window again
	}
	else {
		kdDebug() << "[KopeteMessageManager] Widget is non-oldschool: " << mWidget << endl;
	}

	mMessageQueue.clear();
}

void KopeteMessageManager::slotReadMessages()
{
	readMessages();
}

void KopeteMessageManager::messageSentFromWindow(const QString &message)
{
	QString body = message;
	KopeteMessage tmpmessage(mUser, mContactList, QStyleSheet::escape(body), KopeteMessage::Outbound);
	emit messageSent(tmpmessage);
}

void KopeteMessageManager::chatWindowClosing()
{
	kdDebug() << "[KopeteMessageManager] Chat Window closed, now 0L" << endl;
	mChatWindow = 0L;
}

void KopeteMessageManager::cancelUnreadMessageEvent()
{
	if (mUnreadMessageEvent == 0L)
	{
		kdDebug() << "[KopeteMessageManager] No event to delete" << endl;
	}
	else
	{
		kdDebug() << "[KopeteMessageManager] cancelUnreadMessageEvent Deleting Event" << endl;
		delete mUnreadMessageEvent;
		mUnreadMessageEvent = 0L;
		kdDebug() << "[KopeteMessageManager] cancelUnreadMessageEvent Event Deleted" << endl;
	}
}

void KopeteMessageManager::slotEventDeleted(KopeteEvent *e)
{
	kdDebug() << "[KopeteMessageManager] Event done(), now 0L" << endl;
	if ( e == mUnreadMessageEvent)
		mUnreadMessageEvent = 0L;
}

void KopeteMessageManager::appendMessage( const KopeteMessage &msg )
{
	bool isvisible = false;

	mMessageQueue.append(msg);

	if( mLogger )
	{
		mLogger->append( msg );
	}

	if (mReadMode == Popup)
	{
    	readMessages();
	}
	else if ( mReadMode == Queued )
	{
    	/* First stage, see what to do */
		if ( mChatWindow == 0L )
		{
			isvisible = false;
		}
		else if (  (mChatWindow != 0L) && ( mChatWindow->isHidden() || mChatWindow->isMinimized()) )
        {
			isvisible = false;
		}
		else
		{
			isvisible = true;
		}

		/* Second stage, do it */
		if ( isvisible )
		{
			readMessages();
		}
		else
		{
			/* Create an event if a prevoius one not exist */
			if ( (mUnreadMessageEvent == 0L) && (msg.direction() == KopeteMessage::Inbound) )
			{
		 		mUnreadMessageEvent = new KopeteEvent( i18n("Message from %1").arg(msg.from()->name()), "kopete/pics/newmsg.png", this, SLOT(slotReadMessages()));
				connect(mUnreadMessageEvent, SIGNAL(done(KopeteEvent *)), this, SLOT(slotEventDeleted(KopeteEvent *)));
				kopeteapp->notifyEvent( mUnreadMessageEvent );
			}
		}
	}

}
void KopeteMessageManager::addContact( const KopeteContact *c )
{
	KopeteContact *tmp;

	for ( tmp = mContactList.first(); tmp; tmp = mContactList.next() )
	{
		if ( tmp == c )
		{
			kdDebug() << "[KopeteMessageManager] Contact already exists" <<endl;
			return;
		}
	}

	kdDebug() << "[KopeteMessageManager] Contact Joined session" <<endl;
	mContactList.append(c);
}

void KopeteMessageManager::removeContact( const KopeteContact *c )
{
	mContactList.take( mContactList.find(c) );
}

void KopeteMessageManager::readModeChanged()
{
	if ( kopeteapp->appearance()->useQueue() )
	{
		mReadMode = Queued;
	}
	else
	{
		mReadMode = Popup;
	}
}

void KopeteMessageManager::addResource(const KopeteContact *c, QString resource)
{
	if (mWidget == WIDGET_OLDSCHOOL) {
		kdDebug() << "[KopeteMessageManager] Adding new resource to KCW: " << resource << endl;
		if (mChatWindow != 0L) {
			kdDebug() << "[KopeteMessageManager] mChatWindow != 0L!" << endl;
			mChatWindow->addResource(c, resource);
		}
		(resources[c]).append(resource);
	}
	else {
		kdDebug() << "[KopeteMessageManager] Adding new resource to other widget: " << resource << endl;
		(resources[c]).append(resource);
	}
}

void KopeteMessageManager::removeResource(const KopeteContact *c, QString resource) {
	if (mWidget == WIDGET_OLDSCHOOL) {
		kdDebug() << "[KopeteMessageManager] Removing resource from KCW: " << resource << endl;
		if (mChatWindow != 0L) {
			mChatWindow->removeResource(c, resource);
		}
		(resources[c]).remove(resource);
	}
	else {
		kdDebug() << "[KopeteMessageManager] Removing resource from other widget: " << resource << endl;
	}
}

bool KopeteMessageManager::serverChecked()
{
	return	mChatWindow->cbServer->isChecked();
}

void KopeteMessageManager::checkServer(bool check)
{
	mChatWindow->cbServer->setChecked(check);
}

// vim: set noet ts=4 sts=4 sw=4:
#include "kopetemessagemanager.moc"
<|endoftext|>


<commit_before>#include "testutil.h"
#include <sys/stat.h>
#include <npk.h>
#include <npk_dev.h>

int libnpk_streamable( int argc, char * argv [] )
{
    int teakey[4] = {1,2,3,4};

    NPK_PACKAGE pack;
    NPK_ENTITY entity;

    // create a pack
    CHECK( NPK_SUCCESS == npk_package_alloc( &pack, teakey ) );
    CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "sample.txt", &entity ) );
    CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "tea.txt", &entity ) );
    CHECK( NPK_SUCCESS == npk_entity_set_flag( entity, NPK_ENTITY_ENCRYPT_TEA ) );
    CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "xxtea.txt", &entity ) );
    CHECK( NPK_SUCCESS == npk_entity_set_flag( entity, NPK_ENTITY_ENCRYPT_XXTEA ) );
    CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "zip.txt", &entity ) );
    CHECK( NPK_SUCCESS == npk_entity_set_flag( entity, NPK_ENTITY_COMPRESS_ZLIB ) );
    CHECK( NPK_SUCCESS == npk_package_save( pack, "foo.npk", true ) );

    npk_package_close( pack );

    // simulate download
    int rh = open( "foo.npk", O_RDONLY | O_BINARY );
    size_t filesize = npk_seek( rh, 0, SEEK_END );
    npk_seek( rh, 0, SEEK_SET );

    int wh = open( "foo_2.npk", O_CREAT | O_RDWR | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE );

    // validation
    std::string entityNames[4] = { "sample.txt", "tea.txt", "xxtea.txt", "zip.txt" };
    pack = 0;
    int i = 0;
    size_t offset = 0;
    char buf[255];

    while( offset < filesize )
    {
        size_t r = rand()%16;
        if( r + offset > filesize )
            r = filesize - offset;

        read( rh, &buf, sizeof(char)*r );
        write( wh, buf, sizeof(char)*r );
        printf( "offset %ld, reading %ld byte(s).\n", offset, r );
        offset += r;

        if( pack == 0 )
        {
            pack = npk_package_open( "foo_2.npk", teakey );
            if( pack != 0 )
                printf( "   package loaded.\n" );
        }
        else
        {
            NPK_ENTITY entity = npk_package_get_entity( pack, entityNames[i].c_str() );
            CHECK( entity != NULL );

            NPK_SIZE size = npk_entity_get_size( entity );
            if( npk_entity_is_ready( entity ) )
            {
                printf( "   entity %s ready.\n", entityNames[i].c_str() );
                void* buf = malloc( size );

                CHECK( npk_entity_read( entity, buf ) );
                CHECK_EQUAL_STR_WITH_FILE( (const char*)buf, "sample.txt" );

                free( buf );
                ++i;
            }
        }
    }

    npk_package_close( pack );
    close( wh );
    close( rh );

    return 0;
}
<commit_msg>Use off_t beside size_t on testing<commit_after>#include "testutil.h"
#include <sys/stat.h>
#include <npk.h>
#include <npk_dev.h>

int libnpk_streamable( int argc, char * argv [] )
{
    int teakey[4] = {1,2,3,4};

    NPK_PACKAGE pack;
    NPK_ENTITY entity;

    // create a pack
    CHECK( NPK_SUCCESS == npk_package_alloc( &pack, teakey ) );
    CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "sample.txt", &entity ) );
    CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "tea.txt", &entity ) );
    CHECK( NPK_SUCCESS == npk_entity_set_flag( entity, NPK_ENTITY_ENCRYPT_TEA ) );
    CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "xxtea.txt", &entity ) );
    CHECK( NPK_SUCCESS == npk_entity_set_flag( entity, NPK_ENTITY_ENCRYPT_XXTEA ) );
    CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "zip.txt", &entity ) );
    CHECK( NPK_SUCCESS == npk_entity_set_flag( entity, NPK_ENTITY_COMPRESS_ZLIB ) );
    CHECK( NPK_SUCCESS == npk_package_save( pack, "foo.npk", true ) );

    npk_package_close( pack );

    // simulate download
    int rh = open( "foo.npk", O_RDONLY | O_BINARY );
    size_t filesize = npk_seek( rh, 0, SEEK_END );
    npk_seek( rh, 0, SEEK_SET );

    int wh = open( "foo_2.npk", O_CREAT | O_RDWR | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE );

    // validation
    std::string entityNames[4] = { "sample.txt", "tea.txt", "xxtea.txt", "zip.txt" };
    pack = 0;
    int i = 0;
    off_t offset = 0;
    char buf[255];

    while( offset < filesize )
    {
        off_t r = rand()%16;
        if( r + offset > filesize )
            r = filesize - offset;

        read( rh, &buf, sizeof(char)*r );
        write( wh, buf, sizeof(char)*r );
        printf( "offset %ld, reading %ld byte(s).\n", offset, r );
        offset += r;

        if( pack == 0 )
        {
            pack = npk_package_open( "foo_2.npk", teakey );
            if( pack != 0 )
                printf( "   package loaded.\n" );
        }
        else
        {
            NPK_ENTITY entity = npk_package_get_entity( pack, entityNames[i].c_str() );
            CHECK( entity != NULL );

            NPK_SIZE size = npk_entity_get_size( entity );
            if( npk_entity_is_ready( entity ) )
            {
                printf( "   entity %s ready.\n", entityNames[i].c_str() );
                void* buf = malloc( size );

                CHECK( npk_entity_read( entity, buf ) );
                CHECK_EQUAL_STR_WITH_FILE( (const char*)buf, "sample.txt" );

                free( buf );
                ++i;
            }
        }
    }

    npk_package_close( pack );
    close( wh );
    close( rh );

    return 0;
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2016, Paul R. Swan
// 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.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// 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
// COPYRIGHT HOLDER OR 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.
//
#include "Arduino.h"
#include "Error.h"
#include "C6502ClockMasterCpu.h"
#include "PinMap.h"
#include "6502PinDescription.h"

//
// External master clock on J14 AUX pin 8 (next to the 2-pin GND pin).
//
static const CONNECTION s_Clock_o    = {  8, "Clock"    };

C6502ClockMasterCpu::C6502ClockMasterCpu(
) : m_busA(g_pinMap40DIL, s_A_ot,  ARRAYSIZE(s_A_ot)),
    m_busD(g_pinMap40DIL, s_D_iot, ARRAYSIZE(s_D_iot)),
    m_pinCLK0i(g_pinMap40DIL, &s_CLK0i_i),
    m_pinCLK1o(g_pinMap40DIL, &s_CLK1o_o),
    m_pinCLK2o(g_pinMap40DIL, &s_CLK2o_o),
    m_pinRDY(g_pinMap40DIL, &s_RDY_i),
    m_pinClock(g_pinMap8Aux, &s_Clock_o),
    m_valueCLK1o(-1), // Force initial state matching
    m_valueCLK2o(-1)  // Force initial state matching
{
};

//
// The idle function sets up the pins into the correct direction (input/output)
// and idle state ready for the next bus cycle.
//
PERROR
C6502ClockMasterCpu::idle(
)
{
    pinMode(g_pinMap40DIL[s_GND1_i.pin],           INPUT_PULLUP);

    pinMode(g_pinMap40DIL[s__IRQ_i.pin],           INPUT);
    pinMode(g_pinMap40DIL[s__NMI_i.pin],           INPUT);

    digitalWrite(g_pinMap40DIL[s_SYNC_o.pin],      HIGH);
    pinMode(g_pinMap40DIL[s_SYNC_o.pin],           OUTPUT);

    pinMode(g_pinMap40DIL[s_Vcc_i.pin],            INPUT);
    pinMode(g_pinMap40DIL[s_GND2_i.pin],           INPUT_PULLUP);

    digitalWrite(g_pinMap40DIL[s_R_W_o.pin],       HIGH);
    pinMode(g_pinMap40DIL[s_R_W_o.pin],            OUTPUT);

    pinMode(g_pinMap40DIL[s_SO_i.pin],             INPUT);

    pinMode(g_pinMap40DIL[s_RES_i.pin],            INPUT);

    // Use the pullup input as the float to detect shorts to ground.
    m_busA.pinMode(INPUT_PULLUP);
    m_busD.pinMode(INPUT_PULLUP);

    // Set the fast input pins to input
    m_pinRDY.pinMode(INPUT);
    m_pinCLK0i.pinMode(INPUT);

    // Set the clock pins to output and perform a single pulse to start.
    m_pinClock.pinMode(OUTPUT);
    m_pinCLK1o.pinMode(OUTPUT);
    m_pinCLK2o.pinMode(OUTPUT);

    clockPulse();

    return errorSuccess;
}

//
// The check function performs a basic pin check that all the outputs can be pulled high
// by the pullup resistor as a way to detect a GND short or pulled output. It also validates
// the default state of the control pins would allow the CPU to execute instructions.
//
// If check fails the pins are left in the failing state. If check succeeds the pins are reset
// to idle state.
//
PERROR
C6502ClockMasterCpu::check(
)
{
    PERROR error = errorSuccess;

    // The ground pin (with pullup) should be connected to GND (LOW)
    CHECK_VALUE_EXIT(error, s_GND1_i, LOW);
    CHECK_VALUE_EXIT(error, s_GND2_i, LOW);

    // The Vcc pin should be high (power is on).
    CHECK_VALUE_EXIT(error, s_Vcc_i, HIGH);

    // Nothing should be driving wait states.
    CHECK_VALUE_EXIT(error, s_RDY_i, HIGH);

    // The address bus should be uncontended and pulled high.
    CHECK_BUS_VALUE_UINT16_EXIT(error, m_busA, s_A_ot, 0xFFFF);

    // The data bus should be uncontended and pulled high.
    CHECK_BUS_VALUE_UINT8_EXIT(error, m_busD, s_D_iot, 0xFF);

    // Loop to detect that reset clears
    // On exit the reset pin should be high (no reset).
    //
    {
        for (UINT32 i = 0 ; i < 0x40000 ; i++)
        {
            int value = ::digitalRead(g_pinMap40DIL[s_RES_i.pin]);

            if (value == HIGH)
            {
                break;
            }

            clockPulse();
        }
    }
    CHECK_VALUE_EXIT(error, s_RES_i, HIGH);

    // Loop to detect a clock by sampling and detecting both high and lows.
    {
        UINT16 hiCount = 0;
        UINT16 loCount = 0;

        for (int i = 0 ; i < 0x400 ; i++)
        {
            int value = m_pinCLK0i.digitalRead();

            if (value == LOW)
            {
                loCount++;
            }
            else
            {
                hiCount++;
            }

            clockPulse();
        }

        if (loCount == 0)
        {
            CHECK_PIN_VALUE_EXIT(error, m_pinCLK0i, s_CLK0i_i, LOW);
        }
        else if (hiCount == 0)
        {
            CHECK_PIN_VALUE_EXIT(error, m_pinCLK0i, s_CLK0i_i, HIGH);
        }
    }

Exit:
    return error;
}

PERROR
C6502ClockMasterCpu::memoryRead(
    UINT32 address,
    UINT8  *data
)
{
    PERROR error = errorSuccess;
    bool interruptsDisabled = false;
    UINT16 data16 = 0;

    // Set a read cycle.
    digitalWrite(g_pinMap40DIL[s_R_W_o.pin], HIGH);

    // Enable the address bus and set the value (the lower 16 bits only)
    m_busA.pinMode(OUTPUT);
    m_busA.digitalWrite((UINT16) (address & 0xFFFF));

    // Set the databus to input.
    m_busD.pinMode(INPUT);

    // Critical timing section
    noInterrupts();
    interruptsDisabled = true;

    // Assert the clocks
    m_pinCLK1o.digitalWriteLOW();
    m_pinCLK2o.digitalWriteHIGH();

    // Poll RDY for cycle completion
    {
        int rdyValue;

        for (int i = 0 ; i < 64 ; i++)
        {
            rdyValue = m_pinRDY.digitalRead();

            if (rdyValue == HIGH)
            {
                // Read the data presented on the bus as soon as we see no RDY set then clear _RD
                m_busD.digitalReadThenDigitalWriteLOW(&data16, m_pinCLK2o);
                m_pinCLK1o.digitalWriteHIGH();

                break;
            }
        }

        CHECK_LITERAL_VALUE_EXIT(error, s_RDY_i, rdyValue, HIGH);
    }

Exit:

    if (interruptsDisabled)
    {
        interrupts();
    }

    *data = (UINT8) data16;

    return error;
}

PERROR
C6502ClockMasterCpu::memoryWrite(
    UINT32 address,
    UINT8  data
)
{
    PERROR error = errorSuccess;
    bool interruptsDisabled = false;

    // Set a write cycle.
    digitalWrite(g_pinMap40DIL[s_R_W_o.pin], LOW);

    // Enable the address bus and set the value.
    m_busA.pinMode(OUTPUT);
    m_busA.digitalWrite((UINT16) (address & 0xFFFF));

    // Set the databus to output and set a value.
    m_busD.pinMode(OUTPUT);
    m_busD.digitalWrite((UINT16) data);

    // Critical timing section
    noInterrupts();
    interruptsDisabled = true;

    // Assert the clocks
    m_pinCLK1o.digitalWriteLOW();
    m_pinCLK2o.digitalWriteHIGH();

    // Poll WAIT for cycle completion
    {
        int rdyValue;

        for (int i = 0 ; i < 64 ; i++)
        {
            rdyValue = m_pinRDY.digitalRead();

            if (rdyValue == HIGH)
            {
                m_pinCLK2o.digitalWriteLOW();
                m_pinCLK1o.digitalWriteHIGH();

                break;
            }
        }
        CHECK_LITERAL_VALUE_EXIT(error, s_RDY_i, rdyValue, HIGH);
    }

    // Set a read cycle.
    digitalWrite(g_pinMap40DIL[s_R_W_o.pin], HIGH);

Exit:

    if (interruptsDisabled)
    {
        interrupts();
    }

    return error;
}

PERROR
C6502ClockMasterCpu::waitForInterrupt(
    Interrupt interrupt,
    UINT16    timeoutInMs
)
{
    PERROR error = errorSuccess;
    unsigned long startTime = millis();
    unsigned long endTime = startTime + timeoutInMs;
    int value = 0;

    UINT8 intPin = ((interrupt == NMI) ? (g_pinMap40DIL[s__NMI_i.pin]) :
                                         (g_pinMap40DIL[s__IRQ_i.pin]));

    do
    {
        value = ::digitalRead(intPin);

        if (value == LOW)
        {
            break;
        }
    }
    while (millis() < endTime);

    if (value != LOW)
    {
        error = errorTimeout;
    }

Exit:

    return error;
}

//
//
//
PERROR
C6502ClockMasterCpu::acknowledgeInterrupt(
    UINT8 *response
)
{
/*
    digitalWrite(g_pinMap40DIL[s_M_IO_o.pin], LOW);

    digitalWrite(g_pinMap40DIL[s_INTACK_o.pin], HIGH);

    return read(0, response);
*/
}

//
// Pulse the clock pin high.
// The 6502 outputs CLK1 & CLK2 based on the transition on the CLK0 input.
// Therefore, every time a clock pulse occurs we must also check to see if
// CLK0 transitions and if so drive proper output state on CLK1 & CLK2.
// The "internal" state of CLK1 & CLK2 are used in place of the pin state
// for properly generating the bus cyle.
//
void
C6502ClockMasterCpu::clockPulse(
)
{
    m_pinClock.digitalWriteHIGH();
    m_pinClock.digitalWriteLOW();

    if (m_pinCLK0i.digitalRead() == HIGH)
    {
        // From the Synertek datasheet timing diagram on CLK0 Hi transitions CLK1 leads.
        if (m_valueCLK1o != LOW)
        {
            m_valueCLK1o = LOW;
            m_pinCLK1o.digitalWrite(m_valueCLK1o);
        }
        if (m_valueCLK2o != HIGH)
        {
            m_valueCLK2o = HIGH;
            m_pinCLK2o.digitalWrite(m_valueCLK2o);
        }
    }
    else
    {
        // From the Synertek datasheet timing diagram on CLK0 Lo transitions CLK2 leads.
        if (m_valueCLK2o != LOW)
        {
            m_valueCLK2o = LOW;
            m_pinCLK2o.digitalWrite(m_valueCLK2o);
        }
        if (m_valueCLK1o != HIGH)
        {
            m_valueCLK1o = HIGH;
            m_pinCLK1o.digitalWrite(m_valueCLK1o);
        }
    }
}

<commit_msg>Initial implementation of the 6502 bus cycle in clock maaster form.<commit_after>//
// Copyright (c) 2016, Paul R. Swan
// 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.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// 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
// COPYRIGHT HOLDER OR 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.
//
#include "Arduino.h"
#include "Error.h"
#include "C6502ClockMasterCpu.h"
#include "PinMap.h"
#include "6502PinDescription.h"

//
// External master clock on J14 AUX pin 8 (next to the 2-pin GND pin).
//
static const CONNECTION s_Clock_o    = {  8, "Clock"    };

C6502ClockMasterCpu::C6502ClockMasterCpu(
) : m_busA(g_pinMap40DIL, s_A_ot,  ARRAYSIZE(s_A_ot)),
    m_busD(g_pinMap40DIL, s_D_iot, ARRAYSIZE(s_D_iot)),
    m_pinCLK0i(g_pinMap40DIL, &s_CLK0i_i),
    m_pinCLK1o(g_pinMap40DIL, &s_CLK1o_o),
    m_pinCLK2o(g_pinMap40DIL, &s_CLK2o_o),
    m_pinRDY(g_pinMap40DIL, &s_RDY_i),
    m_pinClock(g_pinMap8Aux, &s_Clock_o),
    m_valueCLK1o(-1), // Force initial state matching
    m_valueCLK2o(-1)  // Force initial state matching
{
};

//
// The idle function sets up the pins into the correct direction (input/output)
// and idle state ready for the next bus cycle.
//
PERROR
C6502ClockMasterCpu::idle(
)
{
    pinMode(g_pinMap40DIL[s_GND1_i.pin],           INPUT_PULLUP);

    pinMode(g_pinMap40DIL[s__IRQ_i.pin],           INPUT);
    pinMode(g_pinMap40DIL[s__NMI_i.pin],           INPUT);

    digitalWrite(g_pinMap40DIL[s_SYNC_o.pin],      HIGH);
    pinMode(g_pinMap40DIL[s_SYNC_o.pin],           OUTPUT);

    pinMode(g_pinMap40DIL[s_Vcc_i.pin],            INPUT);
    pinMode(g_pinMap40DIL[s_GND2_i.pin],           INPUT_PULLUP);

    digitalWrite(g_pinMap40DIL[s_R_W_o.pin],       HIGH);
    pinMode(g_pinMap40DIL[s_R_W_o.pin],            OUTPUT);

    pinMode(g_pinMap40DIL[s_SO_i.pin],             INPUT);

    pinMode(g_pinMap40DIL[s_RES_i.pin],            INPUT);

    // Use the pullup input as the float to detect shorts to ground.
    m_busA.pinMode(INPUT_PULLUP);
    m_busD.pinMode(INPUT_PULLUP);

    // Set the fast input pins to input
    m_pinRDY.pinMode(INPUT);
    m_pinCLK0i.pinMode(INPUT);

    // Set the clock pins to output and perform a single pulse to start.
    m_pinClock.pinMode(OUTPUT);
    m_pinCLK1o.pinMode(OUTPUT);
    m_pinCLK2o.pinMode(OUTPUT);

    clockPulse();

    return errorSuccess;
}

//
// The check function performs a basic pin check that all the outputs can be pulled high
// by the pullup resistor as a way to detect a GND short or pulled output. It also validates
// the default state of the control pins would allow the CPU to execute instructions.
//
// If check fails the pins are left in the failing state. If check succeeds the pins are reset
// to idle state.
//
PERROR
C6502ClockMasterCpu::check(
)
{
    PERROR error = errorSuccess;

    // The ground pin (with pullup) should be connected to GND (LOW)
    CHECK_VALUE_EXIT(error, s_GND1_i, LOW);
    CHECK_VALUE_EXIT(error, s_GND2_i, LOW);

    // The Vcc pin should be high (power is on).
    CHECK_VALUE_EXIT(error, s_Vcc_i, HIGH);

    // Nothing should be driving wait states.
    CHECK_VALUE_EXIT(error, s_RDY_i, HIGH);

    // The address bus should be uncontended and pulled high.
    CHECK_BUS_VALUE_UINT16_EXIT(error, m_busA, s_A_ot, 0xFFFF);

    // The data bus should be uncontended and pulled high.
    CHECK_BUS_VALUE_UINT8_EXIT(error, m_busD, s_D_iot, 0xFF);

    // Loop to detect that reset clears
    // On exit the reset pin should be high (no reset).
    //
    {
        for (UINT32 i = 0 ; i < 0x40000 ; i++)
        {
            int value = ::digitalRead(g_pinMap40DIL[s_RES_i.pin]);

            if (value == HIGH)
            {
                break;
            }

            clockPulse();
        }
    }
    CHECK_VALUE_EXIT(error, s_RES_i, HIGH);

    // Loop to detect a clock by sampling and detecting both high and lows.
    {
        UINT16 hiCount = 0;
        UINT16 loCount = 0;

        for (int i = 0 ; i < 0x400 ; i++)
        {
            int value = m_pinCLK0i.digitalRead();

            if (value == LOW)
            {
                loCount++;
            }
            else
            {
                hiCount++;
            }

            clockPulse();
        }

        if (loCount == 0)
        {
            CHECK_PIN_VALUE_EXIT(error, m_pinCLK0i, s_CLK0i_i, LOW);
        }
        else if (hiCount == 0)
        {
            CHECK_PIN_VALUE_EXIT(error, m_pinCLK0i, s_CLK0i_i, HIGH);
        }
    }

Exit:
    return error;
}

//
// Though there are two clock outputs the datasheet only shows timing
// related to CLK2. It's an output from the CPU but we use it here as
// an "input" for implementing the cycle correlated with it. It's
// fairly simple, drive the outputs in the low phase and terminate
// the cycle on the falling edge. CLK2 thus appears to be similar to
// the 68xx series "E" clock (but the datasheet doesn't suggest that
// CLK1 is "Q" ...)
//
PERROR
C6502ClockMasterCpu::memoryReadWrite(
    UINT32 address,
    UINT8  *data,
    int    readWrite
)
{
    PERROR error = errorSuccess;

    //
    // Step 1 - Wait for CLK2 Lo
    //
    for (int x = 0 ; x < 100 ; x++)
    {
        if (m_valueCLK2o == LOW)
        {
            break;
        }
        clockPulse();
    }
    CHECK_LITERAL_VALUE_EXIT(error, s_CLK2o_o, m_valueCLK2o, LOW);

    //
    // Step 2 - Drive RW, A, onto the bus.
    // For read, set D input.
    //
    m_busA.pinMode(OUTPUT);
    m_busA.digitalWrite(address);

    if (readWrite == LOW)
    {
        digitalWrite(g_pinMap40DIL[s_R_W_o.pin], LOW);
        m_busD.pinMode(OUTPUT);
        m_busD.digitalWrite(*data);
    }
    else
    {
        digitalWrite(g_pinMap40DIL[s_R_W_o.pin], HIGH);
        m_busD.pinMode(INPUT);
    }

    //
    // Currently no support for RDY delayed cycles.
    // It only works for reads making it of little use in practice.
    //
    CHECK_VALUE_EXIT(error, s_RDY_i, HIGH);

    //
    // Step 3 - Wait for CLK2 Hi
    //
    for (int x = 0 ; x < 100 ; x++)
    {
        if (m_valueCLK2o == HIGH)
        {
            break;
        }
        clockPulse();
    }
    CHECK_LITERAL_VALUE_EXIT(error, s_CLK2o_o, m_valueCLK2o, HIGH);

    //
    // Step 4 - D-Read.
    //
    if (readWrite == HIGH)
    {
        UINT16 data16;

        m_busD.digitalRead(&data16);
        *data = (UINT8) data16;
    }

    //
    // Step 5 - Wait for CLK2 Lo to complete the cycle.
    // Back to initial state.
    //
    for (int x = 0 ; x < 100 ; x++)
    {
        if (m_valueCLK2o == LOW)
        {
            break;
        }
        clockPulse();
    }
    CHECK_LITERAL_VALUE_EXIT(error, s_CLK2o_o, m_valueCLK2o, LOW);

    if (readWrite == LOW)
    {
        m_busD.pinMode(INPUT);
        digitalWrite(g_pinMap40DIL[s_R_W_o.pin], HIGH);
    }

Exit:
    return error;
}

PERROR
C6502ClockMasterCpu::memoryRead(
    UINT32 address,
    UINT8  *data
)
{
    return memoryReadWrite(address, data, HIGH);
}

PERROR
C6502ClockMasterCpu::memoryWrite(
    UINT32 address,
    UINT8  data
)
{
    return memoryReadWrite(address, &data, LOW);
}

PERROR
C6502ClockMasterCpu::waitForInterrupt(
    Interrupt interrupt,
    UINT16    timeoutInMs
)
{
    return errorNotImplemented;
}

//
//
//
PERROR
C6502ClockMasterCpu::acknowledgeInterrupt(
    UINT8 *response
)
{
    return errorNotImplemented;
}

//
// Pulse the clock pin high.
// The 6502 outputs CLK1 & CLK2 based on the transition on the CLK0 input.
// Therefore, every time a clock pulse occurs we must also check to see if
// CLK0 transitions and if so drive proper output state on CLK1 & CLK2.
// The "internal" state of CLK1 & CLK2 are used in place of the pin state
// for properly generating the bus cyle.
//
void
C6502ClockMasterCpu::clockPulse(
)
{
    m_pinClock.digitalWriteHIGH();
    m_pinClock.digitalWriteLOW();

    if (m_pinCLK0i.digitalRead() == HIGH)
    {
        // From the Synertek datasheet timing diagram on CLK0 Hi transitions CLK1 leads.
        if (m_valueCLK1o != LOW)
        {
            m_valueCLK1o = LOW;
            m_pinCLK1o.digitalWrite(m_valueCLK1o);
        }
        if (m_valueCLK2o != HIGH)
        {
            m_valueCLK2o = HIGH;
            m_pinCLK2o.digitalWrite(m_valueCLK2o);
        }
    }
    else
    {
        // From the Synertek datasheet timing diagram on CLK0 Lo transitions CLK2 leads.
        if (m_valueCLK2o != LOW)
        {
            m_valueCLK2o = LOW;
            m_pinCLK2o.digitalWrite(m_valueCLK2o);
        }
        if (m_valueCLK1o != HIGH)
        {
            m_valueCLK1o = HIGH;
            m_pinCLK1o.digitalWrite(m_valueCLK1o);
        }
    }
}

<|endoftext|>