<commit_before>//******************************************************************************************************
//  RoutingTables.cpp - Gbtc
//
//  Copyright  2019, Grid Protection Alliance.  All Rights Reserved.
//
//  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
//  the NOTICE file distributed with this work for additional information regarding copyright ownership.
//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
//  file except in compliance with the License. You may obtain a copy of the License at:
//
//      http://opensource.org/licenses/MIT
//
//  Unless agreed to in writing, the subject software distributed under the License is distributed on an
//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
//  License for the specific language governing permissions and limitations.
//
//  Code Modification History:
//  ----------------------------------------------------------------------------------------------------
//  03/28/2019 - J. Ritchie Carroll
//       Generated original version of source code.
//
//******************************************************************************************************

#include "RoutingTables.h"

using namespace std;
using namespace GSF;
using namespace GSF::TimeSeries;
using namespace GSF::TimeSeries::Transport;

RoutingTables::RoutingTables() :
    m_activeRoutes(NewSharedPtr<RoutingTable>()),
    m_enabled(true)
{
    Thread([this]()
    {
        while (m_enabled)
        {
            m_routingTableOperations.WaitForData();
            const auto operation = m_routingTableOperations.Dequeue();
            operation.first(*this, operation.second);
        }
    });
}

RoutingTables::~RoutingTables()
{
    m_enabled = false;
    m_routingTableOperations.Release();
}

RoutingTables::RoutingTablePtr RoutingTables::CloneActiveRoutes()
{
    ReaderLock readLock(m_activeRoutesLock);
    RoutingTablePtr clonedRoutes = NewSharedPtr<RoutingTable>(*m_activeRoutes);
    return clonedRoutes;
}

void RoutingTables::SetActiveRoutes(RoutingTablePtr activeRoutes)
{
    WriterLock writeLock(m_activeRoutesLock);
    m_activeRoutes = std::move(activeRoutes);
}

void RoutingTables::UpdateRoutesOperation(RoutingTables& routingTables, const DestinationRoutes& destinationRoutes)
{
    RoutingTablePtr activeRoutes = routingTables.CloneActiveRoutes();
    const SubscriberConnectionPtr& destination = destinationRoutes.first;
    const unordered_set<GSF::Guid>& routes = destinationRoutes.second;

    // Remove subscriber connection from undesired measurement route destinations
    for (auto& pair : *activeRoutes)
    {
        if (routes.find(pair.first) != routes.end())
            pair.second->erase(destination);
    }

    // Add subscriber connection to desired measurement route destinations
    for (auto& signalID : routes)
    {
        DestinationsPtr destinations;

        if (!TryGetValue(*activeRoutes, signalID, destinations, destinations))
        {
            destinations = NewSharedPtr<Destinations>();
            activeRoutes->emplace(signalID, destinations);
        }

        destinations->insert(destination);
    }

    routingTables.SetActiveRoutes(activeRoutes);
}

void RoutingTables::RemoveRoutesOperation(RoutingTables& routingTables, const DestinationRoutes& destinationRoutes)
{
    const RoutingTablePtr activeRoutes = routingTables.CloneActiveRoutes();
    const SubscriberConnectionPtr& destination = destinationRoutes.first;

    // Remove subscriber connection from existing measurement route destinations
    for (auto& pair : *activeRoutes)
        pair.second->erase(destination);

    routingTables.SetActiveRoutes(activeRoutes);
}

void RoutingTables::UpdateRoutes(const SubscriberConnectionPtr& destination, const unordered_set<Guid>& routes)
{
    // Queue update routes operation
    m_routingTableOperations.Enqueue(RoutingTableOperation(&UpdateRoutesOperation, DestinationRoutes(destination, routes)));
}

void RoutingTables::RemoveRoutes(const SubscriberConnectionPtr& destination)
{
    // Queue remove routes operation
    m_routingTableOperations.Enqueue(RoutingTableOperation(&RemoveRoutesOperation, DestinationRoutes(destination, unordered_set<Guid>())));
}

void RoutingTables::PublishMeasurements(const vector<MeasurementPtr>& measurements)
{
    typedef vector<MeasurementPtr> Measurements;
    typedef SharedPtr<Measurements> MeasurementsPtr;
    unordered_map<SubscriberConnectionPtr, MeasurementsPtr> routedMeasurementMap;
    const size_t size = measurements.size();

    // Constrain read lock to this block
    {
        ReaderLock readLock(m_activeRoutesLock);
        const RoutingTable activeRoutes = *m_activeRoutes;

        for (auto& measurement : measurements)
        {
            DestinationsPtr destinationsPtr;

            if (TryGetValue(activeRoutes, measurement->SignalID, destinationsPtr, destinationsPtr))
            {
                const Destinations destinations = *destinationsPtr;

                for (auto& destination : destinations)
                {
                    MeasurementsPtr routedMeasurements;

                    if (!TryGetValue(routedMeasurementMap, destination, routedMeasurements, routedMeasurements))
                    {
                        routedMeasurements = NewSharedPtr<Measurements>();
                        routedMeasurements->reserve(size);
                        routedMeasurementMap.emplace(destination, routedMeasurements);
                    }

                    routedMeasurements->push_back(measurement);
                }
            }
        }
    }

    // Publish routed measurements
    for (auto& pair : routedMeasurementMap)
    {
        auto& destination = pair.first;

        if (destination->GetIsSubscribed() && !destination->GetIsTemporalSubscription())
            destination->PublishMeasurements(*pair.second);
    }
}
<commit_msg>TimeSeriesPlatformLibrary: Updated use of shared pointer derefs to const reference instances in RoutingTables.<commit_after>//******************************************************************************************************
//  RoutingTables.cpp - Gbtc
//
//  Copyright  2019, Grid Protection Alliance.  All Rights Reserved.
//
//  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
//  the NOTICE file distributed with this work for additional information regarding copyright ownership.
//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
//  file except in compliance with the License. You may obtain a copy of the License at:
//
//      http://opensource.org/licenses/MIT
//
//  Unless agreed to in writing, the subject software distributed under the License is distributed on an
//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
//  License for the specific language governing permissions and limitations.
//
//  Code Modification History:
//  ----------------------------------------------------------------------------------------------------
//  03/28/2019 - J. Ritchie Carroll
//       Generated original version of source code.
//
//******************************************************************************************************

#include "RoutingTables.h"

using namespace std;
using namespace GSF;
using namespace GSF::TimeSeries;
using namespace GSF::TimeSeries::Transport;

RoutingTables::RoutingTables() :
    m_activeRoutes(NewSharedPtr<RoutingTable>()),
    m_enabled(true)
{
    Thread([this]()
    {
        while (m_enabled)
        {
            m_routingTableOperations.WaitForData();
            const auto operation = m_routingTableOperations.Dequeue();
            operation.first(*this, operation.second);
        }
    });
}

RoutingTables::~RoutingTables()
{
    m_enabled = false;
    m_routingTableOperations.Release();
}

RoutingTables::RoutingTablePtr RoutingTables::CloneActiveRoutes()
{
    ReaderLock readLock(m_activeRoutesLock);
    RoutingTablePtr clonedRoutes = NewSharedPtr<RoutingTable>(*m_activeRoutes);
    return clonedRoutes;
}

void RoutingTables::SetActiveRoutes(RoutingTablePtr activeRoutes)
{
    WriterLock writeLock(m_activeRoutesLock);
    m_activeRoutes = std::move(activeRoutes);
}

void RoutingTables::UpdateRoutesOperation(RoutingTables& routingTables, const DestinationRoutes& destinationRoutes)
{
    const RoutingTablePtr activeRoutesPtr = routingTables.CloneActiveRoutes();
    RoutingTable& activeRoutes = *activeRoutesPtr;
    const SubscriberConnectionPtr& destination = destinationRoutes.first;
    const unordered_set<GSF::Guid>& routes = destinationRoutes.second;

    // Remove subscriber connection from undesired measurement route destinations
    for (auto& pair : activeRoutes)
    {
        if (routes.find(pair.first) != routes.end())
            pair.second->erase(destination);
    }

    // Add subscriber connection to desired measurement route destinations
    for (auto& signalID : routes)
    {
        DestinationsPtr destinations;

        if (!TryGetValue(activeRoutes, signalID, destinations, destinations))
        {
            destinations = NewSharedPtr<Destinations>();
            activeRoutes.emplace(signalID, destinations);
        }

        destinations->insert(destination);
    }

    routingTables.SetActiveRoutes(activeRoutesPtr);
}

