<commit_before>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/thread.h"

#include "base/lazy_instance.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/thread_local.h"
#include "base/waitable_event.h"

namespace base {

// This task is used to trigger the message loop to exit.
class ThreadQuitTask : public Task {
 public:
  virtual void Run() {
    MessageLoop::current()->Quit();
    Thread::SetThreadWasQuitProperly(true);
  }
};

// Used to pass data to ThreadMain.  This structure is allocated on the stack
// from within StartWithOptions.
struct Thread::StartupData {
  // We get away with a const reference here because of how we are allocated.
  const Thread::Options& options;

  // Used to synchronize thread startup.
  WaitableEvent event;

  explicit StartupData(const Options& opt)
      : options(opt),
        event(false, false) {}
};

Thread::Thread(const char* name)
    : started_(false),
      stopping_(false),
      startup_data_(NULL),
      thread_(0),
      message_loop_(NULL),
      thread_id_(0),
      name_(name) {
}

Thread::~Thread() {
  Stop();
}

namespace {

// We use this thread-local variable to record whether or not a thread exited
// because its Stop method was called.  This allows us to catch cases where
// MessageLoop::Quit() is called directly, which is unexpected when using a
// Thread to setup and run a MessageLoop.
base::LazyInstance<base::ThreadLocalBoolean> lazy_tls_bool(
    base::LINKER_INITIALIZED);

}  // namespace

void Thread::SetThreadWasQuitProperly(bool flag) {
  lazy_tls_bool.Pointer()->Set(flag);
}

bool Thread::GetThreadWasQuitProperly() {
  bool quit_properly = true;
#ifndef NDEBUG
  quit_properly = lazy_tls_bool.Pointer()->Get();
#endif
  return quit_properly;
}

bool Thread::Start() {
  return StartWithOptions(Options());
}

bool Thread::StartWithOptions(const Options& options) {
  DCHECK(!message_loop_);

  SetThreadWasQuitProperly(false);

  StartupData startup_data(options);
  startup_data_ = &startup_data;

  if (!PlatformThread::Create(options.stack_size, this, &thread_)) {
    DLOG(ERROR) << "failed to create thread";
    startup_data_ = NULL;
    return false;
  }

  // Wait for the thread to start and initialize message_loop_
  startup_data.event.Wait();

  // set it to NULL so we don't keep a pointer to some object on the stack.
  startup_data_ = NULL;
  started_ = true;

  DCHECK(message_loop_);
  return true;
}

void Thread::Stop() {
  if (!thread_was_started())
    return;

  StopSoon();

  // Wait for the thread to exit.
  //
  // TODO(darin): Unfortunately, we need to keep message_loop_ around until
  // the thread exits.  Some consumers are abusing the API.  Make them stop.
  //
  PlatformThread::Join(thread_);

  // The thread should NULL message_loop_ on exit.
  DCHECK(!message_loop_);

  // The thread no longer needs to be joined.
  started_ = false;

  stopping_ = false;
}

void Thread::StopSoon() {
  // We should only be called on the same thread that started us.

  // Reading thread_id_ without a lock can lead to a benign data race
  // with ThreadMain, so we annotate it to stay silent under ThreadSanitizer.
  DCHECK_NE(ANNOTATE_UNPROTECTED_READ(thread_id_), PlatformThread::CurrentId());

  if (stopping_ || !message_loop_)
    return;

  stopping_ = true;
  message_loop_->PostTask(FROM_HERE, new ThreadQuitTask());
}

#if defined(OS_WIN)
#pragma warning (disable: 4748)
#pragma optimize( "", off )
#endif

void Thread::Run(MessageLoop* message_loop) {
#if defined(OS_WIN)
  // Logging the thread name for debugging.
  // TODO(huanr): remove after done.
  // http://code.google.com/p/chromium/issues/detail?id=54307
  char name[16];
  strncpy(name, name_.c_str(), arraysize(name) - 1);
  name[arraysize(name) - 1] = '\0';
#endif
  message_loop->Run();
}

#if defined(OS_WIN)
#pragma optimize( "", on )
#pragma warning (default: 4748)
#endif

void Thread::ThreadMain() {
  {
    // The message loop for this thread.
    MessageLoop message_loop(startup_data_->options.message_loop_type);

    // Complete the initialization of our Thread object.
    thread_id_ = PlatformThread::CurrentId();
    PlatformThread::SetName(name_.c_str());
    ANNOTATE_THREAD_NAME(name_.c_str());  // Tell the name to race detector.
    message_loop.set_thread_name(name_);
    message_loop_ = &message_loop;
    message_loop_proxy_ = MessageLoopProxy::CreateForCurrentThread();

    // Let the thread do extra initialization.
    // Let's do this before signaling we are started.
    Init();

    startup_data_->event.Signal();
    // startup_data_ can't be touched anymore since the starting thread is now
    // unlocked.

    Run(message_loop_);

    // Let the thread do extra cleanup.
    CleanUp();

    // Assert that MessageLoop::Quit was called by ThreadQuitTask.
    DCHECK(GetThreadWasQuitProperly());

    // We can't receive messages anymore.
    message_loop_ = NULL;
    message_loop_proxy_ = NULL;
  }
  CleanUpAfterMessageLoopDestruction();
  thread_id_ = 0;
}

}  // namespace base
<commit_msg>Revert 58786 - Adding debugging info for thread name.<commit_after>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/thread.h"

#include "base/lazy_instance.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/thread_local.h"
#include "base/waitable_event.h"

namespace base {

// This task is used to trigger the message loop to exit.
class ThreadQuitTask : public Task {
 public:
  virtual void Run() {
    MessageLoop::current()->Quit();
    Thread::SetThreadWasQuitProperly(true);
  }
};

// Used to pass data to ThreadMain.  This structure is allocated on the stack
// from within StartWithOptions.
struct Thread::StartupData {
  // We get away with a const reference here because of how we are allocated.
  const Thread::Options& options;

  // Used to synchronize thread startup.
  WaitableEvent event;

  explicit StartupData(const Options& opt)
      : options(opt),
        event(false, false) {}
};

Thread::Thread(const char* name)
    : started_(false),
      stopping_(false),
      startup_data_(NULL),
      thread_(0),
      message_loop_(NULL),
      thread_id_(0),
      name_(name) {
}

Thread::~Thread() {
  Stop();
}

namespace {

// We use this thread-local variable to record whether or not a thread exited
// because its Stop method was called.  This allows us to catch cases where
// MessageLoop::Quit() is called directly, which is unexpected when using a
// Thread to setup and run a MessageLoop.
base::LazyInstance<base::ThreadLocalBoolean> lazy_tls_bool(
    base::LINKER_INITIALIZED);

}  // namespace

void Thread::SetThreadWasQuitProperly(bool flag) {
  lazy_tls_bool.Pointer()->Set(flag);
}

bool Thread::GetThreadWasQuitProperly() {
  bool quit_properly = true;
#ifndef NDEBUG
  quit_properly = lazy_tls_bool.Pointer()->Get();
#endif
  return quit_properly;
}

bool Thread::Start() {
  return StartWithOptions(Options());
}

bool Thread::StartWithOptions(const Options& options) {
  DCHECK(!message_loop_);

  SetThreadWasQuitProperly(false);

  StartupData startup_data(options);
  startup_data_ = &startup_data;

  if (!PlatformThread::Create(options.stack_size, this, &thread_)) {
    DLOG(ERROR) << "failed to create thread";
    startup_data_ = NULL;
    return false;
  }

  // Wait for the thread to start and initialize message_loop_
  startup_data.event.Wait();

  // set it to NULL so we don't keep a pointer to some object on the stack.
  startup_data_ = NULL;
  started_ = true;

  DCHECK(message_loop_);
  return true;
}

void Thread::Stop() {
  if (!thread_was_started())
    return;

  StopSoon();

  // Wait for the thread to exit.
  //
  // TODO(darin): Unfortunately, we need to keep message_loop_ around until
  // the thread exits.  Some consumers are abusing the API.  Make them stop.
  //
  PlatformThread::Join(thread_);

  // The thread should NULL message_loop_ on exit.
  DCHECK(!message_loop_);

  // The thread no longer needs to be joined.
  started_ = false;

  stopping_ = false;
}

void Thread::StopSoon() {
  // We should only be called on the same thread that started us.

  // Reading thread_id_ without a lock can lead to a benign data race
  // with ThreadMain, so we annotate it to stay silent under ThreadSanitizer.
  DCHECK_NE(ANNOTATE_UNPROTECTED_READ(thread_id_), PlatformThread::CurrentId());

  if (stopping_ || !message_loop_)
    return;

  stopping_ = true;
  message_loop_->PostTask(FROM_HERE, new ThreadQuitTask());
}

void Thread::Run(MessageLoop* message_loop) {
  message_loop->Run();
}

void Thread::ThreadMain() {
  {
    // The message loop for this thread.
    MessageLoop message_loop(startup_data_->options.message_loop_type);

    // Complete the initialization of our Thread object.
    thread_id_ = PlatformThread::CurrentId();
    PlatformThread::SetName(name_.c_str());
    ANNOTATE_THREAD_NAME(name_.c_str());  // Tell the name to race detector.
    message_loop.set_thread_name(name_);
    message_loop_ = &message_loop;
    message_loop_proxy_ = MessageLoopProxy::CreateForCurrentThread();

    // Let the thread do extra initialization.
    // Let's do this before signaling we are started.
    Init();

    startup_data_->event.Signal();
    // startup_data_ can't be touched anymore since the starting thread is now
    // unlocked.

    Run(message_loop_);

    // Let the thread do extra cleanup.
    CleanUp();

    // Assert that MessageLoop::Quit was called by ThreadQuitTask.
    DCHECK(GetThreadWasQuitProperly());

    // We can't receive messages anymore.
    message_loop_ = NULL;
    message_loop_proxy_ = NULL;
  }
  CleanUpAfterMessageLoopDestruction();
  thread_id_ = 0;
}

}  // namespace base
<|endoftext|>