void RoutingTables::RemoveRoutesOperation(RoutingTables& routingTables, const DestinationRoutes& destinationRoutes)
{
    const RoutingTablePtr activeRoutesPtr = routingTables.CloneActiveRoutes();
    const RoutingTable& activeRoutes = *activeRoutesPtr;
    const SubscriberConnectionPtr& destination = destinationRoutes.first;

    // Remove subscriber connection from existing measurement route destinations
    for (auto& pair : activeRoutes)
        pair.second->erase(destination);

    routingTables.SetActiveRoutes(activeRoutesPtr);
}

void RoutingTables::UpdateRoutes(const SubscriberConnectionPtr& destination, const unordered_set<Guid>& routes)
{
    // Queue update routes operation
    m_routingTableOperations.Enqueue(RoutingTableOperation(&UpdateRoutesOperation, DestinationRoutes(destination, routes)));
}

void RoutingTables::RemoveRoutes(const SubscriberConnectionPtr& destination)
{
    // Queue remove routes operation
    m_routingTableOperations.Enqueue(RoutingTableOperation(&RemoveRoutesOperation, DestinationRoutes(destination, unordered_set<Guid>())));
}

void RoutingTables::PublishMeasurements(const vector<MeasurementPtr>& measurements)
{
    typedef vector<MeasurementPtr> Measurements;
    typedef SharedPtr<Measurements> MeasurementsPtr;
    unordered_map<SubscriberConnectionPtr, MeasurementsPtr> routedMeasurementMap;
    const size_t size = measurements.size();

    // Constrain read lock to this block
    {
        ReaderLock readLock(m_activeRoutesLock);
        const RoutingTable& activeRoutes = *m_activeRoutes;

        for (auto& measurement : measurements)
        {
            DestinationsPtr destinationsPtr;

            if (TryGetValue(activeRoutes, measurement->SignalID, destinationsPtr, destinationsPtr))
            {
                const Destinations& destinations = *destinationsPtr;

                for (auto& destination : destinations)
                {
                    MeasurementsPtr routedMeasurements;

                    if (!TryGetValue(routedMeasurementMap, destination, routedMeasurements, routedMeasurements))
                    {
                        routedMeasurements = NewSharedPtr<Measurements>();
                        routedMeasurements->reserve(size);
                        routedMeasurementMap.emplace(destination, routedMeasurements);
                    }

                    routedMeasurements->push_back(measurement);
                }
            }
        }
    }

    // Publish routed measurements
    for (auto& pair : routedMeasurementMap)
    {
        auto& destination = pair.first;

        if (destination->GetIsSubscribed() && !destination->GetIsTemporalSubscription())
            destination->PublishMeasurements(*pair.second);
    }
}
<|endoftext|>


<commit_before>//
//  Sector.hpp
//  G3MiOSSDK
//
//  Created by Agustín Trujillo Pino on 12/06/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef G3MiOSSDK_Sector_h
#define G3MiOSSDK_Sector_h

#include <vector>
#include <math.h>

#include "Geodetic2D.hpp"
#include "Context.hpp"
#include "Vector2D.hpp"
#include "Geodetic3D.hpp"
#include "Vector3D.hpp"

//class Sector_Geodetic2DCachedData;

class Sector {

private:
  const Geodetic2D _lower;
  const Geodetic2D _upper;
  const Geodetic2D _center;

  const Angle _deltaLatitude;
  const Angle _deltaLongitude;

  // this lazy value represent the half diagonal of the sector, measured in radians
  // it's stored in double instead of Angle class to optimize performance in android
  // this value is only used in the method Sector::isBackOriented
  mutable double _deltaRadius;

  //const Geodetic2D getClosestPoint(const Geodetic2D& pos) const;

  /*
  // cached values for speed up in isBackOriented()
  mutable Sector_Geodetic2DCachedData* _nwData;
  mutable Sector_Geodetic2DCachedData* _neData;
  mutable Sector_Geodetic2DCachedData* _swData;
  mutable Sector_Geodetic2DCachedData* _seData;
   */

  mutable Vector3D* _cartesianCenter;

public:

  ~Sector();

  Sector(const Geodetic2D& lower,
         const Geodetic2D& upper) :
  _lower(lower),
  _upper(upper),
  _deltaLatitude(upper.latitude().sub(lower.latitude())),
  _deltaLongitude(upper.longitude().sub(lower.longitude())),
  _center(Angle::midAngle(lower.latitude(), upper.latitude()),
          Angle::midAngle(lower.longitude(), upper.longitude())),
  _deltaRadius(-1.0),
  /*
   _nwData(NULL),
  _neData(NULL),
  _swData(NULL),
  _seData(NULL),
   */
  _cartesianCenter(NULL)
  {
  }

  Sector(const Sector& sector) :
  _lower(sector._lower),
  _upper(sector._upper),
  _deltaLatitude(sector._deltaLatitude),
  _deltaLongitude(sector._deltaLongitude),
  _center(sector._center),
  _deltaRadius(sector._deltaRadius),
  /*
   _nwData(NULL),
  _neData(NULL),
  _swData(NULL),
  _seData(NULL),
   */
  _cartesianCenter((sector._cartesianCenter==NULL)? NULL : new Vector3D(*(sector._cartesianCenter)))
  {
  }

  static Sector fromDegrees(double minLat, double minLon, double maxLat, double maxLon){
    const Geodetic2D lower(Angle::fromDegrees(minLat), Angle::fromDegrees(minLon));
    const Geodetic2D upper(Angle::fromDegrees(maxLat), Angle::fromDegrees(maxLon));

    return Sector(lower, upper);
  }

  const Vector2D div(const Sector& that) const;

//  Vector2D getTranslationFactor(const Sector& that) const;

  bool fullContains(const Sector& that) const;

  Sector intersection(const Sector& that) const;

  Sector mergedWith(const Sector& that) const;

  static Sector fullSphere() {
    return Sector(Geodetic2D(Angle::fromDegrees(-90), Angle::fromDegrees(-180)),
                  Geodetic2D(Angle::fromDegrees( 90), Angle::fromDegrees( 180)));
  }

  const Geodetic2D lower() const {
    return _lower;
  }

  const Angle lowerLatitude() const {
    return _lower.latitude();
  }

  const Angle lowerLongitude() const {
    return _lower.longitude();
  }

  const Geodetic2D upper() const {
    return _upper;
  }

  const Angle upperLatitude() const {
    return _upper.latitude();
  }

  const Angle upperLongitude() const {
    return _upper.longitude();
  }

  bool contains(const Angle& latitude,
                const Angle& longitude) const;

  bool contains(const Geodetic2D& position) const {
    return contains(position.latitude(),
                    position.longitude());
  }

  bool contains(const Geodetic3D& position) const {
    return contains(position.latitude(),
                    position.longitude());
  }

  bool touchesWith(const Sector& that) const;

  const Angle getDeltaLatitude() const {
    return _deltaLatitude;
  }

  const Angle getDeltaLongitude() const {
    return _deltaLongitude;
  }

  const Geodetic2D getSW() const {
    return _lower;
  }

  const Geodetic2D getNE() const {
    return _upper;
  }

  const Geodetic2D getNW() const {
    return Geodetic2D(_upper.latitude(),
                      _lower.longitude());
  }

  const Geodetic2D getSE() const {
    return Geodetic2D(_lower.latitude(),
                      _upper.longitude());
  }

  const Geodetic2D getCenter() const {
    return _center;
  }

  // (u,v) are similar to texture coordinates inside the Sector
  // (u,v)=(0,0) in NW point, and (1,1) in SE point
  const Geodetic2D getInnerPoint(double u, double v) const;

  const Angle getInnerPointLatitude(double v) const;

  const Vector2D getUVCoordinates(const Geodetic2D& point) const {
    return getUVCoordinates(point.latitude(), point.longitude());
  }

  Vector2D getUVCoordinates(const Angle& latitude,
                            const Angle& longitude) const {
    return Vector2D(getUCoordinate(longitude),
                    getVCoordinate(latitude));
  }

  double getUCoordinate(const Angle& longitude) const {
    return (longitude._radians - _lower.longitude()._radians) / _deltaLongitude._radians;
  }

  double getVCoordinate(const Angle& latitude) const {
    return (_upper.latitude()._radians - latitude._radians)   / _deltaLatitude._radians;
  }

  bool isBackOriented(const G3MRenderContext *rc,
                      double minHeight) const;

  const Geodetic2D clamp(const Geodetic2D& pos) const;

  const std::string description() const;

  Sector* shrinkedByPercentP(float percent) const {
    const Angle deltaLatitude  = _deltaLatitude.times(percent).div(2);
    const Angle deltaLongitude = _deltaLongitude.times(percent).div(2);

    const Geodetic2D delta(deltaLatitude, deltaLongitude);

    return new Sector(_lower.add( delta ),
                      _upper.sub( delta ) );
  }