<commit_before>/*
 * Copyright 2019 The Open GEE Contributors
 *
 * 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 "StateUpdater.h"
#include "AssetVersionD.h"
#include "common/notify.h"

using namespace boost;
using namespace std;

// The depth_first_search function needs a way to map vertices to indexes. We
// store a unique index inside each vertex; the code below provides a way for
// boost to access them. These must be defined before including
// depth_first_search.hpp.
template <class Graph>
class InNodeVertexIndexMap {
  public:
    typedef readable_property_map_tag category;
    typedef size_t value_type;
    typedef value_type reference;
    typedef typename Graph::vertex_descriptor key_type;

    InNodeVertexIndexMap(const Graph & graph) : graph(graph) {};
    const Graph & graph;
};

namespace boost {
  template<>
  struct property_map<StateUpdater::TreeType, vertex_index_t> {
    typedef InNodeVertexIndexMap<StateUpdater::TreeType> const_type;
  };

  template<class Graph>
  InNodeVertexIndexMap<Graph> get(vertex_index_t, const Graph & graph) {
    return InNodeVertexIndexMap<Graph>(graph);
  }

  template<class Graph>
  typename InNodeVertexIndexMap<Graph>::value_type get(
      const InNodeVertexIndexMap<Graph> & map,
      typename InNodeVertexIndexMap<Graph>::key_type vertex) {
    return map.graph[vertex].index;
  }
}

#include <boost/graph/depth_first_search.hpp>

// Builds the asset version tree containing the specified asset version.
StateUpdater::TreeType::vertex_descriptor
StateUpdater::BuildTree(const SharedString & ref) {
  VertexMap vertices;
  size_t index = 0;
  list<TreeType::vertex_descriptor> toFillIn, toFillInNext;
  // First create an empty vertex for the provided asset. Then fill it in,
  // which includes adding its connections to other assets. Every time we fill
  // in a node we will get new assets to add to the tree until all assets have
  // been added. This basically builds the tree using a breadth first search,
  // which allows us to keep memory usage (relatively) low by not forcing
  // assets to stay in the cache and limiting the size of the toFillIn and
  // toFillInNext lists.
  auto myVertex = AddEmptyVertex(ref, vertices, index, toFillIn);
  while (toFillIn.size() > 0) {
    for (auto vertex : toFillIn) {
      FillInVertex(vertex, vertices, index, toFillInNext);
    }
    toFillIn = std::move(toFillInNext);
    toFillInNext.clear();
  }
  return myVertex;
}

// Creates an "empty" node for this asset if it has not already been added to
// the tree. The node has a default state and doesn't include links to
// inputs/children/etc. The vertex must be "filled in" by calling FillInVertex
// before it can be used.
StateUpdater::TreeType::vertex_descriptor
StateUpdater::AddEmptyVertex(
    const SharedString & ref,
    VertexMap & vertices,
    size_t & index,
    list<TreeType::vertex_descriptor> & toFillIn) {
  auto myVertexIter = vertices.find(ref);
  if (myVertexIter == vertices.end()) {
    // I'm not in the graph yet, so make a new empty vertex and let the caller
    // know we need to load it with the correct information
    auto myVertex = add_vertex(tree);
    tree[myVertex] = {ref, AssetDefs::New, index};
    ++index;
    vertices[ref] = myVertex;
    toFillIn.push_back(myVertex);
    return myVertex;
  }
  else {
    // I'm already in the graph, so just return my vertex descriptor.
    return myVertexIter->second;
  }
}

// "Fills in" an existing vertex with the state of an asset and its connections
// to other assets. Adds any new nodes that need to be filled in to toFillIn.
void StateUpdater::FillInVertex(
    TreeType::vertex_descriptor myVertex,
    VertexMap & vertices,
    size_t & index,
    list<TreeType::vertex_descriptor> & toFillIn) {
  SharedString name = tree[myVertex].name;
  notify(NFY_PROGRESS, "Loading '%s' for state update", name.toString().c_str());
  AssetVersionD version(name);
  if (!version) {
    notify(NFY_WARN, "Could not load asset '%s' which is referenced by another asset.",
           name.toString().c_str());
    // Set it to a bad state, but use a state that can be fixed by another
    // rebuild operation.
    tree[myVertex].state = AssetDefs::Blocked;
    return;
  }
  tree[myVertex].state = version->state;
  vector<SharedString> dependents;
  version->DependentChildren(dependents);
  for (const auto & dep : dependents) {
    auto depVertex = AddEmptyVertex(dep, vertices, index, toFillIn);
    AddEdge(myVertex, depVertex, {DEPENDENT});
  }
  for (const auto & child : version->children) {
    auto childVertex = AddEmptyVertex(child, vertices, index, toFillIn);
    AddEdge(myVertex, childVertex, {CHILD});
  }
  for (const auto & input : version->inputs) {
    auto inputVertex = AddEmptyVertex(input, vertices, index, toFillIn);
    AddEdge(myVertex, inputVertex, {INPUT});
  }
  for (const auto & parent : version->parents) {
    auto parentVertex = AddEmptyVertex(parent, vertices, index, toFillIn);
    AddEdge(parentVertex, myVertex, {CHILD});
  }
  for (const auto & listener : version->listeners) {
    auto listenerVertex = AddEmptyVertex(listener, vertices, index, toFillIn);
    AddEdge(listenerVertex, myVertex, {INPUT});
  }
}

void StateUpdater::AddEdge(
    TreeType::vertex_descriptor from,
    TreeType::vertex_descriptor to,
    AssetEdge data) {
  auto edgeData = add_edge(from, to, tree);
  if (edgeData.second) {
    // This is a new edge
    tree[edgeData.first] = data;
  }
  else {
    // Check if this is both a dependent and a child
    DependencyType currentType = tree[edgeData.first].type;
    DependencyType newType = data.type;
    if ((currentType == DEPENDENT && newType == CHILD) ||
        (currentType == CHILD && newType == DEPENDENT)) {
      tree[edgeData.first].type = DEPENDENT_AND_CHILD;
    }
  }
}

void StateUpdater::SetStateForRefAndDependents(
    const SharedString & ref,
    AssetDefs::State newState,
    function<bool(AssetDefs::State)> updateStatePredicate) {
  auto refVertex = BuildTree(ref);
  SetStateForVertexAndDependents(refVertex, newState, updateStatePredicate);
}

// Sets the state for the specified ref and recursively sets the state for
// the ref's dependent children.
void StateUpdater::SetStateForVertexAndDependents(
    TreeType::vertex_descriptor vertex,
    AssetDefs::State newState,
    function<bool(AssetDefs::State)> updateStatePredicate) {
  if (updateStatePredicate(tree[vertex].state)) {
    // Set the state. The OnStateChange handler will take care
    // of stopping any running tasks, etc
    // false -> don't send notifications about the new state because we
    // will change it soon.
    SetState(vertex, newState, false);

    // Now update the dependent children
    auto edgeIters = out_edges(vertex, tree);
    auto edgeBegin = edgeIters.first;
    auto edgeEnd = edgeIters.second;
    for (auto i = edgeBegin; i != edgeEnd; ++i) {
      if (IsDependent(tree[*i].type)) {
        SetStateForVertexAndDependents(target(*i, tree), newState, updateStatePredicate);
      }
    }
  }
}

void StateUpdater::SetState(
    TreeType::vertex_descriptor vertex,
    AssetDefs::State newState,
    bool sendNotifications) {
  SharedString name = tree[vertex].name;
  if (newState != tree[vertex].state) {
    MutableAssetVersionD version(name);
    notify(NFY_PROGRESS, "Setting state of '%s' to '%s'",
           name.toString().c_str(), ToString(newState).c_str());
    if (version) {
      // Set the state. The OnStateChange handler will take care
      // of stopping any running tasks, etc.
      // This call does not propagate the state change to other assets. We will
      // take care of that inside the state updater.
      version->SetMyStateOnly(newState, sendNotifications);
      // Setting the state can trigger additional state changes, so get the new
      // state directly from the asset version.
      tree[vertex].state = version->state;
    }
    else {
      // This shoud never happen - we had to successfully load the asset
      // previously to get it into the tree.
      notify(NFY_WARN, "Could not load asset '%s' to set state.",
             name.toString().c_str());
    }
  }
}

// Helper class to calculate the state of asset versions based on the states
// of their inputs and children. It calculates states in depth-first order;
// we use the finish_vertex function to ensure that we calculate the state
// of an asset version after we've calculated the states of its inputs
// and children.
class StateUpdater::UpdateStateVisitor : public default_dfs_visitor {
  private:
    // Keep a pointer to the state updater
    StateUpdater * const updater;

    // Helper class for calculating state from inputs
    class InputStates {
      private:
        uint numinputs = 0;
        uint numgood = 0;
        uint numblocking = 0;
        uint numoffline = 0;
      public:
        void Add(AssetDefs::State inputState) {
          ++numinputs;
          if (inputState == AssetDefs::Succeeded) {
            ++numgood;
          } else if (inputState == AssetDefs::Offline) {
            ++numblocking;
            ++numoffline;
          } else if (inputState & (AssetDefs::Blocked |
                                   AssetDefs::Failed |
                                   AssetDefs::Canceled |
                                   AssetDefs::Bad)) {
            ++numblocking;
          }
        }
        void GetOutputs(AssetDefs::State & stateByInputs, bool & blockersAreOffline, uint32 & numWaitingFor) {
          if (numinputs == numgood) {
            stateByInputs = AssetDefs::Queued;
          } else if (numblocking) {
            stateByInputs = AssetDefs::Blocked;
          } else {
            stateByInputs = AssetDefs::Waiting;
          }

          blockersAreOffline = (numblocking == numoffline);

          if (stateByInputs == AssetDefs::Waiting) {
            numWaitingFor = (numinputs - numgood);
          } else {
            numWaitingFor = 0;
          }
        }
    };
    // Helper class for calculating state from children
    class ChildStates {
      private:
        uint numkids = 0;
        uint numgood = 0;
        uint numblocking = 0;
        uint numinprog = 0;
        uint numfailed = 0;
      public:
        void Add(AssetDefs::State childState) {
          ++numkids;
          if (childState == AssetDefs::Succeeded) {
            ++numgood;
          } else if (childState == AssetDefs::Failed) {
            ++numfailed;
          } else if (childState == AssetDefs::InProgress) {
            ++numinprog;
          } else if (childState & (AssetDefs::Blocked  |
                                   AssetDefs::Canceled |
                                   AssetDefs::Offline  |
                                   AssetDefs::Bad)) {
            ++numblocking;
          }
        }
        void GetOutputs(AssetDefs::State & stateByChildren) {
          if (numkids == numgood) {
            stateByChildren = AssetDefs::Succeeded;
          } else if (numblocking || numfailed) {
            stateByChildren = AssetDefs::Blocked;
          } else if (numgood || numinprog) {
            stateByChildren = AssetDefs::InProgress;
          } else {
            stateByChildren = AssetDefs::Queued;
          }
        }
    };

    // Loops through the inputs and children of an asset and calculates
    // everything the asset verion needs to know to figure out its state. This
    // data will be passed to the asset version so it can calculate its own
    // state.
    void CalculateStateParameters(
        StateUpdater::TreeType::vertex_descriptor vertex,
        const StateUpdater::TreeType & tree,
        AssetDefs::State &stateByInputs,
        AssetDefs::State &stateByChildren,
        bool & blockersAreOffline,
        uint32 & numWaitingFor) const {
      InputStates inputStates;
      ChildStates childStates;

      auto edgeIters = out_edges(vertex, tree);
      auto edgeBegin = edgeIters.first;
      auto edgeEnd = edgeIters.second;
      for (auto i = edgeBegin; i != edgeEnd; ++i) {
        StateUpdater::DependencyType type = tree[*i].type;
        StateUpdater::TreeType::vertex_descriptor dep = target(*i, tree);
        AssetDefs::State depState = tree[dep].state;
        switch(type) {
          case StateUpdater::INPUT:
            inputStates.Add(depState);
            break;
          case StateUpdater::CHILD:
          case StateUpdater::DEPENDENT_AND_CHILD:
            childStates.Add(depState);
            break;
          case StateUpdater::DEPENDENT:
            // Dependents that are not also children are not considered when
            // calculating state.
            break;
        }
      }

      inputStates.GetOutputs(stateByInputs, blockersAreOffline, numWaitingFor);
      childStates.GetOutputs(stateByChildren);
    }
  public:
    UpdateStateVisitor(StateUpdater * updater) : updater(updater) {};

    // Update the state of an asset after we've updated the state of its
    // inputs and children.
    virtual void finish_vertex(
        StateUpdater::TreeType::vertex_descriptor vertex,
        const StateUpdater::TreeType & tree) const {
      SharedString name = tree[vertex].name;
      notify(NFY_PROGRESS, "Calculating state for '%s'", name.toString().c_str());
      AssetVersionD version(name);
      if (!version) {
        // This shoud never happen - we had to successfully load the asset
        // previously to get it into the tree.
        notify(NFY_WARN, "Could not load asset '%s' to recalculate state.",
               name.toString().c_str());
        return;
      }
      if (!version->NeedComputeState()) return;
      AssetDefs::State stateByInputs;
      AssetDefs::State stateByChildren;
      bool blockersAreOffline;
      uint32 numWaitingFor;
      CalculateStateParameters(vertex, tree, stateByInputs, stateByChildren, blockersAreOffline, numWaitingFor);
      AssetDefs::State newState =
          version->CalcStateByInputsAndChildren(stateByInputs, stateByChildren, blockersAreOffline, numWaitingFor);
      // Set the state and send notifications.
      updater->SetState(vertex, newState, true);
    }
};

void StateUpdater::RecalculateAndSaveStates() {
  // Traverse the state tree, recalculate states, and update states as needed.
  // State is calculated for each vertex in the tree after state is calculated
  // for all of its child and input vertices.
  // Possible optimization: Many assets have significant overlap in their
  // inputs. It might save time if we could calculate the overlapping state
  // only once.
  depth_first_search(tree, visitor(UpdateStateVisitor(this)));
}
<commit_msg>Always use the correct version ref<commit_after>/*
 * Copyright 2019 The Open GEE Contributors
 *
 * 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 "StateUpdater.h"
#include "AssetVersionD.h"
#include "common/notify.h"

using namespace boost;
using namespace std;

// The depth_first_search function needs a way to map vertices to indexes. We
// store a unique index inside each vertex; the code below provides a way for
// boost to access them. These must be defined before including
// depth_first_search.hpp.
template <class Graph>
class InNodeVertexIndexMap {
  public:
    typedef readable_property_map_tag category;
    typedef size_t value_type;
    typedef value_type reference;
    typedef typename Graph::vertex_descriptor key_type;

    InNodeVertexIndexMap(const Graph & graph) : graph(graph) {};
    const Graph & graph;
};

namespace boost {
  template<>
  struct property_map<StateUpdater::TreeType, vertex_index_t> {
    typedef InNodeVertexIndexMap<StateUpdater::TreeType> const_type;
  };

  template<class Graph>
  InNodeVertexIndexMap<Graph> get(vertex_index_t, const Graph & graph) {
    return InNodeVertexIndexMap<Graph>(graph);
  }

  template<class Graph>
  typename InNodeVertexIndexMap<Graph>::value_type get(
      const InNodeVertexIndexMap<Graph> & map,
      typename InNodeVertexIndexMap<Graph>::key_type vertex) {
    return map.graph[vertex].index;
  }
}

#include <boost/graph/depth_first_search.hpp>

// Builds the asset version tree containing the specified asset version.
StateUpdater::TreeType::vertex_descriptor
StateUpdater::BuildTree(const SharedString & ref) {
  VertexMap vertices;
  size_t index = 0;
  list<TreeType::vertex_descriptor> toFillIn, toFillInNext;
  // First create an empty vertex for the provided asset. Then fill it in,
  // which includes adding its connections to other assets. Every time we fill
  // in a node we will get new assets to add to the tree until all assets have
  // been added. This basically builds the tree using a breadth first search,
  // which allows us to keep memory usage (relatively) low by not forcing
  // assets to stay in the cache and limiting the size of the toFillIn and
  // toFillInNext lists.
  auto myVertex = AddEmptyVertex(ref, vertices, index, toFillIn);
  while (toFillIn.size() > 0) {
    for (auto vertex : toFillIn) {
      FillInVertex(vertex, vertices, index, toFillInNext);
    }
    toFillIn = std::move(toFillInNext);
    toFillInNext.clear();
  }
  return myVertex;
}

// Creates an "empty" node for this asset if it has not already been added to
// the tree. The node has a default state and doesn't include links to
// inputs/children/etc. The vertex must be "filled in" by calling FillInVertex
// before it can be used.
StateUpdater::TreeType::vertex_descriptor
StateUpdater::AddEmptyVertex(
    const SharedString & ref,
    VertexMap & vertices,
    size_t & index,
    list<TreeType::vertex_descriptor> & toFillIn) {
  auto myVertexIter = vertices.find(ref);
  if (myVertexIter == vertices.end()) {
    // I'm not in the graph yet, so make a new empty vertex and let the caller
    // know we need to load it with the correct information
    auto myVertex = add_vertex(tree);
    tree[myVertex] = {ref, AssetDefs::New, index};
    ++index;
    vertices[ref] = myVertex;
    toFillIn.push_back(myVertex);
    return myVertex;
  }
  else {
    // I'm already in the graph, so just return my vertex descriptor.
    return myVertexIter->second;
  }
}

// "Fills in" an existing vertex with the state of an asset and its connections
// to other assets. Adds any new nodes that need to be filled in to toFillIn.
void StateUpdater::FillInVertex(
    TreeType::vertex_descriptor myVertex,
    VertexMap & vertices,
    size_t & index,
    list<TreeType::vertex_descriptor> & toFillIn) {
  SharedString name = tree[myVertex].name;
  notify(NFY_PROGRESS, "Loading '%s' for state update", name.toString().c_str());
  AssetVersionD version(name);
  if (!version) {
    notify(NFY_WARN, "Could not load asset '%s' which is referenced by another asset.",
           name.toString().c_str());
    // Set it to a bad state, but use a state that can be fixed by another
    // rebuild operation.
    tree[myVertex].state = AssetDefs::Blocked;
    return;
  }
  tree[myVertex].state = version->state;
  // The ref passed in may be slightly different than the ref used in the storage
  // manager, so fix that here.
  if (name != version->GetRef()) {
    name = version->GetRef();
    tree[myVertex].name = name;
    vertices[name] = myVertex;
  }
  vector<SharedString> dependents;
  version->DependentChildren(dependents);
  for (const auto & dep : dependents) {
    auto depVertex = AddEmptyVertex(dep, vertices, index, toFillIn);
    AddEdge(myVertex, depVertex, {DEPENDENT});
  }
  for (const auto & child : version->children) {
    auto childVertex = AddEmptyVertex(child, vertices, index, toFillIn);
    AddEdge(myVertex, childVertex, {CHILD});
  }
  for (const auto & input : version->inputs) {
    auto inputVertex = AddEmptyVertex(input, vertices, index, toFillIn);
    AddEdge(myVertex, inputVertex, {INPUT});
  }
  for (const auto & parent : version->parents) {
    auto parentVertex = AddEmptyVertex(parent, vertices, index, toFillIn);
    AddEdge(parentVertex, myVertex, {CHILD});
  }
  for (const auto & listener : version->listeners) {
    auto listenerVertex = AddEmptyVertex(listener, vertices, index, toFillIn);
    AddEdge(listenerVertex, myVertex, {INPUT});
  }
}

void StateUpdater::AddEdge(
    TreeType::vertex_descriptor from,
    TreeType::vertex_descriptor to,
    AssetEdge data) {
  auto edgeData = add_edge(from, to, tree);
  if (edgeData.second) {
    // This is a new edge
    tree[edgeData.first] = data;
  }
  else {
    // Check if this is both a dependent and a child
    DependencyType currentType = tree[edgeData.first].type;
    DependencyType newType = data.type;
    if ((currentType == DEPENDENT && newType == CHILD) ||
        (currentType == CHILD && newType == DEPENDENT)) {
      tree[edgeData.first].type = DEPENDENT_AND_CHILD;
    }
  }
}

void StateUpdater::SetStateForRefAndDependents(
    const SharedString & ref,
    AssetDefs::State newState,
    function<bool(AssetDefs::State)> updateStatePredicate) {
  SharedString verref = AssetVersionRef::Bind(ref);
  auto refVertex = BuildTree(verref);
  SetStateForVertexAndDependents(refVertex, newState, updateStatePredicate);
}

// Sets the state for the specified ref and recursively sets the state for
// the ref's dependent children.
void StateUpdater::SetStateForVertexAndDependents(
    TreeType::vertex_descriptor vertex,
    AssetDefs::State newState,
    function<bool(AssetDefs::State)> updateStatePredicate) {
  if (updateStatePredicate(tree[vertex].state)) {
    // Set the state. The OnStateChange handler will take care
    // of stopping any running tasks, etc
    // false -> don't send notifications about the new state because we
    // will change it soon.
    SetState(vertex, newState, false);

    // Now update the dependent children
    auto edgeIters = out_edges(vertex, tree);
    auto edgeBegin = edgeIters.first;
    auto edgeEnd = edgeIters.second;
    for (auto i = edgeBegin; i != edgeEnd; ++i) {
      if (IsDependent(tree[*i].type)) {
        SetStateForVertexAndDependents(target(*i, tree), newState, updateStatePredicate);
      }
    }
  }
}

void StateUpdater::SetState(
    TreeType::vertex_descriptor vertex,
    AssetDefs::State newState,
    bool sendNotifications) {
  SharedString name = tree[vertex].name;
  if (newState != tree[vertex].state) {
    MutableAssetVersionD version(name);
    notify(NFY_PROGRESS, "Setting state of '%s' to '%s'",
           name.toString().c_str(), ToString(newState).c_str());
    if (version) {
      // Set the state. The OnStateChange handler will take care
      // of stopping any running tasks, etc.
      // This call does not propagate the state change to other assets. We will
      // take care of that inside the state updater.
      version->SetMyStateOnly(newState, sendNotifications);
      // Setting the state can trigger additional state changes, so get the new
      // state directly from the asset version.
      tree[vertex].state = version->state;
    }
    else {
      // This shoud never happen - we had to successfully load the asset
      // previously to get it into the tree.
      notify(NFY_WARN, "Could not load asset '%s' to set state.",
             name.toString().c_str());
    }
  }
}

// Helper class to calculate the state of asset versions based on the states
// of their inputs and children. It calculates states in depth-first order;
// we use the finish_vertex function to ensure that we calculate the state
// of an asset version after we've calculated the states of its inputs
// and children.
class StateUpdater::UpdateStateVisitor : public default_dfs_visitor {
  private:
    // Keep a pointer to the state updater
    StateUpdater * const updater;

    // Helper class for calculating state from inputs
    class InputStates {
      private:
        uint numinputs = 0;
        uint numgood = 0;
        uint numblocking = 0;
        uint numoffline = 0;
      public:
        void Add(AssetDefs::State inputState) {
          ++numinputs;
          if (inputState == AssetDefs::Succeeded) {
            ++numgood;
          } else if (inputState == AssetDefs::Offline) {
            ++numblocking;
            ++numoffline;
          } else if (inputState & (AssetDefs::Blocked |
                                   AssetDefs::Failed |
                                   AssetDefs::Canceled |
                                   AssetDefs::Bad)) {
            ++numblocking;
          }
        }
        void GetOutputs(AssetDefs::State & stateByInputs, bool & blockersAreOffline, uint32 & numWaitingFor) {
          if (numinputs == numgood) {
            stateByInputs = AssetDefs::Queued;
          } else if (numblocking) {
            stateByInputs = AssetDefs::Blocked;
          } else {
            stateByInputs = AssetDefs::Waiting;
          }

          blockersAreOffline = (numblocking == numoffline);

          if (stateByInputs == AssetDefs::Waiting) {
            numWaitingFor = (numinputs - numgood);
          } else {
            numWaitingFor = 0;
          }
        }
    };
    // Helper class for calculating state from children
    class ChildStates {
      private:
        uint numkids = 0;
        uint numgood = 0;
        uint numblocking = 0;
        uint numinprog = 0;
        uint numfailed = 0;
      public:
        void Add(AssetDefs::State childState) {
          ++numkids;
          if (childState == AssetDefs::Succeeded) {
            ++numgood;
          } else if (childState == AssetDefs::Failed) {
            ++numfailed;
          } else if (childState == AssetDefs::InProgress) {
            ++numinprog;
          } else if (childState & (AssetDefs::Blocked  |
                                   AssetDefs::Canceled |
                                   AssetDefs::Offline  |
                                   AssetDefs::Bad)) {
            ++numblocking;
          }
        }
        void GetOutputs(AssetDefs::State & stateByChildren) {
          if (numkids == numgood) {
            stateByChildren = AssetDefs::Succeeded;
          } else if (numblocking || numfailed) {
            stateByChildren = AssetDefs::Blocked;
          } else if (numgood || numinprog) {
            stateByChildren = AssetDefs::InProgress;
          } else {
            stateByChildren = AssetDefs::Queued;
          }
        }
    };

    // Loops through the inputs and children of an asset and calculates
    // everything the asset verion needs to know to figure out its state. This
    // data will be passed to the asset version so it can calculate its own
    // state.
    void CalculateStateParameters(
        StateUpdater::TreeType::vertex_descriptor vertex,
        const StateUpdater::TreeType & tree,
        AssetDefs::State &stateByInputs,
        AssetDefs::State &stateByChildren,
        bool & blockersAreOffline,
        uint32 & numWaitingFor) const {
      InputStates inputStates;
      ChildStates childStates;

      auto edgeIters = out_edges(vertex, tree);
      auto edgeBegin = edgeIters.first;
      auto edgeEnd = edgeIters.second;
      for (auto i = edgeBegin; i != edgeEnd; ++i) {
        StateUpdater::DependencyType type = tree[*i].type;
        StateUpdater::TreeType::vertex_descriptor dep = target(*i, tree);
        AssetDefs::State depState = tree[dep].state;
        switch(type) {
          case StateUpdater::INPUT:
            inputStates.Add(depState);
            break;
          case StateUpdater::CHILD:
          case StateUpdater::DEPENDENT_AND_CHILD:
            childStates.Add(depState);
            break;
          case StateUpdater::DEPENDENT:
            // Dependents that are not also children are not considered when
            // calculating state.
            break;
        }
      }

      inputStates.GetOutputs(stateByInputs, blockersAreOffline, numWaitingFor);
      childStates.GetOutputs(stateByChildren);
    }
  public:
    UpdateStateVisitor(StateUpdater * updater) : updater(updater) {};

    // Update the state of an asset after we've updated the state of its
    // inputs and children.
    virtual void finish_vertex(
        StateUpdater::TreeType::vertex_descriptor vertex,
        const StateUpdater::TreeType & tree) const {
      SharedString name = tree[vertex].name;
      notify(NFY_PROGRESS, "Calculating state for '%s'", name.toString().c_str());
      AssetVersionD version(name);
      if (!version) {
        // This shoud never happen - we had to successfully load the asset
        // previously to get it into the tree.
        notify(NFY_WARN, "Could not load asset '%s' to recalculate state.",
               name.toString().c_str());
        return;
      }
      if (!version->NeedComputeState()) return;
      AssetDefs::State stateByInputs;
      AssetDefs::State stateByChildren;
      bool blockersAreOffline;
      uint32 numWaitingFor;
      CalculateStateParameters(vertex, tree, stateByInputs, stateByChildren, blockersAreOffline, numWaitingFor);
      AssetDefs::State newState =
          version->CalcStateByInputsAndChildren(stateByInputs, stateByChildren, blockersAreOffline, numWaitingFor);
      // Set the state and send notifications.
      updater->SetState(vertex, newState, true);
    }
};

void StateUpdater::RecalculateAndSaveStates() {
  // Traverse the state tree, recalculate states, and update states as needed.
  // State is calculated for each vertex in the tree after state is calculated
  // for all of its child and input vertices.
  // Possible optimization: Many assets have significant overlap in their
  // inputs. It might save time if we could calculate the overlapping state
  // only once.
  depth_first_search(tree, visitor(UpdateStateVisitor(this)));
}
<|endoftext|>


<commit_before><commit_msg>fix typo<commit_after><|endoftext|>


<commit_before>// __BEGIN_LICENSE__
//  Copyright (c) 2009-2012, United States Government as represented by the
//  Administrator of the National Aeronautics and Space Administration. All
//  rights reserved.
//
//  The NGT platform is 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.
// __END_LICENSE__

// Wholesale copy from orthoproject.cc. Longer term, this needs to be dealt with properly.

/// \file reconstruct_aux.cc
///
#include <iostream>
#include <string>
#include <fstream>
#include <vector>

#include <vw/Camera.h>
#include <vw/Cartography.h>
#include <vw/Core.h>
#include <vw/FileIO.h>
#include <vw/Image.h>
#include <vw/Math.h>
#include <vw/Math/Functors.h>
#include <vw/Photometry.h>
using namespace std;
using namespace vw::camera;
using namespace vw::cartography;
using namespace vw::math;
using namespace vw::photometry;
using namespace vw;

#include <asp/Core/Macros.h>
#include <asp/Core/Common.h>
#include <asp/Sessions.h>
#include <asp/IsisIO/DiskImageResourceIsis.h>
#include <asp/IsisIO/IsisCameraModel.h>
#include <asp/IsisIO/IsisAdjustCameraModel.h>
#include <boost/tokenizer.hpp>
namespace po = boost::program_options;
namespace fs = boost::filesystem;
using namespace std;
struct Options : asp::BaseOptions {
  Options(){}
  std::string image_file, camera_model_file, stereo_session;
};

int extractDRGFromCube(bool useDEMTiles, double metersPerPixel, std::string DEMTilesDir, std::string DEMFile,
                      std::string cubeFile, std::string isis_adjust_file, std::string outputDrgFile,
                      Vector3 & sunPosition, Vector3 & spacecraftPosition
                      ){

  // Extract the sun/spacecraft position from the cube. If, in
  // addition, the file isis_adjust_file is specified, extract
  // the adjusted spacecraft position from that file instead.

  Options opt;
  try {

    if ( !fs::exists(isis_adjust_file) ){
      std::cout << "WARNING: The ISIS adjust file " << isis_adjust_file
                << " is missing, will extract the unadjusted spacecraft position from the cube file "
                << cubeFile << std::endl;
      isis_adjust_file = cubeFile;
    }

    opt.image_file        = cubeFile;
    opt.camera_model_file = isis_adjust_file;

    // Create a fresh stereo session and query it for the camera models.
    asp::StereoSession::register_session_type("rmax", &asp::StereoSessionRmax::construct);

#if defined(ASP_HAVE_PKG_ISISIO) && ASP_HAVE_PKG_ISISIO == 1
    asp::StereoSession::register_session_type("isis", &asp::StereoSessionIsis::construct);

    opt.stereo_session = "isis";

    // Okay, here's a total hack.  We create a stereo session where both
    // of the imagers and images are the same, because we want to take
    // advantage of the stereo pipeline's ability to generate camera
    // models for various missions.  Hence, we create two identical
    // camera models, but only one is used.  The last empty strings
    // are dummy arguments.
    typedef boost::scoped_ptr<asp::StereoSession> SessionPtr;
    SessionPtr session( asp::StereoSession::create(opt.stereo_session) );
    session->initialize(opt, opt.image_file, opt.image_file,
                        opt.camera_model_file, opt.camera_model_file,
                        "", "","","","" );
    boost::shared_ptr<camera::CameraModel> camera_model;
    camera_model = session->camera_model(opt.image_file, opt.camera_model_file);
    spacecraftPosition = camera_model->camera_center(Vector2());

    vw::camera::IsisCameraModel M(opt.image_file);
    sunPosition = M.sun_position();

    std::cout << "sun and spacecraft positions are: " << sunPosition << ' ' << spacecraftPosition << std::endl;

#else
    std::cout << "ERROR: The ISIS package is missing. Cannot extract " <<
      "sun and spacecraft position from an ISIS cube file. " << std::endl;
    exit(1);
#endif

  } ASP_STANDARD_CATCHES;

  return 0;
}

<commit_msg>Wipe no longer necessary albedo file<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: reginfo.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2007-07-18 08:53:24 $
 *
 *  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_svtools.hxx"

#include "reginfo.hxx"

#ifndef _DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif

#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif

#define MAXREGVALUE 200

// *****************************************************************************
#if defined(WIN) || defined(WNT)

#include <tools/svwin.h>

#define DBG_HDL DBG_ASSERT(pImp->bValidGroup, "Keine Gruppe gesetzt"); \
    if( !pImp->bValidGroup ) return

struct RegInfo_Impl
{
    HKEY aGroupHdl;
    BOOL bValidGroup;
};

RegInfo::RegInfo()
{
    pImp=new RegInfo_Impl;
    pImp->bValidGroup = FALSE;
}

RegInfo::~RegInfo()
{
    if(pImp->bValidGroup)
        RegCloseKey( pImp->aGroupHdl );
    delete pImp;
}

String RegInfo::GetKeyName( USHORT nKey ) const
{
    DBG_HDL String::EmptyString();
    char aBuffer[MAXREGVALUE];
    RegEnumKey( pImp->aGroupHdl, nKey, aBuffer, MAXREGVALUE );
    return String( UniString::CreateFromAscii(aBuffer) );
}

USHORT RegInfo::GetKeyCount() const
{
    DBG_HDL 0;
#ifdef WNT
    DWORD nKeys;
    DWORD Dum1=10, Dum2, Dum3, Dum4, Dum5, Dum6, Dum7;
    char s[10];
    FILETIME aDumFileTime;
    RegQueryInfoKey( pImp->aGroupHdl, s, &Dum1, 0, &nKeys, &Dum2, &Dum3,
                    &Dum4, &Dum5, &Dum6, &Dum7, &aDumFileTime );
    return (USHORT) nKeys;
#else
    char aBuffer[MAXREGVALUE];
    USHORT n=0;
    while(RegEnumKey(
        pImp->aGroupHdl, n, aBuffer, MAXREGVALUE) == ERROR_SUCCESS)
        n++;
    return n;
#endif
}

inline String MakeAppGroupString_Impl( const String &rGroup )
{
    String aGroup( UniString::CreateFromAscii("SvAppGroups\\") );
    aGroup+=rGroup;
    return aGroup;
}

void RegInfo::SetAppGroup( const String& rGroup )
{
    aCurrentGroup = MakeAppGroupString_Impl(rGroup);
    if( pImp->bValidGroup )
    {
        RegCloseKey( pImp->aGroupHdl );
        pImp->bValidGroup = FALSE;
    }
    ByteString aBStr( aCurrentGroup, osl_getThreadTextEncoding() );
    RegCreateKey( HKEY_CLASSES_ROOT, aBStr.GetBuffer(), &pImp->aGroupHdl );
    pImp->bValidGroup = TRUE;
}

void RegInfo::DeleteAppGroup( const String &rGroup )
{
    String aOldGroup = aCurrentGroup;
    SetAppGroup( rGroup );
    DBG_HDL;
    USHORT nMax = GetKeyCount();
    for( USHORT n = nMax; n--; )
    {
        String aKey( GetKeyName( n ));
        DeleteKey( aKey );
    }
    RegCloseKey( pImp->aGroupHdl );

    ByteString aBStr( rGroup, osl_getThreadTextEncoding() );
    RegDeleteKey( HKEY_CLASSES_ROOT, aBStr.GetBuffer() );
    pImp->bValidGroup = FALSE;
    if( rGroup != aOldGroup )
        SetAppGroup( aOldGroup );
}

BOOL ReadKey_Impl( const String& rKey,
                  HKEY aHdl, String& rResult )
{
    char s[MAXREGVALUE];
    LONG aLen=MAXREGVALUE;

    ByteString aBStr( rKey, osl_getThreadTextEncoding() );
    LONG nRes = RegQueryValue( aHdl, aBStr.GetBuffer(), s, &aLen);
    if(nRes == ERROR_SUCCESS)
    {
        rResult = UniString::CreateFromAscii(s);
        return TRUE;
    }
    else
        return FALSE;
}

String  RegInfo::ReadKey( const String& rKey ) const
{
    DBG_HDL String::EmptyString();
    String aRes;
    if(ReadKey_Impl( rKey, pImp->aGroupHdl, aRes))
        return aRes;
    else
        return String::EmptyString();
}

String  RegInfo::ReadKey( const String& rKey, const String &rDefault ) const
{
    DBG_HDL String::EmptyString();
    String aRes;
    if(ReadKey_Impl( rKey, pImp->aGroupHdl, aRes))
        return aRes;
    else
        return rDefault;
}

void RegInfo::WriteKey( const String& rKey, const String& rValue )
{
    DBG_HDL;
    ByteString aBStr( rKey, osl_getThreadTextEncoding() );
    ByteString aBStr1( rValue, osl_getThreadTextEncoding() );
    RegSetValue( pImp->aGroupHdl, aBStr.GetBuffer(), REG_SZ, aBStr1.GetBuffer(), 0);
}

void RegInfo::DeleteKey( const String& rKey )
{
    DBG_HDL;
    ByteString aBStr( rKey, osl_getThreadTextEncoding() );
    RegDeleteKey( pImp->aGroupHdl, aBStr.GetBuffer() );
}

// *****************************************************************************
#elif defined(OS2)

#define INCL_WINSHELLDATA
#include <tools/svpm.h>

struct RegInfo_Impl
{
    char *pKeyList;
    String aCurrentApp;
    void BuildKeyList( const String &rGroup );
};

void RegInfo_Impl::BuildKeyList( const String &rGroup )
{
    USHORT nLen = 0;
    do
    {
        nLen+=1000;
        delete[] pKeyList;
        pKeyList = new char[nLen];
        *(int *)pKeyList = 0;
    }
    while( PrfQueryProfileString(
        HINI_USERPROFILE, rGroup,
        0, 0, pKeyList, nLen) == nLen);
}

RegInfo::RegInfo()
{
    pImp=new RegInfo_Impl;
    pImp->pKeyList = 0;
}

RegInfo::~RegInfo()
{
    delete[] pImp->pKeyList;
    delete pImp;
}

inline String MakeAppGroupString_Impl( const String &rGroup )
{
    String aGroup("SvAppGroups:");
    aGroup+=rGroup;
    return aGroup;
}

String RegInfo::GetKeyName( USHORT nKey ) const
{
    if( !pImp->pKeyList )
        pImp->BuildKeyList(pImp->aCurrentApp);

    const char *pc=pImp->pKeyList;
    for( USHORT n=0; n<nKey; n++ )
        while(*pc++);

    return String(pc);
}

USHORT RegInfo::GetKeyCount() const
{
    if( !pImp->pKeyList )
        pImp->BuildKeyList( pImp->aCurrentApp);

    const char *pc=pImp->pKeyList;
    USHORT nRet=0;
    while(*pc)
    {
        while(*pc++);
        nRet++;
    }
    return nRet;
}

void RegInfo::SetAppGroup( const String& rGroup )
{
    delete[] pImp->pKeyList;
    pImp->pKeyList = 0;
    aCurrentGroup = rGroup;
    pImp->aCurrentApp = MakeAppGroupString_Impl( rGroup );
}

void RegInfo::DeleteAppGroup( const String &rGroup )
{
    PrfWriteProfileString(
        HINI_USERPROFILE, MakeAppGroupString_Impl( rGroup ), 0, 0);
}

String  RegInfo::ReadKey( const String& rKey ) const
{
    char *pBuffer= new char[MAXREGVALUE];
    *pBuffer=0;
    PrfQueryProfileString(
        HINI_USERPROFILE, pImp->aCurrentApp, rKey, 0, pBuffer, MAXREGVALUE);
    String aRet(pBuffer);
    delete[] pBuffer;
    return aRet;
}

String  RegInfo::ReadKey( const String& rKey, const String &rDefault ) const
{
    char *pBuffer= new char[MAXREGVALUE];
    *pBuffer=0;
    PrfQueryProfileString(
        HINI_USERPROFILE, pImp->aCurrentApp, rKey,  rDefault, pBuffer, MAXREGVALUE);
    String aRet(pBuffer);
    delete[] pBuffer;
    return aRet;
}

void RegInfo::WriteKey( const String& rKey, const String& rValue )
{
    PrfWriteProfileString(
        HINI_USERPROFILE, pImp->aCurrentApp, rKey, rValue);
}

void RegInfo::DeleteKey( const String& rKey )
{
    PrfWriteProfileString(
        HINI_USERPROFILE, pImp->aCurrentApp, rKey, 0);
}

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

#else

RegInfo::RegInfo()
{
}

RegInfo::~RegInfo()
{
}

String RegInfo::GetKeyName( USHORT ) const
{
    return String::EmptyString();
}

USHORT RegInfo::GetKeyCount() const
{
    return 0;
}

void RegInfo::SetAppGroup( const String& )
{
    return ;
}

void RegInfo::DeleteAppGroup( const String& )
{
    return;
}

String  RegInfo::ReadKey( const String& ) const
{
    return String::EmptyString();
}

String  RegInfo::ReadKey( const String&, const String& ) const
{
    return String::EmptyString();
}

void RegInfo::WriteKey( const String&, const String& )
{
    return;
}

void RegInfo::DeleteKey( const String& )
{
    return;
}

#endif
<commit_msg>INTEGRATION: CWS os2port01 (1.4.24); FILE MERGED 2007/09/05 10:12:15 obr 1.4.24.3: RESYNC: (1.5-1.6); FILE MERGED 2007/08/12 13:37:53 obr 1.4.24.2: RESYNC: (1.4-1.5); FILE MERGED 2006/12/28 15:06:03 ydario 1.4.24.1: OS/2 initial import.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: reginfo.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2007-09-20 16:29:37 $
 *
 *  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_svtools.hxx"

#include "reginfo.hxx"

#ifndef _DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif

#ifndef _OSL_THREAD_H_
#include <osl/thread.h>
#endif

#define MAXREGVALUE 200

// *****************************************************************************
#if defined(WIN) || defined(WNT)

#include <tools/svwin.h>

#define DBG_HDL DBG_ASSERT(pImp->bValidGroup, "Keine Gruppe gesetzt"); \
    if( !pImp->bValidGroup ) return

struct RegInfo_Impl
{
    HKEY aGroupHdl;
    BOOL bValidGroup;
};

RegInfo::RegInfo()
{
    pImp=new RegInfo_Impl;
    pImp->bValidGroup = FALSE;
}

RegInfo::~RegInfo()
{
    if(pImp->bValidGroup)
        RegCloseKey( pImp->aGroupHdl );
    delete pImp;
}

String RegInfo::GetKeyName( USHORT nKey ) const
{
    DBG_HDL String::EmptyString();
    char aBuffer[MAXREGVALUE];
    RegEnumKey( pImp->aGroupHdl, nKey, aBuffer, MAXREGVALUE );
    return String( UniString::CreateFromAscii(aBuffer) );
}

USHORT RegInfo::GetKeyCount() const
{
    DBG_HDL 0;
#ifdef WNT
    DWORD nKeys;
    DWORD Dum1=10, Dum2, Dum3, Dum4, Dum5, Dum6, Dum7;
    char s[10];
    FILETIME aDumFileTime;
    RegQueryInfoKey( pImp->aGroupHdl, s, &Dum1, 0, &nKeys, &Dum2, &Dum3,
                    &Dum4, &Dum5, &Dum6, &Dum7, &aDumFileTime );
    return (USHORT) nKeys;
#else
    char aBuffer[MAXREGVALUE];
    USHORT n=0;
    while(RegEnumKey(
        pImp->aGroupHdl, n, aBuffer, MAXREGVALUE) == ERROR_SUCCESS)
        n++;
    return n;
#endif
}

inline String MakeAppGroupString_Impl( const String &rGroup )
{
    String aGroup( UniString::CreateFromAscii("SvAppGroups\\") );
    aGroup+=rGroup;
    return aGroup;
}

void RegInfo::SetAppGroup( const String& rGroup )
{
    aCurrentGroup = MakeAppGroupString_Impl(rGroup);
    if( pImp->bValidGroup )
    {
        RegCloseKey( pImp->aGroupHdl );
        pImp->bValidGroup = FALSE;
    }
    ByteString aBStr( aCurrentGroup, osl_getThreadTextEncoding() );
    RegCreateKey( HKEY_CLASSES_ROOT, aBStr.GetBuffer(), &pImp->aGroupHdl );
    pImp->bValidGroup = TRUE;
}

void RegInfo::DeleteAppGroup( const String &rGroup )
{
    String aOldGroup = aCurrentGroup;
    SetAppGroup( rGroup );
    DBG_HDL;
    USHORT nMax = GetKeyCount();
    for( USHORT n = nMax; n--; )
    {
        String aKey( GetKeyName( n ));
        DeleteKey( aKey );
    }
    RegCloseKey( pImp->aGroupHdl );

    ByteString aBStr( rGroup, osl_getThreadTextEncoding() );
    RegDeleteKey( HKEY_CLASSES_ROOT, aBStr.GetBuffer() );
    pImp->bValidGroup = FALSE;
    if( rGroup != aOldGroup )
        SetAppGroup( aOldGroup );
}

BOOL ReadKey_Impl( const String& rKey,
                  HKEY aHdl, String& rResult )
{
    char s[MAXREGVALUE];
    LONG aLen=MAXREGVALUE;

    ByteString aBStr( rKey, osl_getThreadTextEncoding() );
    LONG nRes = RegQueryValue( aHdl, aBStr.GetBuffer(), s, &aLen);
    if(nRes == ERROR_SUCCESS)
    {
        rResult = UniString::CreateFromAscii(s);
        return TRUE;
    }
    else
        return FALSE;
}

String  RegInfo::ReadKey( const String& rKey ) const
{
    DBG_HDL String::EmptyString();
    String aRes;
    if(ReadKey_Impl( rKey, pImp->aGroupHdl, aRes))
        return aRes;
    else
        return String::EmptyString();
}

String  RegInfo::ReadKey( const String& rKey, const String &rDefault ) const
{
    DBG_HDL String::EmptyString();
    String aRes;
    if(ReadKey_Impl( rKey, pImp->aGroupHdl, aRes))
        return aRes;
    else
        return rDefault;
}

void RegInfo::WriteKey( const String& rKey, const String& rValue )
{
    DBG_HDL;
    ByteString aBStr( rKey, osl_getThreadTextEncoding() );
    ByteString aBStr1( rValue, osl_getThreadTextEncoding() );
    RegSetValue( pImp->aGroupHdl, aBStr.GetBuffer(), REG_SZ, aBStr1.GetBuffer(), 0);
}

void RegInfo::DeleteKey( const String& rKey )
{
    DBG_HDL;
    ByteString aBStr( rKey, osl_getThreadTextEncoding() );
    RegDeleteKey( pImp->aGroupHdl, aBStr.GetBuffer() );
}

// *****************************************************************************
#elif defined(OS2)

#define INCL_WINSHELLDATA
#include <svpm.h>

struct RegInfo_Impl
{
    char *pKeyList;
    String aCurrentApp;
    void BuildKeyList( const String &rGroup );
};

void RegInfo_Impl::BuildKeyList( const String &rGroup )
{
    ByteString aBStr( rGroup, osl_getThreadTextEncoding() );
    USHORT nLen = 0;
    do
    {
        nLen+=1000;
        delete[] pKeyList;
        pKeyList = new char[nLen];
        *(int *)pKeyList = 0;
    }
    while( PrfQueryProfileString(
        HINI_USERPROFILE, (PCSZ)aBStr.GetBuffer(),
        0, 0, pKeyList, nLen) == nLen);
}

RegInfo::RegInfo()
{
    pImp=new RegInfo_Impl;
    pImp->pKeyList = 0;
}

RegInfo::~RegInfo()
{
    delete[] pImp->pKeyList;
    delete pImp;
}

inline String MakeAppGroupString_Impl( const String &rGroup )
{
    String aGroup(UniString::CreateFromAscii("SvAppGroups:"));
    aGroup+=rGroup;
    return aGroup;
}

String RegInfo::GetKeyName( USHORT nKey ) const
{
    if( !pImp->pKeyList )
        pImp->BuildKeyList(pImp->aCurrentApp);

    const char *pc=pImp->pKeyList;
    for( USHORT n=0; n<nKey; n++ )
        while(*pc++);

    return String(UniString::CreateFromAscii(pc));
}

USHORT RegInfo::GetKeyCount() const
{
    if( !pImp->pKeyList )
        pImp->BuildKeyList( pImp->aCurrentApp);

    const char *pc=pImp->pKeyList;
    USHORT nRet=0;
    while(*pc)
    {
        while(*pc++);
        nRet++;
    }
    return nRet;
}

void RegInfo::SetAppGroup( const String& rGroup )
{
    delete[] pImp->pKeyList;
    pImp->pKeyList = 0;
    aCurrentGroup = rGroup;
    pImp->aCurrentApp = MakeAppGroupString_Impl( rGroup );
}

void RegInfo::DeleteAppGroup( const String &rGroup )
{
    ByteString aBStr( MakeAppGroupString_Impl( rGroup ), osl_getThreadTextEncoding() );
    PrfWriteProfileString(
        HINI_USERPROFILE, (PCSZ)aBStr.GetBuffer(), 0, 0);
}

String  RegInfo::ReadKey( const String& rKey ) const
{
    ULONG    ulBufferMax = MAXREGVALUE;
    char *pBuffer= new char[MAXREGVALUE];
    ByteString aBStr( pImp->aCurrentApp, osl_getThreadTextEncoding() );
    ByteString aBStr1( rKey, osl_getThreadTextEncoding() );
    *pBuffer=0;
    PrfQueryProfileData(
        HINI_USERPROFILE, (PCSZ)aBStr.GetBuffer(), (PCSZ)aBStr1.GetBuffer(), pBuffer, &ulBufferMax);
    String aRet(UniString::CreateFromAscii(pBuffer));
    delete[] pBuffer;
    return aRet;
}

String  RegInfo::ReadKey( const String& rKey, const String &rDefault ) const
{
    String aResult = ReadKey(rKey);
    if (!aResult.Len())
        return rDefault;
    else
        return aResult;
}

void RegInfo::WriteKey( const String& rKey, const String& rValue )
{
    ByteString aBStr( pImp->aCurrentApp, osl_getThreadTextEncoding() );
    ByteString aBStr1( rKey, osl_getThreadTextEncoding() );
    PrfWriteProfileData(
        HINI_USERPROFILE, (PCSZ)aBStr.GetBuffer(), (PCSZ)aBStr1.GetBuffer(), (PVOID)rValue.GetBuffer(), rValue.Len()*2);
}

void RegInfo::DeleteKey( const String& rKey )
{
    ByteString aBStr( pImp->aCurrentApp, osl_getThreadTextEncoding() );
    ByteString aBStr1( rKey, osl_getThreadTextEncoding() );
    PrfWriteProfileString(
        HINI_USERPROFILE, (PCSZ)aBStr.GetBuffer(), (PCSZ)rKey.GetBuffer(), 0);
}

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

#else

RegInfo::RegInfo()
{
}

RegInfo::~RegInfo()
{
}

String RegInfo::GetKeyName( USHORT ) const
{
    return String::EmptyString();
}

USHORT RegInfo::GetKeyCount() const
{
    return 0;
}

void RegInfo::SetAppGroup( const String& )
{
    return ;
}

void RegInfo::DeleteAppGroup( const String& )
{
    return;
}

String  RegInfo::ReadKey( const String& ) const
{
    return String::EmptyString();
}

String  RegInfo::ReadKey( const String&, const String& ) const
{
    return String::EmptyString();
}

void RegInfo::WriteKey( const String&, const String& )
{
    return;
}

void RegInfo::DeleteKey( const String& )
{
    return;
}

#endif
<|endoftext|>


<commit_before><commit_msg>unused define<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: tresitem.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 21:46: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
 *
 ************************************************************************/

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