  Sector shrinkedByPercent(float percent) const {
    const Angle deltaLatitude  = _deltaLatitude.times(percent).div(2);
    const Angle deltaLongitude = _deltaLongitude.times(percent).div(2);

    const Geodetic2D delta(deltaLatitude, deltaLongitude);

    return Sector(_lower.add( delta ),
                  _upper.sub( delta ) );
  }

  bool isEqualsTo(const Sector& that) const {
    return _lower.isEqualsTo(that._lower) && _upper.isEqualsTo(that._upper);
  }

  bool touchesNorthPole() const {
    return (_upper.latitude()._degrees >= 89.9);
  }

  bool touchesSouthPole() const {
    return (_lower.latitude()._degrees <= -89.9);
  }

  double getDeltaRadius() const {
    if (_deltaRadius<0.0)
      _deltaRadius = sqrt(_deltaLatitude.radians()*_deltaLatitude.radians()+_deltaLongitude.radians()*_deltaLongitude.radians())*0.5;
    return _deltaRadius;
  }

  const Vector3D getCartesianCenter(const Planet* planet) const;
};

#endif
<commit_msg>solving java error in Sector constructor<commit_after>//
//  Sector.hpp
//  G3MiOSSDK
//
//  Created by Agustín Trujillo Pino on 12/06/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#ifndef G3MiOSSDK_Sector_h
#define G3MiOSSDK_Sector_h

#include <vector>
#include <math.h>

#include "Geodetic2D.hpp"
#include "Context.hpp"
#include "Vector2D.hpp"
#include "Geodetic3D.hpp"
#include "Vector3D.hpp"

//class Sector_Geodetic2DCachedData;

class Sector {

private:
  const Geodetic2D _lower;
  const Geodetic2D _upper;
  const Geodetic2D _center;

  const Angle _deltaLatitude;
  const Angle _deltaLongitude;

  // this lazy value represent the half diagonal of the sector, measured in radians
  // it's stored in double instead of Angle class to optimize performance in android
  // this value is only used in the method Sector::isBackOriented
  mutable double _deltaRadius;

  //const Geodetic2D getClosestPoint(const Geodetic2D& pos) const;

  /*
  // cached values for speed up in isBackOriented()
  mutable Sector_Geodetic2DCachedData* _nwData;
  mutable Sector_Geodetic2DCachedData* _neData;
  mutable Sector_Geodetic2DCachedData* _swData;
  mutable Sector_Geodetic2DCachedData* _seData;
   */

  mutable Vector3D* _cartesianCenter;

public:

  ~Sector();

  Sector(const Geodetic2D& lower,
         const Geodetic2D& upper) :
  _lower(lower),
  _upper(upper),
  _deltaLatitude(upper.latitude().sub(lower.latitude())),
  _deltaLongitude(upper.longitude().sub(lower.longitude())),
  _center(Angle::midAngle(lower.latitude(), upper.latitude()),
          Angle::midAngle(lower.longitude(), upper.longitude())),
  _deltaRadius(-1.0),
  /*
   _nwData(NULL),
  _neData(NULL),
  _swData(NULL),
  _seData(NULL),
   */
  _cartesianCenter(NULL)
  {
  }

  Sector(const Sector& sector) :
  _lower(sector._lower),
  _upper(sector._upper),
  _deltaLatitude(sector._deltaLatitude),
  _deltaLongitude(sector._deltaLongitude),
  _center(sector._center),
  _deltaRadius(sector._deltaRadius)
  /*
   _nwData(NULL),
  _neData(NULL),
  _swData(NULL),
  _seData(NULL),
   */
  {
    if (sector._cartesianCenter==NULL)
      _cartesianCenter = NULL;
    else {
      const Vector3D* cartesianCenter = sector._cartesianCenter;
      _cartesianCenter = new Vector3D(*cartesianCenter);
    }

  }

  static Sector fromDegrees(double minLat, double minLon, double maxLat, double maxLon){
    const Geodetic2D lower(Angle::fromDegrees(minLat), Angle::fromDegrees(minLon));
    const Geodetic2D upper(Angle::fromDegrees(maxLat), Angle::fromDegrees(maxLon));

    return Sector(lower, upper);
  }

  const Vector2D div(const Sector& that) const;

//  Vector2D getTranslationFactor(const Sector& that) const;

  bool fullContains(const Sector& that) const;

  Sector intersection(const Sector& that) const;

  Sector mergedWith(const Sector& that) const;

  static Sector fullSphere() {
    return Sector(Geodetic2D(Angle::fromDegrees(-90), Angle::fromDegrees(-180)),
                  Geodetic2D(Angle::fromDegrees( 90), Angle::fromDegrees( 180)));
  }

  const Geodetic2D lower() const {
    return _lower;
  }

  const Angle lowerLatitude() const {
    return _lower.latitude();
  }

  const Angle lowerLongitude() const {
    return _lower.longitude();
  }

  const Geodetic2D upper() const {
    return _upper;
  }

  const Angle upperLatitude() const {
    return _upper.latitude();
  }

  const Angle upperLongitude() const {
    return _upper.longitude();
  }

  bool contains(const Angle& latitude,
                const Angle& longitude) const;

  bool contains(const Geodetic2D& position) const {
    return contains(position.latitude(),
                    position.longitude());
  }

  bool contains(const Geodetic3D& position) const {
    return contains(position.latitude(),
                    position.longitude());
  }

  bool touchesWith(const Sector& that) const;

  const Angle getDeltaLatitude() const {
    return _deltaLatitude;
  }

  const Angle getDeltaLongitude() const {
    return _deltaLongitude;
  }

  const Geodetic2D getSW() const {
    return _lower;
  }

  const Geodetic2D getNE() const {
    return _upper;
  }

  const Geodetic2D getNW() const {
    return Geodetic2D(_upper.latitude(),
                      _lower.longitude());
  }

  const Geodetic2D getSE() const {
    return Geodetic2D(_lower.latitude(),
                      _upper.longitude());
  }

  const Geodetic2D getCenter() const {
    return _center;
  }

  // (u,v) are similar to texture coordinates inside the Sector
  // (u,v)=(0,0) in NW point, and (1,1) in SE point
  const Geodetic2D getInnerPoint(double u, double v) const;

  const Angle getInnerPointLatitude(double v) const;

  const Vector2D getUVCoordinates(const Geodetic2D& point) const {
    return getUVCoordinates(point.latitude(), point.longitude());
  }

  Vector2D getUVCoordinates(const Angle& latitude,
                            const Angle& longitude) const {
    return Vector2D(getUCoordinate(longitude),
                    getVCoordinate(latitude));
  }

  double getUCoordinate(const Angle& longitude) const {
    return (longitude._radians - _lower.longitude()._radians) / _deltaLongitude._radians;
  }

  double getVCoordinate(const Angle& latitude) const {
    return (_upper.latitude()._radians - latitude._radians)   / _deltaLatitude._radians;
  }

  bool isBackOriented(const G3MRenderContext *rc,
                      double minHeight) const;

  const Geodetic2D clamp(const Geodetic2D& pos) const;

  const std::string description() const;

  Sector* shrinkedByPercentP(float percent) const {
    const Angle deltaLatitude  = _deltaLatitude.times(percent).div(2);
    const Angle deltaLongitude = _deltaLongitude.times(percent).div(2);

    const Geodetic2D delta(deltaLatitude, deltaLongitude);

    return new Sector(_lower.add( delta ),
                      _upper.sub( delta ) );
  }

  Sector shrinkedByPercent(float percent) const {
    const Angle deltaLatitude  = _deltaLatitude.times(percent).div(2);
    const Angle deltaLongitude = _deltaLongitude.times(percent).div(2);

    const Geodetic2D delta(deltaLatitude, deltaLongitude);

    return Sector(_lower.add( delta ),
                  _upper.sub( delta ) );
  }

  bool isEqualsTo(const Sector& that) const {
    return _lower.isEqualsTo(that._lower) && _upper.isEqualsTo(that._upper);
  }

  bool touchesNorthPole() const {
    return (_upper.latitude()._degrees >= 89.9);
  }

  bool touchesSouthPole() const {
    return (_lower.latitude()._degrees <= -89.9);
  }

  double getDeltaRadius() const {
    if (_deltaRadius<0.0)
      _deltaRadius = sqrt(_deltaLatitude.radians()*_deltaLatitude.radians()+_deltaLongitude.radians()*_deltaLongitude.radians())*0.5;
    return _deltaRadius;
  }

  const Vector3D getCartesianCenter(const Planet* planet) const;
};

#endif
<|endoftext|>


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

#ifndef _NAMEBUFF_HXX
#define _NAMEBUFF_HXX

#ifndef _TOOLS_DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

#ifndef SC_COMPILER_HXX
#include "compiler.hxx"
#endif

#ifndef _ROOT_HXX
#include "root.hxx"
#endif

#include "rangenam.hxx"

class ScDocument;
class ScTokenArray;
class NameBuffer;

class StringHashEntry
{
private:
    friend NameBuffer;
    String          aString;
    UINT32          nHash;

    static UINT32   MakeHashCode( const String& );
public:
    inline          StringHashEntry( const String& );
    inline          StringHashEntry( void );
    inline void     operator =( const sal_Char* );
    inline void     operator =( const String& );
    inline void     operator =( const StringHashEntry& );
    inline BOOL     operator ==( const StringHashEntry& ) const;
};

inline StringHashEntry::StringHashEntry( void )
{
}

inline StringHashEntry::StringHashEntry( const String& r ) : aString( r )
{
    nHash = MakeHashCode( r );
}

inline void StringHashEntry::operator =( const sal_Char* p )
{
    aString.AssignAscii( p );
    nHash = MakeHashCode( aString );
}

inline void StringHashEntry::operator =( const String& r )
{
    aString = r;
    nHash = MakeHashCode( r );
}

inline void StringHashEntry::operator =( const StringHashEntry& r )
{
    nHash = r.nHash;
    aString = r.aString;
}

inline BOOL StringHashEntry::operator ==( const StringHashEntry& r ) const
{
    return ( nHash == r.nHash && aString ==  r.aString );
}

class NameBuffer : private List, public ExcRoot
{
private:
    UINT16                  nBase;      // Index-Basis
public:
//    inline                  NameBuffer( void );   //#94039# prevent empty rootdata
    inline                  NameBuffer( RootData* );
    inline                  NameBuffer( RootData*, UINT16 nNewBase );

    virtual                 ~NameBuffer();
    inline const String*    Get( UINT16 nIndex );
    inline UINT16           GetLastIndex( void );
    inline void             SetBase( UINT16 nNewBase = 0 );
    void                    operator <<( const String& rNewString );
    void                    Reset( void );
    BOOL                    Find( const sal_Char* pRefName, UINT16& rIndex );
};

//#94039# prevent empty rootdata
//inline NameBuffer::NameBuffer( void )
//{
//    nBase = 0;
//}

inline NameBuffer::NameBuffer( RootData* p ) : ExcRoot( p )
{
    nBase = 0;
}

inline NameBuffer::NameBuffer( RootData* p, UINT16 nNewBase ) : ExcRoot( p )
{
    nBase = nNewBase;
}

inline const String* NameBuffer::Get( UINT16 n )
{
    if( n < nBase )
        return NULL;
    else
    {
        StringHashEntry* pObj = ( StringHashEntry* ) List::GetObject( n );

        if( pObj )
            return &pObj->aString;
        else
            return NULL;
    }
}

inline UINT16 NameBuffer::GetLastIndex( void )
{
    DBG_ASSERT( Count() + nBase <= 0xFFFF, "*NameBuffer::GetLastIndex(): Ich hab' die Nase voll!" );

    return ( UINT16 ) ( Count() + nBase );
}

inline void NameBuffer::SetBase( UINT16 nNewBase )
{
    nBase = nNewBase;
}

class RangeNameBuffer : private List, public ExcRoot
{
protected:
    static const UINT16     nError;             // Dummy, Null-Wert
public:
    inline                  RangeNameBuffer( RootData* p );
                                            // Name, Definition
    void                    Store( ByteString&, const ScTokenArray*,
                                UINT16 nAltSheet = 0, const RangeType eNameType = RT_ABSAREA );
    void                    Store( String&, const ScTokenArray*,
                                UINT16 nAltSheet = 0, const RangeType eNameType = RT_ABSAREA );
    inline UINT16           operator[]( UINT16 nExcInd ) const;
    inline UINT16           GetPos( void ) const;
};

inline RangeNameBuffer::RangeNameBuffer( RootData* p ) : ExcRoot( p )
{
    // Ersten gibt's in Excel UND bei SC nicht!
    Insert( ( void* ) FALSE, LIST_APPEND );
}

inline UINT16 RangeNameBuffer::operator[]( UINT16 nExcInd ) const
{
    DBG_ASSERT( nExcInd, "-RangeNameBuffer::operator[](): 0 nicht definiert!?" );

    return nExcInd;
}

inline UINT16 RangeNameBuffer::GetPos( void ) const
{
    DBG_ASSERT( Count() <= 0xFFFF, "*RangeNameBuffer::GetPos(): zuviel in Liste!" );

    return ( UINT16 ) Count();
}

class ShrfmlaBuffer : private List, public ExcRoot
{
private:
    UINT16                  nBase;          // Startwert Indizierung
public:
                            ShrfmlaBuffer( RootData* pRD );
    virtual                 ~ShrfmlaBuffer();
    void                    Store( const ScRange& rRange, const ScTokenArray& );
    UINT16                  Find( const ScAddress aAdress );

    static String           CreateName( const ScRange& );
    static BOOL             GetAddress( const String& rName, ScRange& rReturn );
    };

class RangeNameBufferWK3 : private List
{
private:
    struct ENTRY
        {
        StringHashEntry     aStrHashEntry;
        ComplRefData        aComplRefDataRel;
        String              aScAbsName;
        UINT16              nAbsInd;        // == 0 -> noch keine Abs-Name!
        UINT16              nRelInd;
        BOOL                bSingleRef;
                            ENTRY( const String& rName, const String& rScName, const ComplRefData& rCRD ) :
                                aStrHashEntry( rName ),
                                aComplRefDataRel( rCRD ),
                                aScAbsName( rScName )
                            {
                                nAbsInd = 0;
                                aScAbsName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_ABS" ) );
                            }
        };

    ScTokenArray*           pScTokenArray;
    UINT16                  nIntCount;
public:
                            RangeNameBufferWK3( void );
    virtual                 ~RangeNameBufferWK3();
    void                    Add( const String& rName, const ComplRefData& rCRD );
    inline void             Add( const String& rName, const ScRange& aScRange );
    BOOL                    FindRel( const String& rRef, UINT16& rIndex );
    BOOL                    FindAbs( const String& rRef, UINT16& rIndex );
};

inline void RangeNameBufferWK3::Add( const String& rName, const ScRange& aScRange )
{
    ComplRefData        aCRD;
    SingleRefData*      pSRD;
    const ScAddress*    pScAddr;

    pSRD = &aCRD.Ref1;
    pScAddr = &aScRange.aStart;
    pSRD->SetFlag3D( TRUE );
    pSRD->nCol = pScAddr->Col();
    pSRD->nRow = pScAddr->Row();
    pSRD->nTab = pScAddr->Tab();

    // zunaechst ALLE Refs nur absolut
    pSRD->SetColRel( FALSE );
    pSRD->SetRowRel( FALSE );
    pSRD->SetTabRel( FALSE );

    pSRD = &aCRD.Ref2;
    pScAddr = &aScRange.aEnd;
    pSRD->SetFlag3D( TRUE );
    pSRD->nCol = pScAddr->Col();
    pSRD->nRow = pScAddr->Row();
    pSRD->nTab = pScAddr->Tab();

    // zunaechst ALLE Refs nur absolut
    pSRD->SetColRel( FALSE );
    pSRD->SetRowRel( FALSE );
    pSRD->SetTabRel( FALSE );

    Add( rName, aCRD );
}

class ExtSheetBuffer : private List, public ExcRoot
{
private:
    struct Cont
        {
        String      aFile;
        String      aTab;
        UINT16      nTabNum;    // 0xFFFF -> noch nicht angelegt
                                // 0xFFFE -> versucht anzulegen, ging aber schief
                                // 0xFFFD -> soll im selben Workbook sein, findet's aber nicht
        BOOL        bSWB;
        BOOL        bLink;
                    Cont( const String& rFilePathAndName, const String& rTabName ) :
                        aFile( rFilePathAndName ),
                        aTab( rTabName )
                    {
                        nTabNum = 0xFFFF;   // -> Tabelle noch nicht erzeugt
                        bSWB = bLink = FALSE;
                    }
                    Cont( const String& rFilePathAndName, const String& rTabName,
                        const BOOL bSameWB ) :
                        aFile( rFilePathAndName ),
                        aTab( rTabName )
                    {
                        nTabNum = 0xFFFF;   // -> Tabelle noch nicht erzeugt
                        bSWB = bSameWB;
                        bLink = FALSE;
                    }
        };
public:
    inline          ExtSheetBuffer( RootData* );
    virtual         ~ExtSheetBuffer();

    void            Add( const String& rFilePathAndName,
                        const String& rTabName, const BOOL bSameWorkbook = FALSE );