#ifndef SVTOOLS_TRESITEM_HXX
#include <svtools/tresitem.hxx>
#endif

using namespace com::sun::star;

//============================================================================
//
//  CntTransferResultItem
//
//============================================================================

TYPEINIT1_AUTOFACTORY(CntTransferResultItem, SfxPoolItem)

//============================================================================
// virtual
int CntTransferResultItem::operator ==(SfxPoolItem const & rItem) const
{
    if (CntTransferResultItem * pResultItem = PTR_CAST(CntTransferResultItem,
                                                       &rItem))
        return m_aResult.Source == pResultItem->m_aResult.Source
               && m_aResult.Target == pResultItem->m_aResult.Target
               && m_aResult.Result == pResultItem->m_aResult.Result;
    return false;
}

//============================================================================
// virtual
BOOL CntTransferResultItem::QueryValue(uno::Any & rVal, BYTE) const
{
    rVal <<= m_aResult;
    return true;
}

//============================================================================
// virtual
BOOL CntTransferResultItem::PutValue(uno::Any const & rVal, BYTE)
{
    return rVal >>= m_aResult;
}

//============================================================================
// virtual
SfxPoolItem * CntTransferResultItem::Clone(SfxItemPool *) const
{
    return new CntTransferResultItem(*this);
}