    BOOL            GetScTabIndex( UINT16 nExcSheetIndex, UINT16& rIn_LastTab_Out_ScIndex );
    BOOL            IsLink( const UINT16 nExcSheetIndex ) const;
    BOOL            GetLink( const UINT16 nExcSheetIndex, String &rAppl, String &rDoc ) const;
    BOOL            IsExternal( UINT16 nExcSheetIndex ) const;

    void            Reset( void );
};

inline ExtSheetBuffer::ExtSheetBuffer( RootData* p ) : ExcRoot( p )
{
}

struct ExtName
{
    String          aName;
    UINT32          nStorageId;
    UINT16          nFlags;

    inline          ExtName( const String& r ) : aName( r ), nStorageId( 0 ) {}

    BOOL            IsDDE( void ) const;
    BOOL            IsOLE( void ) const;
    BOOL            IsName( void ) const;
};

class ExtNameBuff : private List, protected ExcRoot
{
private:
    static const sal_Char*  pJoostTest;
protected:
public:
    inline          ExtNameBuff( RootData* );
    virtual         ~ExtNameBuff();

    void            AddDDE( const String& rName );
    void            AddOLE( const String& rName, UINT32 nStorageId );
    void            AddName( const String& rName );

    const ExtName*  GetName( const UINT16 nExcelIndex ) const;

    void            Reset( void );
};

inline ExtNameBuff::ExtNameBuff( RootData* p ) : ExcRoot( p )
{
}

#endif

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

#ifndef _NAMEBUFF_HXX
#define _NAMEBUFF_HXX

#ifndef _TOOLS_DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif
#ifndef _STRING_HXX
#include <tools/string.hxx>
#endif

#ifndef SC_COMPILER_HXX
#include "compiler.hxx"
#endif

#ifndef _ROOT_HXX
#include "root.hxx"
#endif

#include "rangenam.hxx"

class ScDocument;
class ScTokenArray;
class NameBuffer;

class StringHashEntry
{
private:
    friend NameBuffer;
    String          aString;
    UINT32          nHash;

    static UINT32   MakeHashCode( const String& );
public:
    inline          StringHashEntry( const String& );
    inline          StringHashEntry( void );
    inline void     operator =( const sal_Char* );
    inline void     operator =( const String& );
    inline void     operator =( const StringHashEntry& );
    inline BOOL     operator ==( const StringHashEntry& ) const;
};

inline StringHashEntry::StringHashEntry( void )
{
}

inline StringHashEntry::StringHashEntry( const String& r ) : aString( r )
{
    nHash = MakeHashCode( r );
}

inline void StringHashEntry::operator =( const sal_Char* p )
{
    aString.AssignAscii( p );
    nHash = MakeHashCode( aString );
}

inline void StringHashEntry::operator =( const String& r )
{
    aString = r;
    nHash = MakeHashCode( r );
}

inline void StringHashEntry::operator =( const StringHashEntry& r )
{
    nHash = r.nHash;
    aString = r.aString;
}

inline BOOL StringHashEntry::operator ==( const StringHashEntry& r ) const
{
    return ( nHash == r.nHash && aString ==  r.aString );
}

class NameBuffer : private List, public ExcRoot
{
private:
    UINT16                  nBase;      // Index-Basis
public:
//    inline                  NameBuffer( void );   //#94039# prevent empty rootdata
    inline                  NameBuffer( RootData* );
    inline                  NameBuffer( RootData*, UINT16 nNewBase );

    virtual                 ~NameBuffer();
    inline const String*    Get( UINT16 nIndex );
    inline UINT16           GetLastIndex( void );
    inline void             SetBase( UINT16 nNewBase = 0 );
    void                    operator <<( const String& rNewString );
    void                    Reset( void );
    BOOL                    Find( const sal_Char* pRefName, UINT16& rIndex );
};

//#94039# prevent empty rootdata
//inline NameBuffer::NameBuffer( void )
//{
//    nBase = 0;
//}

inline NameBuffer::NameBuffer( RootData* p ) : ExcRoot( p )
{
    nBase = 0;
}

inline NameBuffer::NameBuffer( RootData* p, UINT16 nNewBase ) : ExcRoot( p )
{
    nBase = nNewBase;
}

inline const String* NameBuffer::Get( UINT16 n )
{
    if( n < nBase )
        return NULL;
    else
    {
        StringHashEntry* pObj = ( StringHashEntry* ) List::GetObject( n );

        if( pObj )
            return &pObj->aString;
        else
            return NULL;
    }
}

inline UINT16 NameBuffer::GetLastIndex( void )
{
    DBG_ASSERT( Count() + nBase <= 0xFFFF, "*NameBuffer::GetLastIndex(): Ich hab' die Nase voll!" );

    return ( UINT16 ) ( Count() + nBase );
}

inline void NameBuffer::SetBase( UINT16 nNewBase )
{
    nBase = nNewBase;
}

class ShrfmlaBuffer : private List, public ExcRoot
{
private:
    UINT16                  nBase;          // Startwert Indizierung
public:
                            ShrfmlaBuffer( RootData* pRD );
    virtual                 ~ShrfmlaBuffer();
    void                    Store( const ScRange& rRange, const ScTokenArray& );
    UINT16                  Find( const ScAddress aAdress );

    static String           CreateName( const ScRange& );
    static BOOL             GetAddress( const String& rName, ScRange& rReturn );
    };

class RangeNameBufferWK3 : private List
{
private:
    struct ENTRY
        {
        StringHashEntry     aStrHashEntry;
        ComplRefData        aComplRefDataRel;
        String              aScAbsName;
        UINT16              nAbsInd;        // == 0 -> noch keine Abs-Name!
        UINT16              nRelInd;
        BOOL                bSingleRef;
                            ENTRY( const String& rName, const String& rScName, const ComplRefData& rCRD ) :
                                aStrHashEntry( rName ),
                                aComplRefDataRel( rCRD ),
                                aScAbsName( rScName )
                            {
                                nAbsInd = 0;
                                aScAbsName.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "_ABS" ) );
                            }
        };

    ScTokenArray*           pScTokenArray;
    UINT16                  nIntCount;
public:
                            RangeNameBufferWK3( void );
    virtual                 ~RangeNameBufferWK3();
    void                    Add( const String& rName, const ComplRefData& rCRD );
    inline void             Add( const String& rName, const ScRange& aScRange );
    BOOL                    FindRel( const String& rRef, UINT16& rIndex );
    BOOL                    FindAbs( const String& rRef, UINT16& rIndex );
};

inline void RangeNameBufferWK3::Add( const String& rName, const ScRange& aScRange )
{
    ComplRefData        aCRD;
    SingleRefData*      pSRD;
    const ScAddress*    pScAddr;

    pSRD = &aCRD.Ref1;
    pScAddr = &aScRange.aStart;
    pSRD->SetFlag3D( TRUE );
    pSRD->nCol = pScAddr->Col();
    pSRD->nRow = pScAddr->Row();
    pSRD->nTab = pScAddr->Tab();

    // zunaechst ALLE Refs nur absolut
    pSRD->SetColRel( FALSE );
    pSRD->SetRowRel( FALSE );
    pSRD->SetTabRel( FALSE );

    pSRD = &aCRD.Ref2;
    pScAddr = &aScRange.aEnd;
    pSRD->SetFlag3D( TRUE );
    pSRD->nCol = pScAddr->Col();
    pSRD->nRow = pScAddr->Row();
    pSRD->nTab = pScAddr->Tab();

    // zunaechst ALLE Refs nur absolut
    pSRD->SetColRel( FALSE );
    pSRD->SetRowRel( FALSE );
    pSRD->SetTabRel( FALSE );

    Add( rName, aCRD );
}

class ExtSheetBuffer : private List, public ExcRoot
{
private:
    struct Cont
        {
        String      aFile;
        String      aTab;
        UINT16      nTabNum;    // 0xFFFF -> noch nicht angelegt
                                // 0xFFFE -> versucht anzulegen, ging aber schief
                                // 0xFFFD -> soll im selben Workbook sein, findet's aber nicht
        BOOL        bSWB;
        BOOL        bLink;
                    Cont( const String& rFilePathAndName, const String& rTabName ) :
                        aFile( rFilePathAndName ),
                        aTab( rTabName )
                    {
                        nTabNum = 0xFFFF;   // -> Tabelle noch nicht erzeugt
                        bSWB = bLink = FALSE;
                    }
                    Cont( const String& rFilePathAndName, const String& rTabName,
                        const BOOL bSameWB ) :
                        aFile( rFilePathAndName ),
                        aTab( rTabName )
                    {
                        nTabNum = 0xFFFF;   // -> Tabelle noch nicht erzeugt
                        bSWB = bSameWB;
                        bLink = FALSE;
                    }
        };
public:
    inline          ExtSheetBuffer( RootData* );
    virtual         ~ExtSheetBuffer();

    void            Add( const String& rFilePathAndName,
                        const String& rTabName, const BOOL bSameWorkbook = FALSE );

    BOOL            GetScTabIndex( UINT16 nExcSheetIndex, UINT16& rIn_LastTab_Out_ScIndex );
    BOOL            IsLink( const UINT16 nExcSheetIndex ) const;
    BOOL            GetLink( const UINT16 nExcSheetIndex, String &rAppl, String &rDoc ) const;
    BOOL            IsExternal( UINT16 nExcSheetIndex ) const;

    void            Reset( void );
};

inline ExtSheetBuffer::ExtSheetBuffer( RootData* p ) : ExcRoot( p )
{
}

struct ExtName
{
    String          aName;
    UINT32          nStorageId;
    UINT16          nFlags;

    inline          ExtName( const String& r ) : aName( r ), nStorageId( 0 ) {}

    BOOL            IsDDE( void ) const;
    BOOL            IsOLE( void ) const;
    BOOL            IsName( void ) const;
};

class ExtNameBuff : private List, protected ExcRoot
{
private:
    static const sal_Char*  pJoostTest;
protected:
public:
    inline          ExtNameBuff( RootData* );
    virtual         ~ExtNameBuff();

    void            AddDDE( const String& rName );
    void            AddOLE( const String& rName, UINT32 nStorageId );
    void            AddName( const String& rName );

    const ExtName*  GetName( const UINT16 nExcelIndex ) const;

    void            Reset( void );
};

inline ExtNameBuff::ExtNameBuff( RootData* p ) : ExcRoot( p )
{
}

#endif

<|endoftext|>


<commit_before><commit_msg>coverity#1187654 Logically dead code<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pntlock.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 13:45:28 $
 *
 *  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
 *
 ************************************************************************/

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

#include "pntlock.hxx"

//------------------------------------------------------------------------

ScPaintLockData::ScPaintLockData(USHORT nNewMode) :
    nMode( nNewMode ),
    nParts( 0 ),
    nLevel( 0 ),
    nDocLevel( 0 ),
    bModified( FALSE )
{
}

ScPaintLockData::~ScPaintLockData()
{
}

void ScPaintLockData::AddRange( const ScRange& rRange, USHORT nP )
{
    if (!xRangeList.Is())
        xRangeList = new ScRangeList;

    xRangeList->Join( rRange );
    nParts |= nP;
}

<commit_msg>INTEGRATION: CWS calcwarnings (1.4.110); FILE MERGED 2006/12/12 17:03:11 nn 1.4.110.1: #i69284# warning-free: ui, unxlngi6<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: pntlock.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2007-02-27 13:09:30 $
 *
 *  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
 *
 ************************************************************************/

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

#include "pntlock.hxx"

//------------------------------------------------------------------------

ScPaintLockData::ScPaintLockData(USHORT nNewMode) :
    nMode( nNewMode ),
    nLevel( 0 ),
    nDocLevel( 0 ),
    nParts( 0 ),
    bModified( FALSE )
{
}

ScPaintLockData::~ScPaintLockData()
{
}

void ScPaintLockData::AddRange( const ScRange& rRange, USHORT nP )
{
    if (!xRangeList.Is())
        xRangeList = new ScRangeList;

    xRangeList->Join( rRange );
    nParts |= nP;
}

<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
/// @brief line editor using readline
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "ReadlineShell.h"
#include "Utilities/Completer.h"
#include "Utilities/LineEditor.h"

#include <iostream>
#include <readline/readline.h>
#include <readline/history.h>

#include "BasicsC/tri-strings.h"

#include <vector>

#include <v8.h>

using namespace std;
using namespace triagens;

namespace {

  Completer * COMPLETER;

  static char WordBreakCharacters[] = {
    ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
    '<', '>', '=', ';', '|', '&', '{', '}', '(', ')',
    '\0'
  };

  static char* CompletionGenerator (char const* text, int state) {
    static size_t currentIndex;
    static vector<string> result;
    // compute the possible completion
    if(state == 0) {
      COMPLETER->getAlternatives(text, result);
      LineEditor::sortAlternatives(result);
    }

    if (currentIndex < result.size()) {
      return TRI_SystemDuplicateString(result[currentIndex++].c_str());
    }
    else {
      currentIndex = 0;
      result.clear();
      return 0;
    }
  }