<commit_msg>INTEGRATION: CWS changefileheader (1.5.246); FILE MERGED 2008/04/01 12:43:45 thb 1.5.246.2: #i85898# Stripping all external header guards 2008/03/31 13:02:11 rt 1.5.246.1: #i87441# Change license header to LPGL v3.<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: tresitem.cxx,v $
 * $Revision: 1.6 $
 *
 * 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_svtools.hxx"
#include <svtools/tresitem.hxx>

using namespace com::sun::star;

//============================================================================
//
//  CntTransferResultItem
//
//============================================================================

TYPEINIT1_AUTOFACTORY(CntTransferResultItem, SfxPoolItem)

//============================================================================
// virtual
int CntTransferResultItem::operator ==(SfxPoolItem const & rItem) const
{
    if (CntTransferResultItem * pResultItem = PTR_CAST(CntTransferResultItem,
                                                       &rItem))
        return m_aResult.Source == pResultItem->m_aResult.Source
               && m_aResult.Target == pResultItem->m_aResult.Target
               && m_aResult.Result == pResultItem->m_aResult.Result;
    return false;
}

//============================================================================
// virtual
BOOL CntTransferResultItem::QueryValue(uno::Any & rVal, BYTE) const
{
    rVal <<= m_aResult;
    return true;
}