  static char** AttemptedCompletion (char const* text, int start, int end) {
    char** result;

    result = rl_completion_matches(text, CompletionGenerator);
    rl_attempted_completion_over = true;

    if (result != 0 && result[0] != 0 && result[1] == 0) {
      size_t n = strlen(result[0]);

      if (result[0][n - 1] == ')') {
        result[0][n - 1] = '\0';
      }
    }

#if RL_READLINE_VERSION >= 0x0500
    // issue #289
    rl_completion_suppress_append = 1;
#endif

    return result;
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                               class ReadlineShell
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new editor
////////////////////////////////////////////////////////////////////////////////

ReadlineShell::ReadlineShell(std::string const& history, Completer *completer)
  : ShellImplementation(history, completer) {

    COMPLETER = completer;

    rl_initialize();

    rl_attempted_completion_function = AttemptedCompletion;
    rl_completer_word_break_characters = WordBreakCharacters;

#ifndef __APPLE__
  rl_catch_signals = 0;
#endif
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief line editor open
////////////////////////////////////////////////////////////////////////////////

bool ReadlineShell::open(bool autoComplete) {
  if (autoComplete) {

    // issue #289: do not append a space after completion
    rl_completion_append_character = '\0';

    // works only in Readline 4.2+
#if RL_READLINE_VERSION >= 0x0500
    // enable this to turn on the visual bell - evil!
    // rl_variable_bind("prefer-visible-bell", "1");

    // use this for single-line editing as in mongodb shell
    // rl_variable_bind("horizontal-scroll-mode", "1");

    // show matching parentheses
    rl_set_paren_blink_timeout(1 * 1000 * 1000);
    rl_variable_bind("blink-matching-paren", "1");

    // show selection list when completion is ambiguous. not setting this
    // variable will turn the selection list off at least on Ubuntu
    rl_variable_bind("show-all-if-ambiguous", "1");

    // use readline's built-in page-wise completer
    rl_variable_bind("page-completions", "1");
#endif

    rl_bind_key('\t', rl_complete);
  }

  using_history();
  //stifle_history(MAX_HISTORY_ENTRIES);
  stifle_history(1000);

  _state = STATE_OPENED;

  return read_history(historyPath().c_str()) == 0;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief line editor shutdown
////////////////////////////////////////////////////////////////////////////////

bool ReadlineShell::close() {
  if (_state != STATE_OPENED) {
    // avoid duplicate saving of history
    return true;
  }

  _state = STATE_CLOSED;

  bool res = writeHistory();

#ifndef __APPLE__
  // reset state of the terminal to what it was before readline()
  rl_cleanup_after_signal();
#endif

  return res;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get the history file path
////////////////////////////////////////////////////////////////////////////////

string ReadlineShell::historyPath() {
  string path;

  if (getenv("HOME")) {
    path.append(getenv("HOME"));
    path += '/';
  }

  path.append(_historyFilename);

  return path;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief add to history
////////////////////////////////////////////////////////////////////////////////

void ReadlineShell::addHistory(char const* str) {
  if (*str == '\0') {
    return;
  }

  history_set_pos(history_length-1);

  if (current_history()) {
    do {
      if (strcmp(current_history()->line, str) == 0) {
        remove_history(where_history());
        break;
      }
    }
    while (previous_history());
  }

  add_history(str);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief save history
////////////////////////////////////////////////////////////////////////////////

bool ReadlineShell::writeHistory() {
  return (write_history(historyPath().c_str()) == 0);
}

char * ReadlineShell::getLine(char const * input) {
  return readline(input);
}
// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<commit_msg>Prevent readline-history memleak.<commit_after>////////////////////////////////////////////////////////////////////////////////
/// @brief line editor using readline
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Dr. Frank Celler
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

#include "ReadlineShell.h"
#include "Utilities/Completer.h"
#include "Utilities/LineEditor.h"

#include <iostream>
#include <readline/readline.h>
#include <readline/history.h>

#include "BasicsC/tri-strings.h"

#include <vector>

#include <v8.h>

using namespace std;
using namespace triagens;

namespace {

  Completer * COMPLETER;

  static char WordBreakCharacters[] = {
    ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
    '<', '>', '=', ';', '|', '&', '{', '}', '(', ')',
    '\0'
  };

  static char* CompletionGenerator (char const* text, int state) {
    static size_t currentIndex;
    static vector<string> result;
    // compute the possible completion
    if(state == 0) {
      COMPLETER->getAlternatives(text, result);
      LineEditor::sortAlternatives(result);
    }

    if (currentIndex < result.size()) {
      return TRI_SystemDuplicateString(result[currentIndex++].c_str());
    }
    else {
      currentIndex = 0;
      result.clear();
      return 0;
    }
  }

  static char** AttemptedCompletion (char const* text, int start, int end) {
    char** result;

    result = rl_completion_matches(text, CompletionGenerator);
    rl_attempted_completion_over = true;

    if (result != 0 && result[0] != 0 && result[1] == 0) {
      size_t n = strlen(result[0]);

      if (result[0][n - 1] == ')') {
        result[0][n - 1] = '\0';
      }
    }

#if RL_READLINE_VERSION >= 0x0500
    // issue #289
    rl_completion_suppress_append = 1;
#endif

    return result;
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                               class ReadlineShell
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// --SECTION--                                      constructors and destructors
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief constructs a new editor
////////////////////////////////////////////////////////////////////////////////

ReadlineShell::ReadlineShell(std::string const& history, Completer *completer)
  : ShellImplementation(history, completer) {

    COMPLETER = completer;

    rl_initialize();

    rl_attempted_completion_function = AttemptedCompletion;
    rl_completer_word_break_characters = WordBreakCharacters;

#ifndef __APPLE__
  rl_catch_signals = 0;
#endif
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    public methods
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief line editor open
////////////////////////////////////////////////////////////////////////////////

bool ReadlineShell::open(bool autoComplete) {
  if (autoComplete) {

    // issue #289: do not append a space after completion
    rl_completion_append_character = '\0';

    // works only in Readline 4.2+
#if RL_READLINE_VERSION >= 0x0500
    // enable this to turn on the visual bell - evil!
    // rl_variable_bind("prefer-visible-bell", "1");

    // use this for single-line editing as in mongodb shell
    // rl_variable_bind("horizontal-scroll-mode", "1");

    // show matching parentheses
    rl_set_paren_blink_timeout(1 * 1000 * 1000);
    rl_variable_bind("blink-matching-paren", "1");

    // show selection list when completion is ambiguous. not setting this
    // variable will turn the selection list off at least on Ubuntu
    rl_variable_bind("show-all-if-ambiguous", "1");

    // use readline's built-in page-wise completer
    rl_variable_bind("page-completions", "1");
#endif

    rl_bind_key('\t', rl_complete);
  }

  using_history();
  //stifle_history(MAX_HISTORY_ENTRIES);
  stifle_history(1000);

  _state = STATE_OPENED;

  return read_history(historyPath().c_str()) == 0;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief line editor shutdown
////////////////////////////////////////////////////////////////////////////////

bool ReadlineShell::close() {
  if (_state != STATE_OPENED) {
    // avoid duplicate saving of history
    return true;
  }

  _state = STATE_CLOSED;

  bool res = writeHistory();

  clear_history();
  HIST_ENTRY** hist = history_list();
  free(hist);

#ifndef __APPLE__
  // reset state of the terminal to what it was before readline()
  rl_cleanup_after_signal();
#endif

  return res;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get the history file path
////////////////////////////////////////////////////////////////////////////////

string ReadlineShell::historyPath() {
  string path;

  if (getenv("HOME")) {
    path.append(getenv("HOME"));
    path += '/';
  }

  path.append(_historyFilename);

  return path;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief add to history
////////////////////////////////////////////////////////////////////////////////

void ReadlineShell::addHistory(char const* str) {
  if (*str == '\0') {
    return;
  }

  history_set_pos(history_length-1);

  if (current_history()) {
    do {
      if (strcmp(current_history()->line, str) == 0) {
        HIST_ENTRY* e = remove_history(where_history());
        free_history_entry(e);
        break;
      }
    }
    while (previous_history());
  }

  add_history(str);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief save history
////////////////////////////////////////////////////////////////////////////////

bool ReadlineShell::writeHistory() {
  return (write_history(historyPath().c_str()) == 0);
}

char * ReadlineShell::getLine(char const * input) {
  return readline(input);
}
// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End:
<|endoftext|>


<commit_before>//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

#include "nf_hardware_stm32_native.h"

HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::ReadBytes___STATIC__VOID__U4__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    NANOCLR_HEADER();

    uint32_t position = stack.Arg0().NumericByRef().u4;

    // dereference the data buffer from the argument
    CLR_RT_HeapBlock_Array* buffer = stack.Arg1().DereferenceArray();
    // get a the pointer to the byffer by using the first element of the array
    uint8_t* data = buffer->GetFirstElement();
    // get the length of the data buffer
    uint32_t dataLength =  buffer->m_numOfElements;

    // address of bkp register 0
     __IO uint32_t* baseAddress = &(RTC->BKP0R);
    uint8_t* storeAddress = ((uint8_t*)baseAddress + position);
    uint32_t* registerAddress = NULL;
    uint32_t tempRegisterValue;
    uint32_t counter = 0;
    uint32_t remainder;
    int32_t index = 3;

    // sanity check for out of range position
    if(position > (BACKUP_SIZE - 1) ) NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

    // sanity check for over sized data buffer
    if( (position + dataLength) > BACKUP_SIZE) NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    // check if the store address is starting at a register address boundary
    remainder = (uint32_t)((uint32_t*)storeAddress) % sizeof(RTC_BKP0R_Msk);

    if(remainder > 0)
    {
        // read register
        registerAddress = (uint32_t*)(storeAddress - remainder);
        tempRegisterValue = *registerAddress;

        // adjust remainder to the amount of bytes to move
        remainder = 4 - remainder;

        do
        {
            *data = (uint8_t)(tempRegisterValue >> ( (remainder - 1) * 8));
            data++;
            remainder--;
            counter++;
        }
        while(remainder && (counter < dataLength));
        registerAddress++;
    }

    // keep reading into the buffer if there enough bytes
    if( (dataLength - counter) >= 4)
    {
        // load register
        tempRegisterValue = *registerAddress;

        do
        {
            *data = (uint8_t)(tempRegisterValue >> (index-- * 8));
            data++;
            counter++;

            if(index < 0)
            {
                index = 3;
                registerAddress++;

                // is there enough data in buffer for another round
                if( (dataLength - counter) < 4)
                {
                    // no, exit loop
                    break;
                }

                // load register
                tempRegisterValue = *registerAddress;
            }
        }
        while(1);
    }

    // now read the remaining bytes, if any
    if((dataLength - counter) > 0)
    {
        remainder = dataLength - counter;

        // read register
        tempRegisterValue = *registerAddress;

        // adjust remainder to the amount of bytes to move
        remainder = 4 - remainder;

        do
        {
            *data = (uint8_t)(tempRegisterValue >> (remainder * 8));
            remainder--;
            data++;
            counter++;
        }
        while(remainder);
    }

    NANOCLR_NOCLEANUP();
}

HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::WriteBytes___STATIC__VOID__U4__SZARRAY_U1( CLR_RT_StackFrame& stack )
{
    NANOCLR_HEADER();

    // get position to write to
    uint32_t position = stack.Arg0().NumericByRef().u4;

    // dereference the data buffer from the argument
    CLR_RT_HeapBlock_Array* buffer = stack.Arg1().DereferenceArray();
    // get a the pointer to the byffer by using the first element of the array
    uint8_t* data = buffer->GetFirstElement();
    // get the length of the data buffer
    uint32_t dataLength =  buffer->m_numOfElements;

    // address of bkp register 0
    __IO uint32_t* baseAddress = &(RTC->BKP0R);
    uint8_t* storeAddress = ((uint8_t*)baseAddress + position);
    uint32_t* registerAddress = NULL;
    uint32_t tempRegisterValue;
    uint32_t counter = 0;
    uint32_t remainder;
    int32_t index = 3;

    // sanity check for out of range position
    if(position > (BACKUP_SIZE - 1) ) NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

    // sanity check for over sized data buffer
    if( (position + dataLength) > BACKUP_SIZE) NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    // write has to be done register wide, so if a write address is "in the middle" of a register, need to read it first and overwrite as required
    // this can happen at the begining and/or at the end of the buffer

    // check if the store address is starting at a register address boundary
    remainder = (uint32_t)((uint32_t*)storeAddress) % sizeof(RTC_BKP0R_Msk);

    if(remainder > 0)
    {
        // read register
        registerAddress = (uint32_t*)(storeAddress - remainder);
        tempRegisterValue = *registerAddress;

        // adjust remainder to the amount of bytes to move
        remainder = 4 - remainder;

        // clear the bytes we'll be filling
        tempRegisterValue &= (uint32_t)(0xFFFFFF00 << ( (remainder - 1) * 8));

        do
        {
            tempRegisterValue |= (uint32_t)((uint32_t)*data << ( (remainder - 1) * 8));
            remainder--;
            data++;
            counter++;
        }
        while(remainder && (counter < dataLength));

        // write back register
        *registerAddress = tempRegisterValue;
        registerAddress++;
    }

    // keep processing the buffer if there enough bytes
    if( (dataLength - counter) >= 4)
    {
        // clear register
        *registerAddress = 0;

        do
        {
            *registerAddress |= (uint32_t)((uint32_t)*data << (index-- * 8));
            data++;
            counter++;

            if(index < 0)
            {
                index = 3;
                registerAddress++;

                // is there enough data in buffer for another round
                if( (dataLength - counter) < 4)
                {
                    // no, exit loop
                    break;
                }

                // clear register
                *registerAddress = 0;
            }
        }
        while(1);
    }

    // take care of the remaining bytes, if any
    if((dataLength - counter) > 0)
    {
        remainder = dataLength - counter;

        // read register
        tempRegisterValue = *registerAddress;

        // clear the bytes we'll be filling
        tempRegisterValue &= (uint32_t)(0x00FFFFFF >> ( (remainder - 1) * 8));

        // adjust remainder to the amount of bytes to move
        remainder = 4 - remainder;

        do
        {
            tempRegisterValue |= (uint32_t)((uint32_t)*data << (remainder * 8));
            remainder--;
            data++;
            counter++;
        }
        while(remainder);

        // write back register
        *registerAddress = tempRegisterValue;
    }

    NANOCLR_NOCLEANUP();
}

HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::GetSize___STATIC__I4( CLR_RT_StackFrame& stack )
{
    NANOCLR_HEADER();

    stack.SetResult_I4(BACKUP_SIZE);

    NANOCLR_NOCLEANUP_NOLABEL();
}
 <commit_msg>Code style fix<commit_after>//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//

#include "nf_hardware_stm32_native.h"

HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::
    ReadBytes___STATIC__VOID__U4__SZARRAY_U1(CLR_RT_StackFrame &stack)
{
    NANOCLR_HEADER();

    uint32_t position = stack.Arg0().NumericByRef().u4;

    // dereference the data buffer from the argument
    CLR_RT_HeapBlock_Array *buffer = stack.Arg1().DereferenceArray();
    // get a the pointer to the byffer by using the first element of the array
    uint8_t *data = buffer->GetFirstElement();
    // get the length of the data buffer
    uint32_t dataLength = buffer->m_numOfElements;

    // address of bkp register 0
    __IO uint32_t *baseAddress = &(RTC->BKP0R);
    uint8_t *storeAddress = ((uint8_t *)baseAddress + position);
    uint32_t *registerAddress = NULL;
    uint32_t tempRegisterValue;
    uint32_t counter = 0;
    uint32_t remainder;
    int32_t index = 3;

    // sanity check for out of range position
    if (position > (BACKUP_SIZE - 1))
        NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

    // sanity check for over sized data buffer
    if ((position + dataLength) > BACKUP_SIZE)
        NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    // check if the store address is starting at a register address boundary
    remainder = (uint32_t)((uint32_t *)storeAddress) % sizeof(RTC_BKP0R_Msk);

    if (remainder > 0)
    {
        // read register
        registerAddress = (uint32_t *)(storeAddress - remainder);
        tempRegisterValue = *registerAddress;

        // adjust remainder to the amount of bytes to move
        remainder = 4 - remainder;

        do
        {
            *data = (uint8_t)(tempRegisterValue >> ((remainder - 1) * 8));
            data++;
            remainder--;
            counter++;
        } while (remainder && (counter < dataLength));
        registerAddress++;
    }

    // keep reading into the buffer if there enough bytes
    if ((dataLength - counter) >= 4)
    {
        // load register
        tempRegisterValue = *registerAddress;

        do
        {
            *data = (uint8_t)(tempRegisterValue >> (index-- * 8));
            data++;
            counter++;

            if (index < 0)
            {
                index = 3;
                registerAddress++;

                // is there enough data in buffer for another round
                if ((dataLength - counter) < 4)
                {
                    // no, exit loop
                    break;
                }

                // load register
                tempRegisterValue = *registerAddress;
            }
        } while (1);
    }

    // now read the remaining bytes, if any
    if ((dataLength - counter) > 0)
    {
        remainder = dataLength - counter;

        // read register
        tempRegisterValue = *registerAddress;

        // adjust remainder to the amount of bytes to move
        remainder = 4 - remainder;

        do
        {
            *data = (uint8_t)(tempRegisterValue >> (remainder * 8));
            remainder--;
            data++;
            counter++;
        } while (remainder);
    }

    NANOCLR_NOCLEANUP();
}

HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::
    WriteBytes___STATIC__VOID__U4__SZARRAY_U1(CLR_RT_StackFrame &stack)
{
    NANOCLR_HEADER();

    // get position to write to
    uint32_t position = stack.Arg0().NumericByRef().u4;

    // dereference the data buffer from the argument
    CLR_RT_HeapBlock_Array *buffer = stack.Arg1().DereferenceArray();
    // get a the pointer to the byffer by using the first element of the array
    uint8_t *data = buffer->GetFirstElement();
    // get the length of the data buffer
    uint32_t dataLength = buffer->m_numOfElements;

    // address of bkp register 0
    __IO uint32_t *baseAddress = &(RTC->BKP0R);
    uint8_t *storeAddress = ((uint8_t *)baseAddress + position);
    uint32_t *registerAddress = NULL;
    uint32_t tempRegisterValue;
    uint32_t counter = 0;
    uint32_t remainder;
    int32_t index = 3;

    // sanity check for out of range position
    if (position > (BACKUP_SIZE - 1))
        NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);

    // sanity check for over sized data buffer
    if ((position + dataLength) > BACKUP_SIZE)
        NANOCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);

    // write has to be done register wide, so if a write address is "in the middle" of a register, need to read it first
    // and overwrite as required this can happen at the begining and/or at the end of the buffer

    // check if the store address is starting at a register address boundary
    remainder = (uint32_t)((uint32_t *)storeAddress) % sizeof(RTC_BKP0R_Msk);

    if (remainder > 0)
    {
        // read register
        registerAddress = (uint32_t *)(storeAddress - remainder);
        tempRegisterValue = *registerAddress;

        // adjust remainder to the amount of bytes to move
        remainder = 4 - remainder;

        // clear the bytes we'll be filling
        tempRegisterValue &= (uint32_t)(0xFFFFFF00 << ((remainder - 1) * 8));

        do
        {
            tempRegisterValue |= (uint32_t)((uint32_t)*data << ((remainder - 1) * 8));
            remainder--;
            data++;
            counter++;
        } while (remainder && (counter < dataLength));

        // write back register
        *registerAddress = tempRegisterValue;
        registerAddress++;
    }

    // keep processing the buffer if there enough bytes
    if ((dataLength - counter) >= 4)
    {
        // clear register
        *registerAddress = 0;

        do
        {
            *registerAddress |= (uint32_t)((uint32_t)*data << (index-- * 8));
            data++;
            counter++;

            if (index < 0)
            {
                index = 3;
                registerAddress++;

                // is there enough data in buffer for another round
                if ((dataLength - counter) < 4)
                {
                    // no, exit loop
                    break;
                }

                // clear register
                *registerAddress = 0;
            }
        } while (1);
    }

    // take care of the remaining bytes, if any
    if ((dataLength - counter) > 0)
    {
        remainder = dataLength - counter;

        // read register
        tempRegisterValue = *registerAddress;

        // clear the bytes we'll be filling
        tempRegisterValue &= (uint32_t)(0x00FFFFFF >> ((remainder - 1) * 8));

        // adjust remainder to the amount of bytes to move
        remainder = 4 - remainder;

        do
        {
            tempRegisterValue |= (uint32_t)((uint32_t)*data << (remainder * 8));
            remainder--;
            data++;
            counter++;
        } while (remainder);

        // write back register
        *registerAddress = tempRegisterValue;
    }

    NANOCLR_NOCLEANUP();
}

HRESULT Library_nf_hardware_stm32_native_nanoFramework_Hardware_Stm32_BackupMemory::GetSize___STATIC__I4(
    CLR_RT_StackFrame &stack)
{
    NANOCLR_HEADER();

    stack.SetResult_I4(BACKUP_SIZE);

    NANOCLR_NOCLEANUP_NOLABEL();
}
<|endoftext|>