//============================================================================
// virtual
BOOL CntTransferResultItem::PutValue(uno::Any const & rVal, BYTE)
{
    return rVal >>= m_aResult;
}

//============================================================================
// virtual
SfxPoolItem * CntTransferResultItem::Clone(SfxItemPool *) const
{
    return new CntTransferResultItem(*this);
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: numhead.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: vg $ $Date: 2006-03-16 13:06:19 $
 *
 *  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 NF_NUMHEAD_HXX
#define NF_NUMHEAD_HXX

#ifndef _STREAM_HXX //autogen
#include <tools/stream.hxx>
#endif

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

        //  "Automatischer" Record-Header mit Groessenangabe

/*                      wird fuer SvNumberFormatter nicht gebraucht
class SvNumReadHeader
{
private:
    SvStream&   rStream;
    ULONG       nDataEnd;

public:
    SvNumReadHeader(SvStream& rNewStream);
    ~SvNumReadHeader();

    ULONG   BytesLeft() const;
};

class SvNumWriteHeader
{
private:
    SvStream&   rStream;
    ULONG       nDataPos;
    ULONG       nDataSize;

public:
    SvNumWriteHeader(SvStream& rNewStream, ULONG nDefault = 0);
    ~SvNumWriteHeader();
};

*/

        //  Header mit Groessenangaben fuer mehrere Objekte

class ImpSvNumMultipleReadHeader
{
private:
    SvStream&       rStream;
    char*           pBuf;
    SvMemoryStream* pMemStream;
    ULONG           nEndPos;
    ULONG           nEntryEnd;

public:
    ImpSvNumMultipleReadHeader(SvStream& rNewStream);
    ~ImpSvNumMultipleReadHeader();

    void    StartEntry();
    void    EndEntry();
    ULONG   BytesLeft() const;

    static void Skip( SvStream& );      // komplett ueberspringen
};

class ImpSvNumMultipleWriteHeader
{
private:
    SvStream&       rStream;
    SvMemoryStream  aMemStream;
    ULONG           nDataPos;
    sal_uInt32      nDataSize;
    ULONG           nEntryStart;

public:
    ImpSvNumMultipleWriteHeader(SvStream& rNewStream, ULONG nDefault = 0);
    ~ImpSvNumMultipleWriteHeader();

    void    StartEntry();
    void    EndEntry();
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.3.616); FILE MERGED 2008/04/01 15:45:24 thb 1.3.616.2: #i85898# Stripping all external header guards 2008/03/31 13:02:24 rt 1.3.616.1: #i87441# Change license header to LPGL v3.<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: numhead.hxx,v $
 * $Revision: 1.4 $
 *
 * 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.
 *
 ************************************************************************/

#ifndef NF_NUMHEAD_HXX
#define NF_NUMHEAD_HXX

#include <tools/stream.hxx>

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

        //  "Automatischer" Record-Header mit Groessenangabe

/*                      wird fuer SvNumberFormatter nicht gebraucht
class SvNumReadHeader
{
private:
    SvStream&   rStream;
    ULONG       nDataEnd;

public:
    SvNumReadHeader(SvStream& rNewStream);
    ~SvNumReadHeader();

    ULONG   BytesLeft() const;
};

class SvNumWriteHeader
{
private:
    SvStream&   rStream;
    ULONG       nDataPos;
    ULONG       nDataSize;

public:
    SvNumWriteHeader(SvStream& rNewStream, ULONG nDefault = 0);
    ~SvNumWriteHeader();
};

*/

        //  Header mit Groessenangaben fuer mehrere Objekte

class ImpSvNumMultipleReadHeader
{
private:
    SvStream&       rStream;
    char*           pBuf;
    SvMemoryStream* pMemStream;
    ULONG           nEndPos;
    ULONG           nEntryEnd;

public:
    ImpSvNumMultipleReadHeader(SvStream& rNewStream);
    ~ImpSvNumMultipleReadHeader();

    void    StartEntry();
    void    EndEntry();
    ULONG   BytesLeft() const;

    static void Skip( SvStream& );      // komplett ueberspringen
};

class ImpSvNumMultipleWriteHeader
{
private:
    SvStream&       rStream;
    SvMemoryStream  aMemStream;
    ULONG           nDataPos;
    sal_uInt32      nDataSize;
    ULONG           nEntryStart;

public:
    ImpSvNumMultipleWriteHeader(SvStream& rNewStream, ULONG nDefault = 0);
    ~ImpSvNumMultipleWriteHeader();

    void    StartEntry();
    void    EndEntry();
};

#endif

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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_svtools.hxx"

#include <ctype.h>
#include <stdio.h>
#include <tools/urlobj.hxx>
#ifndef _SVSTDARR_HXX
#define _SVSTDARR_ULONGS
#include <svl/svstdarr.hxx>
#endif

#include <svtools/parhtml.hxx>
#include <svtools/htmltokn.h>
#include <svtools/htmlkywd.hxx>

/*  */

// Table for converting option values into strings

static HTMLOptionEnum const aScriptLangOptEnums[] =
{
    { OOO_STRING_SVTOOLS_HTML_LG_starbasic, HTML_SL_STARBASIC   },
    { OOO_STRING_SVTOOLS_HTML_LG_javascript,    HTML_SL_JAVASCRIPT  },
    { OOO_STRING_SVTOOLS_HTML_LG_javascript11,HTML_SL_JAVASCRIPT    },
    { OOO_STRING_SVTOOLS_HTML_LG_livescript,    HTML_SL_JAVASCRIPT  },
//  { OOO_STRING_SVTOOLS_HTML_LG_unused_javascript, HTML_SL_UNUSEDJS },
//  { OOO_STRING_SVTOOLS_HTML_LG_vbscript,  HTML_SL_VBSCRIPT    },
//  { OOO_STRING_SVTOOLS_HTML_LG_starone,       HTML_SL_STARONE     },
    { 0,                    0                   }
};

sal_Bool HTMLParser::ParseScriptOptions( String& rLangString, const String& rBaseURL,
                                     HTMLScriptLanguage& rLang,
                                     String& rSrc,
                                     String& rLibrary,
                                     String& rModule )
{
    const HTMLOptions *pScriptOptions = GetOptions();

    rLangString.Erase();
    rLang = HTML_SL_JAVASCRIPT;
    rSrc.Erase();
    rLibrary.Erase();
    rModule.Erase();

    for( sal_uInt16 i = pScriptOptions->Count(); i; )
    {
        const HTMLOption *pOption = (*pScriptOptions)[ --i ];
        switch( pOption->GetToken() )
        {
        case HTML_O_LANGUAGE:
            {
                rLangString = pOption->GetString();
                sal_uInt16 nLang;
                if( pOption->GetEnum( nLang, aScriptLangOptEnums ) )
                    rLang = (HTMLScriptLanguage)nLang;
                else
                    rLang = HTML_SL_UNKNOWN;
            }
            break;

        case HTML_O_SRC:
            rSrc = INetURLObject::GetAbsURL( rBaseURL, pOption->GetString() );
            break;
        case HTML_O_SDLIBRARY:
            rLibrary = pOption->GetString();
            break;

        case HTML_O_SDMODULE:
            rModule = pOption->GetString();
            break;
        }
    }

    return sal_True;
}

void HTMLParser::RemoveSGMLComment( String &rString, sal_Bool bFull )
{
    sal_Unicode c = 0;
    while( rString.Len() &&
           ( ' '==(c=rString.GetChar(0)) || '\t'==c || '\r'==c || '\n'==c ) )
        rString.Erase( 0, 1 );

    while( rString.Len() &&
           ( ' '==(c=rString.GetChar( rString.Len()-1))
           || '\t'==c || '\r'==c || '\n'==c ) )
        rString.Erase( rString.Len()-1 );

    // remove SGML comments
    if( rString.Len() >= 4 &&
        rString.CompareToAscii( "<!--", 4 ) == COMPARE_EQUAL )
    {
        xub_StrLen nPos = 3;
        if( bFull )
        {
            // the whole line
            nPos = 4;
            while( nPos < rString.Len() &&
                ( ( c = rString.GetChar( nPos )) != '\r' && c != '\n' ) )
                ++nPos;
            if( c == '\r' && nPos+1 < rString.Len() &&
                '\n' == rString.GetChar( nPos+1 ))
                ++nPos;
            else if( c != '\n' )
                nPos = 3;
        }
        rString.Erase( 0, ++nPos );
    }

    if( rString.Len() >=3 &&
        rString.Copy(rString.Len()-3).CompareToAscii("-->")
            == COMPARE_EQUAL )
    {
        rString.Erase( rString.Len()-3 );
        if( bFull )
        {
            // "//" or "'", maybe preceding CR/LF
            rString.EraseTrailingChars();
            xub_StrLen nDel = 0, nLen = rString.Len();
            if( nLen >= 2 &&
                rString.Copy(nLen-2).CompareToAscii("//") == COMPARE_EQUAL )
            {
                nDel = 2;
            }
            else if( nLen && '\'' == rString.GetChar(nLen-1) )
            {
                nDel = 1;
            }
            if( nDel && nLen >= nDel+1 )
            {
                c = rString.GetChar( nLen-(nDel+1) );
                if( '\r'==c || '\n'==c )
                {
                    nDel++;
                    if( '\n'==c && nLen >= nDel+1 &&
                        '\r'==rString.GetChar( nLen-(nDel+1) ) )
                        nDel++;
                }
            }
            rString.Erase( nLen-nDel );
        }
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Removed comments/commented code<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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_svtools.hxx"

#include <ctype.h>
#include <stdio.h>
#include <tools/urlobj.hxx>
#ifndef _SVSTDARR_HXX
#define _SVSTDARR_ULONGS
#include <svl/svstdarr.hxx>
#endif

#include <svtools/parhtml.hxx>
#include <svtools/htmltokn.h>
#include <svtools/htmlkywd.hxx>

// Table for converting option values into strings
static HTMLOptionEnum const aScriptLangOptEnums[] =
{
    { OOO_STRING_SVTOOLS_HTML_LG_starbasic, HTML_SL_STARBASIC   },
    { OOO_STRING_SVTOOLS_HTML_LG_javascript,    HTML_SL_JAVASCRIPT  },
    { OOO_STRING_SVTOOLS_HTML_LG_javascript11,HTML_SL_JAVASCRIPT    },
    { OOO_STRING_SVTOOLS_HTML_LG_livescript,    HTML_SL_JAVASCRIPT  },
    { 0,                    0                   }
};

sal_Bool HTMLParser::ParseScriptOptions( String& rLangString, const String& rBaseURL,
                                     HTMLScriptLanguage& rLang,
                                     String& rSrc,
                                     String& rLibrary,
                                     String& rModule )
{
    const HTMLOptions *pScriptOptions = GetOptions();

    rLangString.Erase();
    rLang = HTML_SL_JAVASCRIPT;
    rSrc.Erase();
    rLibrary.Erase();
    rModule.Erase();

    for( sal_uInt16 i = pScriptOptions->Count(); i; )
    {
        const HTMLOption *pOption = (*pScriptOptions)[ --i ];
        switch( pOption->GetToken() )
        {
        case HTML_O_LANGUAGE:
            {
                rLangString = pOption->GetString();
                sal_uInt16 nLang;
                if( pOption->GetEnum( nLang, aScriptLangOptEnums ) )
                    rLang = (HTMLScriptLanguage)nLang;
                else
                    rLang = HTML_SL_UNKNOWN;
            }
            break;

        case HTML_O_SRC:
            rSrc = INetURLObject::GetAbsURL( rBaseURL, pOption->GetString() );
            break;
        case HTML_O_SDLIBRARY:
            rLibrary = pOption->GetString();
            break;

        case HTML_O_SDMODULE:
            rModule = pOption->GetString();
            break;
        }
    }

    return sal_True;
}

void HTMLParser::RemoveSGMLComment( String &rString, sal_Bool bFull )
{
    sal_Unicode c = 0;
    while( rString.Len() &&
           ( ' '==(c=rString.GetChar(0)) || '\t'==c || '\r'==c || '\n'==c ) )
        rString.Erase( 0, 1 );

    while( rString.Len() &&
           ( ' '==(c=rString.GetChar( rString.Len()-1))
           || '\t'==c || '\r'==c || '\n'==c ) )
        rString.Erase( rString.Len()-1 );

    // remove SGML comments
    if( rString.Len() >= 4 &&
        rString.CompareToAscii( "<!--", 4 ) == COMPARE_EQUAL )
    {
        xub_StrLen nPos = 3;
        if( bFull )
        {
            // the whole line
            nPos = 4;
            while( nPos < rString.Len() &&
                ( ( c = rString.GetChar( nPos )) != '\r' && c != '\n' ) )
                ++nPos;
            if( c == '\r' && nPos+1 < rString.Len() &&
                '\n' == rString.GetChar( nPos+1 ))
                ++nPos;
            else if( c != '\n' )
                nPos = 3;
        }
        rString.Erase( 0, ++nPos );
    }

    if( rString.Len() >=3 &&
        rString.Copy(rString.Len()-3).CompareToAscii("-->")
            == COMPARE_EQUAL )
    {
        rString.Erase( rString.Len()-3 );
        if( bFull )
        {
            // "//" or "'", maybe preceding CR/LF
            rString.EraseTrailingChars();
            xub_StrLen nDel = 0, nLen = rString.Len();
            if( nLen >= 2 &&
                rString.Copy(nLen-2).CompareToAscii("//") == COMPARE_EQUAL )
            {
                nDel = 2;
            }
            else if( nLen && '\'' == rString.GetChar(nLen-1) )
            {
                nDel = 1;
            }
            if( nDel && nLen >= nDel+1 )
            {
                c = rString.GetChar( nLen-(nDel+1) );
                if( '\r'==c || '\n'==c )
                {
                    nDel++;
                    if( '\n'==c && nLen >= nDel+1 &&
                        '\r'==rString.GetChar( nLen-(nDel+1) ) )
                        nDel++;
                }
            }
            rString.Erase( nLen-nDel );
        }
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>