<commit_before>// @(#)root/thread:$Id$
// Author: Enric Tejedor, CERN  12/09/2016

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TTreeProcessorMT
#define ROOT_TTreeProcessorMT

#include "TKey.h"
#include "TTree.h"
#include "TFile.h"
#include "TChain.h"
#include "TTreeReader.h"
#include "TError.h"
#include "TEntryList.h"
#include "ROOT/TThreadedObject.hxx"

#include <string.h>
#include <functional>
#include <vector>

/** \class TTreeView
    \brief A helper class that encapsulates a file and a tree.

A helper class that encapsulates a TFile and a TTree, along with their names.
It is used together with TTProcessor and ROOT::TThreadedObject, so that
in the TTProcessor::Process method each thread can work on its own
<TFile,TTree> pair.

This class can also be used with a collection of file names or a TChain, in case
the tree is stored in more than one file. A view will always contain only the
current (active) tree and file objects.

A copy constructor is defined for TTreeView to work with ROOT::TThreadedObject.
The latter makes a copy of a model object every time a new thread accesses
the threaded object.
*/

namespace ROOT {
   namespace Internal {
      class TTreeView {
      private:
         std::vector<std::string> fFileNames; ///< Names of the files
         std::string fTreeName;               ///< Name of the tree
         std::unique_ptr<TFile> fCurrentFile; ///<! Current file object of this view.
         TTree *fCurrentTree;                 ///<! Current tree object of this view.
         unsigned int fCurrentIdx;            ///<! Index of the current file.
         std::vector<TEntryList> fEntryLists; ///< Entry numbers to be processed per tree/file
         TEntryList fCurrentEntryList;        ///< Entry numbers for the current range being processed

         ////////////////////////////////////////////////////////////////////////////////
         /// Initialize the file and the tree for this view, first looking for a tree in
         /// the file if necessary.
         void Init()
         {
            fCurrentFile.reset(TFile::Open(fFileNames[fCurrentIdx].data()));

            // If the tree name is empty, look for a tree in the file
            if (fTreeName.empty()) {
               TIter next(fCurrentFile->GetListOfKeys());
               while (TKey *key = (TKey*)next()) {
                  const char *className = key->GetClassName();
                  if (strcmp(className, "TTree") == 0) {
                     fTreeName = key->GetName();
                     break;
                  }
               }
               if (fTreeName.empty())
                  ::Error("TreeView constructor", "Cannot find any tree in file %s", fFileNames[fCurrentIdx].data());
            }

            // We cannot use here the template method (TFile::GetObject) because the header will finish
            // in the PCH and the specialization will be available. PyROOT will not be able to specialize
            // the method for types other that TTree.
            fCurrentTree = (TTree*)fCurrentFile->Get(fTreeName.data());

            // Do not remove this tree from list of cleanups (thread unsafe)
            fCurrentTree->ResetBit(TObject::kMustCleanup);
         }

      public:
         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a file name.
         /// \param[in] fn Name of the file containing the tree to process.
         /// \param[in] tn Name of the tree to process. If not provided,
         ///               the implementation will automatically search for a
         ///               tree in the file.
         TTreeView(std::string_view fn, std::string_view tn) : fTreeName(tn), fCurrentIdx(0)
         {
            fFileNames.emplace_back(fn);
            Init();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a collection of file names.
         /// \param[in] fns Collection of file names containing the tree to process.
         /// \param[in] tn Name of the tree to process. If not provided,
         ///               the implementation will automatically search for a
         ///               tree in the collection of files.
         TTreeView(const std::vector<std::string_view>& fns, std::string_view tn) : fTreeName(tn), fCurrentIdx(0)
         {
            if (fns.size() > 0) {
               for (auto& fn : fns)
                  fFileNames.emplace_back(fn);
               Init();
             }
             else {
                ::Error("TreeView constructor", "The provided list of file names is empty, cannot process tree %s", fTreeName.data());
             }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a TTree.
         /// \param[in] tree Tree or chain of files containing the tree to process.
         TTreeView(TTree& tree) : fTreeName(tree.GetName()), fCurrentIdx(0)
         {
            static const TClassRef clRefTChain("TChain");
            if (clRefTChain == tree.IsA()) {
               TObjArray* filelist = dynamic_cast<TChain&>(tree).GetListOfFiles();
               if (filelist->GetEntries() > 0) {
                  for (auto f : *filelist)
                     fFileNames.emplace_back(f->GetTitle());
                  Init();
               }
               else {
                  ::Error("TreeView constructor", "The provided chain of files is empty, cannot process tree %s", fTreeName.data());
               }
            }
            else {
               fFileNames.emplace_back(tree.GetCurrentFile()->GetName());
               Init();
            }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a TTree and a TEntryList.
         /// \param[in] tree Tree or chain of files containing the tree to process.
         /// \param[in] entries List of entry numbers to process.
         TTreeView(TTree& tree, TEntryList& entries) : TTreeView(tree)
         {
            static const TClassRef clRefTChain("TChain");
            if (clRefTChain == tree.IsA()) {
               // We need to convert the global entry numbers to per-tree entry numbers.
               // This will allow us to build a TEntryList for a given entry range of a tree of the chain.
               size_t nTrees = fFileNames.size();
               fEntryLists.resize(nTrees);

               TChain *chain = dynamic_cast<TChain*>(&tree);
               Long64_t currListEntry  = entries.GetEntry(0);
               Long64_t currTreeOffset = 0;

               for (unsigned int treeNum = 0; treeNum < nTrees && currListEntry >= 0; ++treeNum) {
                  chain->LoadTree(currTreeOffset);
                  TTree *currTree = chain->GetTree();
                  Long64_t currTreeEntries = currTree->GetEntries();
                  Long64_t nextTreeOffset = currTreeOffset + currTreeEntries;

                  while (currListEntry >= 0 && currListEntry < nextTreeOffset) {
                     fEntryLists[treeNum].Enter(currListEntry - currTreeOffset);
                     currListEntry = entries.Next();
                  }

                  currTreeOffset = nextTreeOffset;
               }
            }
            else {
               fEntryLists.emplace_back(entries);
            }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Copy constructor.
         /// \param[in] view Object to copy.
         TTreeView(const TTreeView& view) : fTreeName(view.fTreeName), fCurrentIdx(view.fCurrentIdx)
         {
            for (auto& fn : view.fFileNames)
               fFileNames.emplace_back(fn);

            for (auto& el : view.fEntryLists)
               fEntryLists.emplace_back(el);

            Init();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the cluster iterator for the current tree of this view, starting
         /// from entry zero.
         TTree::TClusterIterator GetClusterIterator()
         {
            return fCurrentTree->GetClusterIterator(0);
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get a TTreeReader for the current tree of this view.
         std::unique_ptr<TTreeReader> GetTreeReader(Long64_t start, Long64_t end)
         {
            TTreeReader *reader;
            if (fEntryLists.size() > 0 && fEntryLists[fCurrentIdx].GetN() > 0) {
               // TEntryList and SetEntriesRange do not work together (the former has precedence).
               // We need to construct a TEntryList that contains only those entry numbers
               // in our desired range.
               fCurrentEntryList.Reset();
               Long64_t entry = fEntryLists[fCurrentIdx].GetEntry(0);
               do {
                  if (entry >= start && entry < end) fCurrentEntryList.Enter(entry);
               } while ((entry = fEntryLists[fCurrentIdx].Next()) >= 0);

               reader = new TTreeReader(fCurrentTree, &fCurrentEntryList);

            }
            else {
               // If no TEntryList is involved we can safely set the range in the reader
               reader = new TTreeReader(fCurrentTree);
               reader->SetEntriesRange(start, end);
            }

            return std::unique_ptr<TTreeReader>(reader);
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the number of entries of the current tree of this view.
         Long64_t GetEntries() const
         {
            return fCurrentTree->GetEntries();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the number of files of this view.
         size_t GetNumFiles() const
         {
            return fFileNames.size();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Set the current file and tree of this view.
         void SetCurrent(unsigned int i)
         {
            if (i != fCurrentIdx) {
               fCurrentIdx = i;
               TFile *f = TFile::Open(fFileNames[fCurrentIdx].data());
               fCurrentTree = (TTree*)f->Get(fTreeName.data());
               fCurrentTree->ResetBit(TObject::kMustCleanup);
               fCurrentFile.reset(f);
            }
         }
      };
   } // End of namespace Internal

   class TTreeProcessorMT {
   private:
      ROOT::TThreadedObject<ROOT::Internal::TTreeView> treeView; ///<! Threaded object with <file,tree> per thread

   public:
      TTreeProcessorMT(std::string_view filename, std::string_view treename = "");
      TTreeProcessorMT(const std::vector<std::string_view>& filenames, std::string_view treename = "");
      TTreeProcessorMT(TTree& tree);
      TTreeProcessorMT(TTree& tree, TEntryList& entries);

      void Process(std::function<void(TTreeReader&)> func);

   };

} // End of namespace ROOT

#endif // defined TTreeProcessorMT
<commit_msg>Fix indentation<commit_after>// @(#)root/thread:$Id$
// Author: Enric Tejedor, CERN  12/09/2016

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TTreeProcessorMT
#define ROOT_TTreeProcessorMT

#include "TKey.h"
#include "TTree.h"
#include "TFile.h"
#include "TChain.h"
#include "TTreeReader.h"
#include "TError.h"
#include "TEntryList.h"
#include "ROOT/TThreadedObject.hxx"

#include <string.h>
#include <functional>
#include <vector>

/** \class TTreeView
    \brief A helper class that encapsulates a file and a tree.

A helper class that encapsulates a TFile and a TTree, along with their names.
It is used together with TTProcessor and ROOT::TThreadedObject, so that
in the TTProcessor::Process method each thread can work on its own
<TFile,TTree> pair.

This class can also be used with a collection of file names or a TChain, in case
the tree is stored in more than one file. A view will always contain only the
current (active) tree and file objects.

A copy constructor is defined for TTreeView to work with ROOT::TThreadedObject.
The latter makes a copy of a model object every time a new thread accesses
the threaded object.
*/

namespace ROOT {
   namespace Internal {
      class TTreeView {
      private:
         std::vector<std::string> fFileNames; ///< Names of the files
         std::string fTreeName;               ///< Name of the tree
         std::unique_ptr<TFile> fCurrentFile; ///<! Current file object of this view.
         TTree *fCurrentTree;                 ///<! Current tree object of this view.
         unsigned int fCurrentIdx;            ///<! Index of the current file.
         std::vector<TEntryList> fEntryLists; ///< Entry numbers to be processed per tree/file
         TEntryList fCurrentEntryList;        ///< Entry numbers for the current range being processed

         ////////////////////////////////////////////////////////////////////////////////
         /// Initialize the file and the tree for this view, first looking for a tree in
         /// the file if necessary.
         void Init()
         {
            fCurrentFile.reset(TFile::Open(fFileNames[fCurrentIdx].data()));

            // If the tree name is empty, look for a tree in the file
            if (fTreeName.empty()) {
               TIter next(fCurrentFile->GetListOfKeys());
               while (TKey *key = (TKey*)next()) {
                  const char *className = key->GetClassName();
                  if (strcmp(className, "TTree") == 0) {
                     fTreeName = key->GetName();
                     break;
                  }
               }
               if (fTreeName.empty())
                  ::Error("TreeView constructor", "Cannot find any tree in file %s", fFileNames[fCurrentIdx].data());
            }

            // We cannot use here the template method (TFile::GetObject) because the header will finish
            // in the PCH and the specialization will be available. PyROOT will not be able to specialize
            // the method for types other that TTree.
            fCurrentTree = (TTree*)fCurrentFile->Get(fTreeName.data());

            // Do not remove this tree from list of cleanups (thread unsafe)
            fCurrentTree->ResetBit(TObject::kMustCleanup);
         }

      public:
         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a file name.
         /// \param[in] fn Name of the file containing the tree to process.
         /// \param[in] tn Name of the tree to process. If not provided,
         ///               the implementation will automatically search for a
         ///               tree in the file.
         TTreeView(std::string_view fn, std::string_view tn) : fTreeName(tn), fCurrentIdx(0)
         {
            fFileNames.emplace_back(fn);
            Init();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a collection of file names.
         /// \param[in] fns Collection of file names containing the tree to process.
         /// \param[in] tn Name of the tree to process. If not provided,
         ///               the implementation will automatically search for a
         ///               tree in the collection of files.
         TTreeView(const std::vector<std::string_view>& fns, std::string_view tn) : fTreeName(tn), fCurrentIdx(0)
         {
            if (fns.size() > 0) {
               for (auto& fn : fns)
                  fFileNames.emplace_back(fn);
               Init();
            }
            else {
               ::Error("TreeView constructor", "The provided list of file names is empty, cannot process tree %s", fTreeName.data());
            }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a TTree.
         /// \param[in] tree Tree or chain of files containing the tree to process.
         TTreeView(TTree& tree) : fTreeName(tree.GetName()), fCurrentIdx(0)
         {
            static const TClassRef clRefTChain("TChain");
            if (clRefTChain == tree.IsA()) {
               TObjArray* filelist = dynamic_cast<TChain&>(tree).GetListOfFiles();
               if (filelist->GetEntries() > 0) {
                  for (auto f : *filelist)
                     fFileNames.emplace_back(f->GetTitle());
                  Init();
               }
               else {
                  ::Error("TreeView constructor", "The provided chain of files is empty, cannot process tree %s", fTreeName.data());
               }
            }
            else {
               fFileNames.emplace_back(tree.GetCurrentFile()->GetName());
               Init();
            }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Constructor based on a TTree and a TEntryList.
         /// \param[in] tree Tree or chain of files containing the tree to process.
         /// \param[in] entries List of entry numbers to process.
         TTreeView(TTree& tree, TEntryList& entries) : TTreeView(tree)
         {
            static const TClassRef clRefTChain("TChain");
            if (clRefTChain == tree.IsA()) {
               // We need to convert the global entry numbers to per-tree entry numbers.
               // This will allow us to build a TEntryList for a given entry range of a tree of the chain.
               size_t nTrees = fFileNames.size();
               fEntryLists.resize(nTrees);

               TChain *chain = dynamic_cast<TChain*>(&tree);
               Long64_t currListEntry  = entries.GetEntry(0);
               Long64_t currTreeOffset = 0;

               for (unsigned int treeNum = 0; treeNum < nTrees && currListEntry >= 0; ++treeNum) {
                  chain->LoadTree(currTreeOffset);
                  TTree *currTree = chain->GetTree();
                  Long64_t currTreeEntries = currTree->GetEntries();
                  Long64_t nextTreeOffset = currTreeOffset + currTreeEntries;

                  while (currListEntry >= 0 && currListEntry < nextTreeOffset) {
                     fEntryLists[treeNum].Enter(currListEntry - currTreeOffset);
                     currListEntry = entries.Next();
                  }

                  currTreeOffset = nextTreeOffset;
               }
            }
            else {
               fEntryLists.emplace_back(entries);
            }
         }

         //////////////////////////////////////////////////////////////////////////
         /// Copy constructor.
         /// \param[in] view Object to copy.
         TTreeView(const TTreeView& view) : fTreeName(view.fTreeName), fCurrentIdx(view.fCurrentIdx)
         {
            for (auto& fn : view.fFileNames)
               fFileNames.emplace_back(fn);

            for (auto& el : view.fEntryLists)
               fEntryLists.emplace_back(el);

            Init();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the cluster iterator for the current tree of this view, starting
         /// from entry zero.
         TTree::TClusterIterator GetClusterIterator()
         {
            return fCurrentTree->GetClusterIterator(0);
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get a TTreeReader for the current tree of this view.
         std::unique_ptr<TTreeReader> GetTreeReader(Long64_t start, Long64_t end)
         {
            TTreeReader *reader;
            if (fEntryLists.size() > 0 && fEntryLists[fCurrentIdx].GetN() > 0) {
               // TEntryList and SetEntriesRange do not work together (the former has precedence).
               // We need to construct a TEntryList that contains only those entry numbers
               // in our desired range.
               fCurrentEntryList.Reset();
               Long64_t entry = fEntryLists[fCurrentIdx].GetEntry(0);
               do {
                  if (entry >= start && entry < end) fCurrentEntryList.Enter(entry);
               } while ((entry = fEntryLists[fCurrentIdx].Next()) >= 0);

               reader = new TTreeReader(fCurrentTree, &fCurrentEntryList);

            }
            else {
               // If no TEntryList is involved we can safely set the range in the reader
               reader = new TTreeReader(fCurrentTree);
               reader->SetEntriesRange(start, end);
            }

            return std::unique_ptr<TTreeReader>(reader);
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the number of entries of the current tree of this view.
         Long64_t GetEntries() const
         {
            return fCurrentTree->GetEntries();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Get the number of files of this view.
         size_t GetNumFiles() const
         {
            return fFileNames.size();
         }

         //////////////////////////////////////////////////////////////////////////
         /// Set the current file and tree of this view.
         void SetCurrent(unsigned int i)
         {
            if (i != fCurrentIdx) {
               fCurrentIdx = i;
               TFile *f = TFile::Open(fFileNames[fCurrentIdx].data());
               fCurrentTree = (TTree*)f->Get(fTreeName.data());
               fCurrentTree->ResetBit(TObject::kMustCleanup);
               fCurrentFile.reset(f);
            }
         }
      };
   } // End of namespace Internal

   class TTreeProcessorMT {
   private:
      ROOT::TThreadedObject<ROOT::Internal::TTreeView> treeView; ///<! Threaded object with <file,tree> per thread

   public:
      TTreeProcessorMT(std::string_view filename, std::string_view treename = "");
      TTreeProcessorMT(const std::vector<std::string_view>& filenames, std::string_view treename = "");
      TTreeProcessorMT(TTree& tree);
      TTreeProcessorMT(TTree& tree, TEntryList& entries);

      void Process(std::function<void(TTreeReader&)> func);

   };

} // End of namespace ROOT

#endif // defined TTreeProcessorMT
<|endoftext|>


<commit_before>/*
* Arduino JSON library
* Benoit Blanchon 2014 - MIT License
*/

#include "JsonToken.h"

using namespace ArduinoJson::Parser;

static char unescapeChar(char c)
{
    switch (c)
    {
    case 'b': return '\b';
    case 'f': return '\f';
    case 'n': return '\n';
    case 'r': return '\r';
    case 't': return '\t';
    default: return c;
    }
}

static void unescapeString(char* s)
{
    char* readPtr = s;
    char* writePtr = s;

    while (true)
    {
        if (*readPtr == '\\')
        {
            readPtr++;
            *writePtr = unescapeChar(*readPtr);
        }
        else
        {
            *writePtr = *readPtr;
        }

        if (*writePtr == 0) break;

        readPtr++;
        writePtr++;
    }
}

char* JsonToken::getText()
{
    char* s = json + token->start;
    json[token->end] = 0;

    unescapeString(s);

    return s;
}

JsonToken JsonToken::nextSibling() const
{
    // start with current token
    jsmntok_t* t = token;

    // count the number of token to skip
    int yetToVisit = 1;

    // skip all nested tokens
    while (yetToVisit)
    {
        yetToVisit += t->size - 1;
        t++;
    }

    // build a JsonToken at the new location
    return JsonToken(json, t);
}<commit_msg>Reduced code size (-6 bytes)<commit_after>/*
* Arduino JSON library
* Benoit Blanchon 2014 - MIT License
*/

#include "JsonToken.h"

using namespace ArduinoJson::Parser;

static char unescapeChar(char c)
{
    switch (c)
    {
    case 'b': return '\b';
    case 'f': return '\f';
    case 'n': return '\n';
    case 'r': return '\r';
    case 't': return '\t';
    default: return c;
    }
}

static void unescapeString(char* s)
{
    char* readPtr = s;
    char* writePtr = s;
    char c;

    do
    {
        c = *readPtr++;

        if (c == '\\')
        {
            c = unescapeChar(*readPtr++);
        }

        *writePtr++ = c;

    } while (c != 0);
}

char* JsonToken::getText()
{
    char* s = json + token->start;
    json[token->end] = 0;

    unescapeString(s);

    return s;
}

JsonToken JsonToken::nextSibling() const
{
    // start with current token
    jsmntok_t* t = token;

    // count the number of token to skip
    int yetToVisit = 1;

    // skip all nested tokens
    while (yetToVisit)
    {
        yetToVisit += t->size - 1;
        t++;
    }

    // build a JsonToken at the new location
    return JsonToken(json, t);
}<|endoftext|>


<commit_before>// Copyright (c) 2011 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 <gmock/gmock.h>
#include <gtest/gtest.h>
#include <string>

#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/chromeos/extensions/file_browser_notifications.h"
#include "chrome/browser/chromeos/notifications/balloon_collection_impl.h"
#include "chrome/browser/notifications/balloon.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"

using ::testing::_;
using ::testing::InSequence;
using ::testing::Return;
using ::testing::StrEq;

namespace chromeos {

class MockNotificationUI : public BalloonCollectionImpl::NotificationUI {
 public:
  virtual ~MockNotificationUI() {}

  MOCK_METHOD1(Add, void(Balloon* balloon));
  MOCK_METHOD1(Update, bool(Balloon* balloon));
  MOCK_METHOD1(Remove, void(Balloon* balloon));
  MOCK_METHOD1(Show, void(Balloon* balloon));

  virtual void ResizeNotification(Balloon* balloon, const gfx::Size& size)
      OVERRIDE {
  }
  virtual void SetActiveView(BalloonViewImpl* view) OVERRIDE {}
};

class MockFileBrowserNotifications : public FileBrowserNotifications {
 public:
  explicit MockFileBrowserNotifications(Profile* profile)
      : FileBrowserNotifications(profile) {
  }
  virtual ~MockFileBrowserNotifications() {}

  virtual void PostDelayedShowNotificationTask(
      const std::string& notification_id,
      NotificationType type,
      const string16&  message,
      size_t delay_ms) {
    show_callback_data_.id = notification_id;
    show_callback_data_.type = type;
    show_callback_data_.message = message;
  }

  virtual void PostDelayedHideNotificationTask(NotificationType type,
                                               const std::string  path,
                                               size_t delay_ms) {
    hide_callback_data_.type = type;
    hide_callback_data_.path = path;
  }

  void ExecuteShow() {
    FileBrowserNotifications::ShowNotificationDelayedTask(
      show_callback_data_.id, show_callback_data_.type,
      show_callback_data_.message, AsWeakPtr());
  }

  void ExecuteHide() {
    FileBrowserNotifications::HideNotificationDelayedTask(
      hide_callback_data_.type, hide_callback_data_.path, AsWeakPtr());
  }

 private:
  struct ShowCallbackData {
    std::string id;
    NotificationType type;
    string16 message;
  };

  ShowCallbackData show_callback_data_;

  struct HideCallbackData {
    NotificationType type;
    std::string path;
  };

  HideCallbackData hide_callback_data_;
};

class FileBrowserNotificationsTest : public InProcessBrowserTest {
 public:
  FileBrowserNotificationsTest() {}

 protected:
  void ChangeNotificationUIMock() {
    // collection will take ownership of the mock.
    mock_notification_ui_ = new MockNotificationUI();
    collection_->set_notification_ui(mock_notification_ui_);
  }

  void InitNotificationUIMock() {
    collection_ = static_cast<BalloonCollectionImpl*>(
        g_browser_process->notification_ui_manager()->balloon_collection());
    ChangeNotificationUIMock();
  }

  bool FindNotification(const std::string& id) {
    return notifications_->notifications().find(id) !=
           notifications_->notifications().end();
  }

  BalloonCollectionImpl* collection_;
  MockNotificationUI* mock_notification_ui_;
  scoped_ptr<FileBrowserNotifications> notifications_;
};

MATCHER_P(BalloonNotificationMatcher, expected_id, "") {
  return arg->notification().notification_id() == expected_id;
}

IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, TestBasic) {
  InitNotificationUIMock();
  notifications_.reset(new MockFileBrowserNotifications(browser()->profile()));

  EXPECT_CALL(*mock_notification_ui_,
              Add(BalloonNotificationMatcher("Dpath")));
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");

  EXPECT_CALL(*mock_notification_ui_,
              Update(BalloonNotificationMatcher("Dpath")))
      .WillOnce(Return(true));
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");

  EXPECT_EQ(1u, notifications_->notifications().size());
  EXPECT_TRUE(FindNotification("Dpath"));

  EXPECT_CALL(*mock_notification_ui_,
              Add(BalloonNotificationMatcher("DFpath")));
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(2u, notifications_->notifications().size());
  EXPECT_TRUE(FindNotification("DFpath"));

  EXPECT_CALL(*mock_notification_ui_,
              Remove(BalloonNotificationMatcher("DFpath")));
  notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");

  EXPECT_EQ(1u, notifications_->notifications().size());
  EXPECT_FALSE(FindNotification("DFpath"));

  ui_test_utils::RunAllPendingInMessageLoop();

  ChangeNotificationUIMock();

  EXPECT_CALL(*mock_notification_ui_, Remove(_))
      .Times(1);
};

IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, ShowDelayedTest) {
  InitNotificationUIMock();
  MockFileBrowserNotifications* mocked_notifications =
      new MockFileBrowserNotifications(browser()->profile());
  notifications_.reset(mocked_notifications);

  EXPECT_CALL(*mock_notification_ui_,
              Add(BalloonNotificationMatcher("Dpath")));
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE,
                                          "path", 3000);
  mocked_notifications->ExecuteShow();

  EXPECT_CALL(*mock_notification_ui_,
              Add(BalloonNotificationMatcher("DFpath")));
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL,
                                          "path", 3000);
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");

  ChangeNotificationUIMock();
  EXPECT_CALL(*mock_notification_ui_,
              Update(BalloonNotificationMatcher("DFpath")));
  mocked_notifications->ExecuteShow();

  EXPECT_CALL(*mock_notification_ui_,
              Remove(BalloonNotificationMatcher("Fpath")))
      .Times(0);
  EXPECT_CALL(*mock_notification_ui_,
              Add(BalloonNotificationMatcher("Fpath")))
      .Times(0);
  notifications_->ShowNotificationDelayed(
      FileBrowserNotifications::FORMAT_FAIL, "path", 3000);
  notifications_->HideNotification(FileBrowserNotifications::FORMAT_FAIL,
                                   "path");
  ui_test_utils::RunAllPendingInMessageLoop();

  mocked_notifications->ExecuteShow();

  ChangeNotificationUIMock();
  EXPECT_CALL(*mock_notification_ui_, Remove(_))
      .Times(2);

  ui_test_utils::RunAllPendingInMessageLoop();
}

IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, HideDelayedTest) {
  InitNotificationUIMock();
  MockFileBrowserNotifications* mocked_notifications =
      new MockFileBrowserNotifications(browser()->profile());
  notifications_.reset(mocked_notifications);

  EXPECT_CALL(*mock_notification_ui_,
              Add(BalloonNotificationMatcher("Dpath")));
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");

  notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE,
                                          "path", 3000);
  ChangeNotificationUIMock();
  EXPECT_CALL(*mock_notification_ui_,
              Remove(BalloonNotificationMatcher("Dpath")));
  mocked_notifications->ExecuteHide();

  ui_test_utils::RunAllPendingInMessageLoop();

  EXPECT_CALL(*mock_notification_ui_,
              Add(BalloonNotificationMatcher("DFpath")));
  EXPECT_CALL(*mock_notification_ui_,
              Remove(BalloonNotificationMatcher("DFpath")));
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  ui_test_utils::RunAllPendingInMessageLoop();

  notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL,
                                          "path", 3000);
  ChangeNotificationUIMock();
  EXPECT_CALL(*mock_notification_ui_,
              Remove(BalloonNotificationMatcher("DFpath")))
      .Times(0);
  mocked_notifications->ExecuteHide();

  ui_test_utils::RunAllPendingInMessageLoop();
}

}  // namespace chromeos.

<commit_msg>Aura: Rewrite FileBrowserNotificationsTest<commit_after>// Copyright (c) 2011 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 "chrome/browser/chromeos/extensions/file_browser_notifications.h"

#include <gtest/gtest.h>
#include <string>

#include "chrome/browser/browser_process.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/notifications/balloon.h"
#include "chrome/browser/notifications/balloon_collection.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/notifications/notification_ui_manager.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"

namespace chromeos {

class MockFileBrowserNotifications : public FileBrowserNotifications {
 public:
  explicit MockFileBrowserNotifications(Profile* profile)
      : FileBrowserNotifications(profile) {
  }
  virtual ~MockFileBrowserNotifications() {}

  // Records the notification so we can force it to show later.
  virtual void PostDelayedShowNotificationTask(
      const std::string& notification_id,
      NotificationType type,
      const string16&  message,
      size_t delay_ms) OVERRIDE {
    show_callback_data_.id = notification_id;
    show_callback_data_.type = type;
    show_callback_data_.message = message;
  }

  // Records the notification so we can force it to hide later.
  virtual void PostDelayedHideNotificationTask(NotificationType type,
                                               const std::string  path,
                                               size_t delay_ms) OVERRIDE {
    hide_callback_data_.type = type;
    hide_callback_data_.path = path;
  }

  void ExecuteShow() {
    FileBrowserNotifications::ShowNotificationDelayedTask(
      show_callback_data_.id, show_callback_data_.type,
      show_callback_data_.message, AsWeakPtr());
  }

  void ExecuteHide() {
    FileBrowserNotifications::HideNotificationDelayedTask(
      hide_callback_data_.type, hide_callback_data_.path, AsWeakPtr());
  }

 private:
  struct ShowCallbackData {
    std::string id;
    NotificationType type;
    string16 message;
  };

  ShowCallbackData show_callback_data_;

  struct HideCallbackData {
    NotificationType type;
    std::string path;
  };

  HideCallbackData hide_callback_data_;
};

class FileBrowserNotificationsTest : public InProcessBrowserTest {
 public:
  FileBrowserNotificationsTest() : collection_(NULL) {}

 protected:
  // This must be initialized late in test startup.
  void InitNotifications() {
    Profile* profile = browser()->profile();
    notifications_.reset(new MockFileBrowserNotifications(profile));
    collection_ =
        g_browser_process->notification_ui_manager()->balloon_collection();
  }

  bool FindNotification(const std::string& id) {
    return notifications_->notifications().find(id) !=
           notifications_->notifications().end();
  }

  bool FindBalloon(const std::string& id) {
    const std::deque<Balloon*>& balloons = collection_->GetActiveBalloons();
    for (std::deque<Balloon*>::const_iterator it = balloons.begin();
         it != balloons.end();
         ++it) {
      Balloon* balloon = *it;
      if (balloon->notification().notification_id() == id)
        return true;
    }
    return false;
  }

  BalloonCollection* collection_;
  scoped_ptr<MockFileBrowserNotifications> notifications_;
};

#if defined(USE_AURA)
// TODO(jamescook): Fails on linux_chromeos_aura because we haven't implemented
// chromeos::SystemNotification yet.  http://crbug.com/104471
#define MAYBE_TestBasic FAILS_TestBasic
#else
#define MAYBE_TestBasic TestBasic
#endif
IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, MAYBE_TestBasic) {
  InitNotifications();
  // We start with no balloons.
  EXPECT_EQ(0u, collection_->GetActiveBalloons().size());

  // Showing a notification both updates our data and shows a balloon.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");
  EXPECT_EQ(1u, notifications_->notifications().size());
  EXPECT_TRUE(FindNotification("Dpath"));
  EXPECT_EQ(1u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("Dpath"));

  // Updating the same notification maintains the same balloon.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");
  EXPECT_EQ(1u, notifications_->notifications().size());
  EXPECT_TRUE(FindNotification("Dpath"));
  EXPECT_EQ(1u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("Dpath"));

  // A new notification adds a new balloon.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(2u, notifications_->notifications().size());
  EXPECT_TRUE(FindNotification("DFpath"));
  EXPECT_TRUE(FindNotification("Dpath"));
  EXPECT_EQ(2u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("DFpath"));
  EXPECT_TRUE(FindBalloon("Dpath"));

  // Hiding a notification removes it from our data.
  notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(1u, notifications_->notifications().size());
  EXPECT_FALSE(FindNotification("DFpath"));
  EXPECT_TRUE(FindNotification("Dpath"));

  // Balloons don't go away until we run the message loop.
  EXPECT_EQ(2u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("DFpath"));
  EXPECT_TRUE(FindBalloon("Dpath"));

  // Running the message loop allows the balloon to disappear.
  ui_test_utils::RunAllPendingInMessageLoop();
  EXPECT_EQ(1u, collection_->GetActiveBalloons().size());
  EXPECT_FALSE(FindBalloon("DFpath"));
  EXPECT_TRUE(FindBalloon("Dpath"));
};

#if defined(USE_AURA)
// TODO(jamescook): Fails on linux_chromeos_aura because we haven't implemented
// chromeos::SystemNotification yet.  http://crbug.com/104471
#define MAYBE_ShowDelayedTest FAILS_ShowDelayedTest
#else
// TODO(jamescook): This test is flaky on linux_chromeos, occasionally causing
// this assertion failure inside Gtk:
//   "murrine_style_draw_box: assertion `height >= -1' failed"
// There may be an underlying bug in the ChromeOS notification code.
// I'm not marking it as FLAKY because this doesn't happen on the bots.
#define MAYBE_ShowDelayedTest ShowDelayedTest
#endif
IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, MAYBE_ShowDelayedTest) {
  InitNotifications();
  // Adding a delayed notification does not show a balloon.
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE,
                                          "path", 3000);
  EXPECT_EQ(0u, collection_->GetActiveBalloons().size());

  // Forcing the show to happen makes the balloon appear.
  notifications_->ExecuteShow();
  ui_test_utils::RunAllPendingInMessageLoop();
  EXPECT_EQ(1u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("Dpath"));

  // Showing a notification both immediately and delayed results in one
  // additional balloon.
  notifications_->ShowNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL,
                                          "path", 3000);
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  EXPECT_EQ(2u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("Dpath"));
  EXPECT_TRUE(FindBalloon("DFpath"));

  // When the delayed notification arrives, it's an update, so we still only
  // have two balloons.
  notifications_->ExecuteShow();
  ui_test_utils::RunAllPendingInMessageLoop();
  EXPECT_EQ(2u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("Dpath"));
  EXPECT_TRUE(FindBalloon("DFpath"));

  // If we schedule a show for later, then hide before it becomes visible,
  // the balloon should not be added.
  notifications_->ShowNotificationDelayed(
      FileBrowserNotifications::FORMAT_FAIL, "path", 3000);
  notifications_->HideNotification(FileBrowserNotifications::FORMAT_FAIL,
                                   "path");
  EXPECT_EQ(2u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("Dpath"));
  EXPECT_TRUE(FindBalloon("DFpath"));
  EXPECT_FALSE(FindBalloon("Fpath"));

  // Even when we try to force the show, nothing appears, because the balloon
  // was explicitly hidden.
  notifications_->ExecuteShow();
  ui_test_utils::RunAllPendingInMessageLoop();
  EXPECT_EQ(2u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("Dpath"));
  EXPECT_TRUE(FindBalloon("DFpath"));
  EXPECT_FALSE(FindBalloon("Fpath"));
}

#if defined(USE_AURA)
// TODO(jamescook): Fails on linux_chromeos_aura because we haven't implemented
// chromeos::SystemNotification yet.  http://crbug.com/104471
#define MAYBE_HideDelayedTest FAILS_HideDelayedTest
#else
#define MAYBE_HideDelayedTest HideDelayedTest
#endif
IN_PROC_BROWSER_TEST_F(FileBrowserNotificationsTest, MAYBE_HideDelayedTest) {
  InitNotifications();
  // Showing now, and scheduling a hide for later, results in one balloon.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE, "path");
  notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE,
                                          "path", 3000);
  EXPECT_EQ(1u, collection_->GetActiveBalloons().size());
  EXPECT_TRUE(FindBalloon("Dpath"));

  // Forcing the hide removes the balloon.
  notifications_->ExecuteHide();
  ui_test_utils::RunAllPendingInMessageLoop();
  EXPECT_EQ(0u, collection_->GetActiveBalloons().size());

  // Immediate show then hide results in no balloons.
  notifications_->ShowNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  notifications_->HideNotification(FileBrowserNotifications::DEVICE_FAIL,
                                   "path");
  ui_test_utils::RunAllPendingInMessageLoop();
  EXPECT_EQ(0u, collection_->GetActiveBalloons().size());

  // Delayed hide for a notification that doesn't exist does nothing.
  notifications_->HideNotificationDelayed(FileBrowserNotifications::DEVICE_FAIL,
                                          "path", 3000);
  notifications_->ExecuteHide();
  ui_test_utils::RunAllPendingInMessageLoop();
  EXPECT_EQ(0u, collection_->GetActiveBalloons().size());
}

}  // namespace chromeos.
<|endoftext|>


<commit_before>//  1
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
	int day, month, year, lastday;
	cout << "Day Month Year:  ";
	cin >> day >> month >> year;
	bool leapYear =( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
	if (year <= 0 || day <=  0)
	{
		cout << "Invalid date" << endl;
		return 1;
	}
	switch (month)
	{
	case 1:case 4: case 6: case 9: case 11: lastday = 31;
		if (day>30)
		{
			cout << "Invalid date";
			return 1;
		}
		break;
	case 5: case 7: case 8: case 10: case 12: lastday = 30;
		if (day>31)
		{
			cout << "Invalid date";
			return 1;
		}
		break;

	case 3: if (leapYear) lastday = 29;
			else lastday = 28;
	case 2: lastday = 31;
			if (leapYear&&day>29)
			{
				cout << "Invalid date";
				return 1;
			}
			if (!leapYear&&day>28)
			{
				cout << "Invalid date";
				return 1;
			}

			break;
	default: cout << "Invalid date" << endl; return 1;

	}
	if (day == 1)

	if (month == 1)
	{
		day = 31;
		month = 12;
		year--;

	}
	else
	{
		month--;
		day = lastday;
	}

	else day--;
	cout << "Previous day is: ";
	printf("%02d.%02d.%d", day, month, year);

	return 0;

}
<commit_msg>Update task2.cpp<commit_after>
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
	int day, month, year, lastday;
	cout << "Day Month Year:  ";
	cin >> day >> month >> year;
	bool leapYear =( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
	if (year <= 0 || day <=  0)
	{
		cout << "Invalid date" << endl;
		return 1;
	}
	switch (month)
	{
	case 1:case 4: case 6: case 9: case 11: lastday = 31;
		if (day>30)
		{
			cout << "Invalid date";
			return 1;
		}
		break;
	case 5: case 7: case 8: case 10: case 12: lastday = 30;
		if (day>31)
		{
			cout << "Invalid date";
			return 1;
		}
		break;

	case 3: if (leapYear) lastday = 29;
			else lastday = 28;
	case 2: lastday = 31;
			if (leapYear&&day>29)
			{
				cout << "Invalid date";
				return 1;
			}
			if (!leapYear&&day>28)
			{
				cout << "Invalid date";
				return 1;
			}

			break;
	default: cout << "Invalid date" << endl; return 1;

	}
	if (day == 1)

	if (month == 1)
	{
		day = 31;
		month = 12;
		year--;

	}
	else
	{
		month--;
		day = lastday;
	}

	else day--;
	cout << "Previous day is: ";
	printf("%02d.%02d.%d", day, month, year);

	return 0;

}
<|endoftext|>


<commit_before>//
#include <iostream>
using namespace std;
int const Max_Size = 1000;
int const Max_Size_Numers = 9000;

bool IsEvenNumber(int arr[], int n)
{
	if (arr[n-1] % 2 == 0) return true;
	else return false;
}

int HowEvenNumbers(int arr[], int n,int count)
{

	if (n!=0)
	{
		if (IsEvenNumber(arr, n))
			count++;
			return HowEvenNumbers(arr, n - 1,count);

	}
	else return count;
}
int CopyNumbers(int  arr[], int n,int arr2[],int i)
{
	if (n != 0)
	{
		if (IsEvenNumber(arr, n))
		{
			arr2[i] = arr[n - 1];
			i++;
		}
	}
	else return 0;
	return CopyNumbers(arr, n - 1, arr2,i);

}

int main()
{

	int n;
	int count = 0;
	do{
		cout << "Enter how much number u want:";
		cin >> n;
	} while (n<0 && n>1000);
	int *arr = new (std::nothrow)int[n];
	for (int i = 0; i < n; i++)
	{
		cin >> arr[i];
	}
	int sizeOfarr2 = HowEvenNumbers(arr, n, count);
	cout << "There... are: "<< sizeOfarr2<<endl;
	int *arr2 = new (std::nothrow) int[sizeOfarr2];
	int i = 0;
	 CopyNumbers(arr, n, arr2,i);
	 cout << "Numbers are:" << endl;
	 for (int i = sizeOfarr2-1; i >= 0; i--)
	 {
		 cout<< arr2[i]<<endl;
	 }
	 system("pause");

	 return 0;
}<commit_msg>Update task2.cpp<commit_after>
#include <iostream>
using namespace std;
int const Max_Size = 1000;
int const Max_Size_Numers = 9000;

bool IsEvenNumber(int arr[], int n)
{
	if (arr[n-1] % 2 == 0) return true;
	else return false;
}

int HowEvenNumbers(int arr[], int n,int count)
{

	if (n!=0)
	{
		if (IsEvenNumber(arr, n))
			count++;
			return HowEvenNumbers(arr, n - 1,count);

	}
	else return count;
}
int CopyNumbers(int  arr[], int n,int arr2[],int i)
{
	if (n != 0)
	{
		if (IsEvenNumber(arr, n))
		{
			arr2[i] = arr[n - 1];
			i++;
		}
	}
	else return 0;
	return CopyNumbers(arr, n - 1, arr2,i);

}

int main()
{

	int n;
	int count = 0;
	do{
		cout << "Enter how much number u want:";
		cin >> n;
	} while (n<0 && n>1000);
	int *arr = new (std::nothrow)int[n];
	for (int i = 0; i < n; i++)
	{
		cin >> arr[i];
	}
	int sizeOfarr2 = HowEvenNumbers(arr, n, count);
	cout << "There... are: "<< sizeOfarr2<<endl;
	int *arr2 = new (std::nothrow) int[sizeOfarr2];
	int i = 0;
	 CopyNumbers(arr, n, arr2,i);
	 cout << "Numbers are:" << endl;
	 for (int i = sizeOfarr2-1; i >= 0; i--)
	 {
		 cout<< arr2[i]<<endl;
	 }
	 system("pause");

	 return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 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/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/password_manager/password_store.h"
#include "chrome/browser/sync/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/passwords_helper.h"
#include "chrome/browser/sync/test/integration/performance/sync_timing_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h"

using passwords_helper::AddLogin;
using passwords_helper::CreateTestPasswordForm;
using passwords_helper::GetLogins;
using passwords_helper::GetPasswordCount;
using passwords_helper::GetPasswordStore;
using passwords_helper::UpdateLogin;

static const int kNumPasswords = 150;

class PasswordsSyncPerfTest : public SyncTest {
 public:
  PasswordsSyncPerfTest() : SyncTest(TWO_CLIENT), password_number_(0) {}

  // Adds |num_logins| new unique passwords to |profile|.
  void AddLogins(int profile, int num_logins);

  // Updates the password for all logins for |profile|.
  void UpdateLogins(int profile);

  // Removes all logins for |profile|.
  void RemoveLogins(int profile);

 private:
  // Returns a new unique login.
  webkit_glue::PasswordForm NextLogin();

  // Returns a new unique password value.
  std::string NextPassword();

  int password_number_;
  DISALLOW_COPY_AND_ASSIGN(PasswordsSyncPerfTest);
};

void PasswordsSyncPerfTest::AddLogins(int profile, int num_logins) {
  for (int i = 0; i < num_logins; ++i) {
    AddLogin(GetPasswordStore(profile), NextLogin());
  }
}

void PasswordsSyncPerfTest::UpdateLogins(int profile) {
  std::vector<webkit_glue::PasswordForm> logins;
  GetLogins(GetPasswordStore(profile), logins);
  for (std::vector<webkit_glue::PasswordForm>::iterator it = logins.begin();
       it != logins.end(); ++it) {
    (*it).password_value = ASCIIToUTF16(NextPassword());
    UpdateLogin(GetPasswordStore(profile), (*it));
  }
}

void PasswordsSyncPerfTest::RemoveLogins(int profile) {
  passwords_helper::RemoveLogins(GetPasswordStore(profile));
}

webkit_glue::PasswordForm PasswordsSyncPerfTest::NextLogin() {
  return CreateTestPasswordForm(password_number_++);
}

std::string PasswordsSyncPerfTest::NextPassword() {
  return base::StringPrintf("password%d", password_number_++);
}

IN_PROC_BROWSER_TEST_F(PasswordsSyncPerfTest, P0) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  // TCM ID - 7367749.
  AddLogins(0, kNumPasswords);
  base::TimeDelta dt =
      SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumPasswords, GetPasswordCount(1));
  SyncTimingHelper::PrintResult("passwords", "add_passwords", dt);

  // TCM ID - 7365093.
  UpdateLogins(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumPasswords, GetPasswordCount(1));
  SyncTimingHelper::PrintResult("passwords", "update_passwords", dt);

  // TCM ID - 7557852
  RemoveLogins(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(0, GetPasswordCount(1));
  SyncTimingHelper::PrintResult("passwords", "delete_passwords", dt);
}
<commit_msg>Mark PasswordsSyncPerfTest.P0 flaky on Windows.<commit_after>// Copyright (c) 2011 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/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/password_manager/password_store.h"
#include "chrome/browser/sync/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/passwords_helper.h"
#include "chrome/browser/sync/test/integration/performance/sync_timing_helper.h"
#include "chrome/browser/sync/test/integration/sync_test.h"

using passwords_helper::AddLogin;
using passwords_helper::CreateTestPasswordForm;
using passwords_helper::GetLogins;
using passwords_helper::GetPasswordCount;
using passwords_helper::GetPasswordStore;
using passwords_helper::UpdateLogin;

static const int kNumPasswords = 150;

class PasswordsSyncPerfTest : public SyncTest {
 public:
  PasswordsSyncPerfTest() : SyncTest(TWO_CLIENT), password_number_(0) {}

  // Adds |num_logins| new unique passwords to |profile|.
  void AddLogins(int profile, int num_logins);

  // Updates the password for all logins for |profile|.
  void UpdateLogins(int profile);

  // Removes all logins for |profile|.
  void RemoveLogins(int profile);

 private:
  // Returns a new unique login.
  webkit_glue::PasswordForm NextLogin();

  // Returns a new unique password value.
  std::string NextPassword();

  int password_number_;
  DISALLOW_COPY_AND_ASSIGN(PasswordsSyncPerfTest);
};

void PasswordsSyncPerfTest::AddLogins(int profile, int num_logins) {
  for (int i = 0; i < num_logins; ++i) {
    AddLogin(GetPasswordStore(profile), NextLogin());
  }
}

void PasswordsSyncPerfTest::UpdateLogins(int profile) {
  std::vector<webkit_glue::PasswordForm> logins;
  GetLogins(GetPasswordStore(profile), logins);
  for (std::vector<webkit_glue::PasswordForm>::iterator it = logins.begin();
       it != logins.end(); ++it) {
    (*it).password_value = ASCIIToUTF16(NextPassword());
    UpdateLogin(GetPasswordStore(profile), (*it));
  }
}

void PasswordsSyncPerfTest::RemoveLogins(int profile) {
  passwords_helper::RemoveLogins(GetPasswordStore(profile));
}

webkit_glue::PasswordForm PasswordsSyncPerfTest::NextLogin() {
  return CreateTestPasswordForm(password_number_++);
}

std::string PasswordsSyncPerfTest::NextPassword() {
  return base::StringPrintf("password%d", password_number_++);
}

// Flaky on Windows, see http://crbug.com/105787
#if defined(OS_WIN)
#define MAYBE_P0 FLAKY_P0
#else
#define MAYBE_P0 P0
#endif

IN_PROC_BROWSER_TEST_F(PasswordsSyncPerfTest, MAYBE_P0) {
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";

  // TCM ID - 7367749.
  AddLogins(0, kNumPasswords);
  base::TimeDelta dt =
      SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumPasswords, GetPasswordCount(1));
  SyncTimingHelper::PrintResult("passwords", "add_passwords", dt);

  // TCM ID - 7365093.
  UpdateLogins(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(kNumPasswords, GetPasswordCount(1));
  SyncTimingHelper::PrintResult("passwords", "update_passwords", dt);

  // TCM ID - 7557852
  RemoveLogins(0);
  dt = SyncTimingHelper::TimeMutualSyncCycle(GetClient(0), GetClient(1));
  ASSERT_EQ(0, GetPasswordCount(1));
  SyncTimingHelper::PrintResult("passwords", "delete_passwords", dt);
}
<|endoftext|>


<commit_before>///
/// \package astlib
/// \file enumerate_symbols.cpp
///
/// \author Marian Krivos <marian.krivos@rsys.sk>
/// \date 13Feb.,2017
/// \brief definicia typu
///
/// (C) Copyright 2017 R-SYS s.r.o
/// All rights reserved.
///

#include "astlib/GeneratedTypes.h"
#include "astlib/model/BitsDescription.h"
#include "astlib/PrimitiveItem.h"

#include <Poco/Ascii.h>
#include <Poco/XML/Content.h>
#include "Poco/SAX/InputSource.h"
#include "Poco/DOM/DOMParser.h"
#include "Poco/DOM/Element.h"
#include "Poco/DOM/Attr.h"
#include "Poco/DOM/Node.h"
#include "Poco/DOM/Text.h"
#include "Poco/DOM/Element.h"
#include "Poco/DOM/Document.h"
#include "Poco/DOM/AutoPtr.h"
#include <Poco/AutoPtr.h>
#include "Poco/Exception.h"
#include "Poco/NumberParser.h"
#include "Poco/NumberFormatter.h"
#include <Poco/FileStream.h>
#include <Poco/Exception.h>
#include <Poco/DirectoryIterator.h>
#include <Poco/File.h>
#include <Poco/Path.h>
#include <Poco/String.h>

#include <iostream>
#include <map>

class BitsRegister
{
public:
    /**
     * Loads and registers all XML descriptions from directory.
     * @param path
     */
    std::vector<std::string> populateCodecsFromDirectory(const std::string& path)
    {
        auto dir = Poco::DirectoryIterator(path);
        auto end = Poco::DirectoryIterator();
        std::vector<std::string> files;

        while (dir != end)
        {
            Poco::File file = *dir;
            if (file.isFile())
            {
                Poco::Path filename = file.path();
                if (filename.getBaseName().find(std::string("asterix_cat")) == 0)
                {
                    files.push_back(file.path());
                }
            }
            ++dir;
        }

        return files;
    }

    void load(const std::string& filename)
    {
        try
        {
            Poco::XML::InputSource src(filename);
            Poco::XML::NamePool* pool = new Poco::XML::NamePool(3571);
            Poco::XML::DOMParser parser(pool);
            pool->release();

            parser.setFeature(Poco::XML::XMLReader::FEATURE_NAMESPACES, true);
            parser.setFeature(Poco::XML::DOMParser::FEATURE_FILTER_WHITESPACE, true);

            Poco::XML::AutoPtr<Poco::XML::Document> document = parser.parse(&src);
            poco_check_ptr (document);

            auto root = Poco::XML::AutoPtr<Poco::XML::Element>(document->documentElement(), true);

            if (root->nodeName() != "Category")
            {
                throw Poco::DataFormatException("no 'Category' element at top level");
            }

            loadCategory(*root);
        }
        catch(Poco::Exception& e)
        {
            throw Poco::Exception("CodecDeclarationLoader::load(" + filename + "): " + e.displayText());
        }
    }

    void loadCategory(const Poco::XML::Element& root)
    {
        for (auto node = root.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element)
            {
                auto name = element->nodeName();
                if (name == "DataItem")
                {
                    loadDataItem(*element);
                }
            }
        }
    }

    void loadDataItem(const Poco::XML::Element& element)
    {
        auto description = element.getChildElement("DataItemName")->innerText();
        Poco::XML::Element* formatElement = dynamic_cast<Poco::XML::Element*>(element.getChildElement("DataItemFormat")->firstChild());
        poco_assert(formatElement);

        loadFormatElement(*formatElement);
    }

    void loadFormatElement(const Poco::XML::Element& formatElement)
    {
        astlib::ItemFormat format = astlib::ItemFormat(formatElement.nodeName());

        switch (format.toValue())
        {
            case astlib::ItemFormat::Fixed:
                loadFixedDeclaration(formatElement);
                break;

            case astlib::ItemFormat::Variable:
                loadVariableDeclaration(formatElement);
                break;

            case astlib::ItemFormat::Repetitive:
                loadRepetitiveDeclaration(formatElement);
                break;

            case astlib::ItemFormat::Compound:
                loadCompoundDeclaration(formatElement);
                break;

            case astlib::ItemFormat::Explicit:
                loadExplicitDeclaration(formatElement);
                break;

            default:
                throw Poco::Exception("CodecDeclarationLoader::loadDataItem(): unknown item type " + format.toString());
        }
    }

    void loadFixedDeclaration(const Poco::XML::Element& element)
    {
        loadFixed(element);
    }

    void loadFixed(const Poco::XML::Element& element)
    {
        loadBitsDeclaration(element);
    }

    void loadVariableDeclaration(const Poco::XML::Element& parent)
    {
        for (auto node = parent.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element && element->nodeName() == "Fixed")
            {
                loadFixed(*element);
            }
        }
    }

    void loadRepetitiveDeclaration(const Poco::XML::Element& parent)
    {
        for (auto node = parent.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element && element->nodeName() == "Fixed")
            {
                loadFixed(*element);
            }
        }
    }

    void loadCompoundDeclaration(const Poco::XML::Element& parent)
    {
        for (auto node = parent.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element)
            {
                loadFormatElement(*element);
            }
        }
    }

    void loadExplicitDeclaration(const Poco::XML::Element& element)
    {
        // TODO:
    }

    void loadBitsDeclaration(const Poco::XML::Element& parent)
    {
        for (auto node = parent.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element && element->nodeType() == Poco::XML::Node::ELEMENT_NODE && element->nodeName() == "Bits")
            {
                astlib::BitsDescription bits;

                if (element->hasAttribute("bit"))
                {
                    bits.bit = Poco::NumberParser::parse(element->getAttribute("bit"));
                    if (element->hasAttribute("fx"))
                    {
                        bits.fx = Poco::NumberParser::parse(element->getAttribute("fx"));
                    }
                }
                else
                {
                    bits.from = Poco::NumberParser::parse(element->getAttribute("from"));
                    bits.to = Poco::NumberParser::parse(element->getAttribute("to"));
                    if (bits.from < bits.to)
                        std::swap(bits.from, bits.to);

                    // Enumerations
                    const Poco::XML::Element* node = dynamic_cast<const Poco::XML::Element*>(element->getChildElement("BitsValue"));
                    for(; node; node = dynamic_cast<const Poco::XML::Element*>(node->nextSibling()))
                    {
                        if (node->nodeName() == "BitsValue")
                        {
                            int value = Poco::NumberParser::parse(node->getAttribute("val"));
                            std::string key = node->innerText();
                            bits.addEnumeration(key, value);
                            //std::cout << "     enum " << key << " = " << value << std::endl;
                        }
                    }
                }

                if (element->hasAttribute("encode"))
                {
                    auto str = element->getAttribute("encode");
                    str[0] = Poco::Ascii::toUpper(str[0]);
                    if (str == "6bitschar")
                        str = "SixBitsChar";
                    bits.encoding = astlib::Encoding(str);
                }

                bits.name = dynamic_cast<const Poco::XML::Element*>(element->getChildElement("BitsShortName"))->innerText();
                Poco::toLowerInPlace(bits.name);
                Poco::replaceInPlace(bits.name, "_", ".");
                Poco::replaceInPlace(bits.name, "/", "_");

                const Poco::XML::Element* descrNode = dynamic_cast<const Poco::XML::Element*>(element->getChildElement("BitsName"));
                if (descrNode)
                {
                    bits.description = descrNode->innerText();
                }

                const Poco::XML::Element* unitNode = dynamic_cast<const Poco::XML::Element*>(element->getChildElement("BitsUnit"));
                if (unitNode)
                {
                    auto units = unitNode->innerText();
                    if (Poco::icompare(units, "M") == 0)
                    {
                        bits.units = astlib::Units::M;
                    }
                    else if (Poco::icompare(units, "NM") == 0)
                    {
                        bits.units = astlib::Units::NM;
                    }
                    else if (Poco::icompare(units, "FL") == 0)
                    {
                        bits.units = astlib::Units::FL;
                    }
                    else if (Poco::icompare(units, "FT") == 0)
                    {
                        bits.units = astlib::Units::FT;
                    }
                    else
                    {
                        //throw Exception("Unknown unit type in " + bits.name);
                    }

                    if (unitNode->hasAttribute("scale"))
                    {
                        bits.scale = Poco::NumberParser::parseFloat(unitNode->getAttribute("scale"));
                    }

                    if (unitNode->hasAttribute("min"))
                    {
                        bits.min = Poco::NumberParser::parseFloat(unitNode->getAttribute("min"));
                    }

                    if (unitNode->hasAttribute("max"))
                    {
                        bits.max = Poco::NumberParser::parseFloat(unitNode->getAttribute("max"));
                    }
                }

                //std::cout << "      " << bits.toString() << " enc " << bits.encoding.toString() << std::endl;
                addPrimitiveItem(bits);
            }
        }
    }

    void addPrimitiveItem(const astlib::BitsDescription& bits)
    {
        if (Poco::icompare(bits.name,"FX") == 0 ||
            Poco::icompare(bits.name, "spare") == 0 ||
            Poco::icompare(bits.name, "unused") == 0 ||
            bits.name.find(std::string(".presence")) != std::string::npos
        )
            return;

        astlib::PrimitiveType type;

        if (bits.effectiveBitsWidth() == 1)
        {
            type = astlib::PrimitiveType::Boolean;
        }
        else
        {
            if (bits.scale != 1.0)
            {
                type = astlib::PrimitiveType::Real;
            }
            else if (bits.encoding == astlib::Encoding::Signed)
            {
                type = astlib::PrimitiveType::Integer;
            }
            else if (bits.encoding == astlib::Encoding::Unsigned)
            {
                type = astlib::PrimitiveType::Unsigned;
            }
            else
            {
                type = astlib::PrimitiveType::String;
            }

        }

        symbols[bits.name] = astlib::PrimitiveItem(bits.name, bits.description, type);
    }

    std::map<std::string, astlib::PrimitiveItem> symbols;
};

int main(int argc, char* argv[])
{
    std::string specs = "specs";
    std::string module = "AsterixItemDictionary";

    if (argc > 1)
    {
        specs = argv[1];

        if (argc > 2)
            module = argv[2];
    }

    std::cout << "Reading specs: " << specs << std::endl;
    std::cout << "Generating source: " << module << "[.cpp .h]" << std::endl;

    try
    {
        BitsRegister bits;
        auto files = bits.populateCodecsFromDirectory(specs);

        Poco::FileOutputStream header(module + ".h");
        header << "/// @brief file generated from XML asterix descriptions" << std::endl << std::endl;
        header << "#pragma once" << std::endl << std::endl;
        header << "#include \"astlib/AsterixItemCode.h\"" << std::endl << std::endl;
        header << "namespace astlib {" << std::endl << std::endl;

        for(auto file: files)
        {
            bits.load(file);
        }

        auto& globals = bits.symbols;

        int index = 1;
        for (const auto& entry : globals)
        {
            astlib::PrimitiveItem item = entry.second;
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            header << "constexpr AsterixItemCode ASTERIX_CODE_" << upperName << "(" << Poco::NumberFormatter::formatHex(index, 4, true) << ", PrimitiveType::" << item.getType().toString() << ");  ///< " << item.getDescription() << std::endl;
            index++;
        }

        header << std::endl;

        for (const auto& entry : globals)
        {
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            header << "extern const std::string ASTERIX_SYMBOL_" << upperName << ";" << std::endl;
        }
        header << std::endl << "constexpr int ASTERIX_ITEM_COUNT = " << Poco::NumberFormatter::format(globals.size()) << ";" << std::endl << std::endl;

        header << "AsterixItemCode asterixSymbolToCode(const std::string& symbol);" << std::endl;
        header << "const std::string& asterixCodeToSymbol(AsterixItemCode code);" << std::endl;
        header << std::endl << "}" << std::endl;

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

        Poco::FileOutputStream source(module + ".cpp");
        source << "/// @brief file generated from XML asterix descriptions" << std::endl << std::endl;
        source << "#include \"" << module << ".h\"" << std::endl;
        source << "#include <unordered_map>" << std::endl << std::endl;
        source << "namespace astlib {" << std::endl << std::endl;

        for (const auto& entry : globals)
        {
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            source << "const std::string ASTERIX_SYMBOL_" << upperName << " = \"" << entry.first << "\";" << std::endl;
        }

        source << std::endl << std::endl;
        source << "static struct AsterixGeneratedEntry { const std::string& name; const std::string description; } codeToNameTable[ASTERIX_ITEM_COUNT] = {\n";

        for (const auto& entry : globals)
        {
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            source << "    { ASTERIX_SYMBOL_" << upperName << ", \"\" }," << std::endl;
        }
        source << "};" << std::endl << std::endl;

        source << "static std::unordered_map<std::string, AsterixItemCode> symbolToCodeMap = {" << std::endl;
        for (const auto& entry : globals)
        {
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            source << "    { ASTERIX_SYMBOL_" << upperName << ", ASTERIX_CODE_" << upperName << " }," << std::endl;
        }
        source << "};" << std::endl << std::endl;

        const char functions[] = "AsterixItemCode asterixSymbolToCode(const std::string& symbol)\n"
            "{\n"
            "    return symbolToCodeMap[symbol];\n"
            "}\n"
            "\n"
            "const std::string& asterixCodeToSymbol(AsterixItemCode code)\n"
            "{\n"
            "    int index = code.code();\n"
            "    poco_assert(index < ASTERIX_ITEM_COUNT);\n"
            "    return codeToNameTable[index+1].name;\n"
            "}\n";

        source << functions << std::endl;

        source << "}" << std::endl;
    }
    catch(Poco::Exception& e)
    {
        std::cerr << e.displayText() << std::endl;
        return 1;
    }

    return 0;
}

<commit_msg>codegen fix<commit_after>///
/// \package astlib
/// \file enumerate_symbols.cpp
///
/// \author Marian Krivos <marian.krivos@rsys.sk>
/// \date 13Feb.,2017
/// \brief definicia typu
///
/// (C) Copyright 2017 R-SYS s.r.o
/// All rights reserved.
///

#include "astlib/GeneratedTypes.h"
#include "astlib/model/BitsDescription.h"
#include "astlib/PrimitiveItem.h"

#include <Poco/Ascii.h>
#include <Poco/XML/Content.h>
#include "Poco/SAX/InputSource.h"
#include "Poco/DOM/DOMParser.h"
#include "Poco/DOM/Element.h"
#include "Poco/DOM/Attr.h"
#include "Poco/DOM/Node.h"
#include "Poco/DOM/Text.h"
#include "Poco/DOM/Element.h"
#include "Poco/DOM/Document.h"
#include "Poco/DOM/AutoPtr.h"
#include <Poco/AutoPtr.h>
#include "Poco/Exception.h"
#include "Poco/NumberParser.h"
#include "Poco/NumberFormatter.h"
#include <Poco/FileStream.h>
#include <Poco/Exception.h>
#include <Poco/DirectoryIterator.h>
#include <Poco/File.h>
#include <Poco/Path.h>
#include <Poco/String.h>

#include <iostream>
#include <map>

class BitsRegister
{
public:
    /**
     * Loads and registers all XML descriptions from directory.
     * @param path
     */
    std::vector<std::string> populateCodecsFromDirectory(const std::string& path)
    {
        auto dir = Poco::DirectoryIterator(path);
        auto end = Poco::DirectoryIterator();
        std::vector<std::string> files;

        while (dir != end)
        {
            Poco::File file = *dir;
            if (file.isFile())
            {
                Poco::Path filename = file.path();
                if (filename.getBaseName().find(std::string("asterix_cat")) == 0)
                {
                    files.push_back(file.path());
                }
            }
            ++dir;
        }

        return files;
    }

    void load(const std::string& filename)
    {
        try
        {
            Poco::XML::InputSource src(filename);
            Poco::XML::NamePool* pool = new Poco::XML::NamePool(3571);
            Poco::XML::DOMParser parser(pool);
            pool->release();

            parser.setFeature(Poco::XML::XMLReader::FEATURE_NAMESPACES, true);
            parser.setFeature(Poco::XML::DOMParser::FEATURE_FILTER_WHITESPACE, true);

            Poco::XML::AutoPtr<Poco::XML::Document> document = parser.parse(&src);
            poco_check_ptr (document);

            auto root = Poco::XML::AutoPtr<Poco::XML::Element>(document->documentElement(), true);

            if (root->nodeName() != "Category")
            {
                throw Poco::DataFormatException("no 'Category' element at top level");
            }

            loadCategory(*root);
        }
        catch(Poco::Exception& e)
        {
            throw Poco::Exception("CodecDeclarationLoader::load(" + filename + "): " + e.displayText());
        }
    }

    void loadCategory(const Poco::XML::Element& root)
    {
        for (auto node = root.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element)
            {
                auto name = element->nodeName();
                if (name == "DataItem")
                {
                    loadDataItem(*element);
                }
            }
        }
    }

    void loadDataItem(const Poco::XML::Element& element)
    {
        auto description = element.getChildElement("DataItemName")->innerText();
        Poco::XML::Element* formatElement = dynamic_cast<Poco::XML::Element*>(element.getChildElement("DataItemFormat")->firstChild());
        poco_assert(formatElement);

        loadFormatElement(*formatElement);
    }

    void loadFormatElement(const Poco::XML::Element& formatElement)
    {
        astlib::ItemFormat format = astlib::ItemFormat(formatElement.nodeName());

        switch (format.toValue())
        {
            case astlib::ItemFormat::Fixed:
                loadFixedDeclaration(formatElement);
                break;

            case astlib::ItemFormat::Variable:
                loadVariableDeclaration(formatElement);
                break;

            case astlib::ItemFormat::Repetitive:
                loadRepetitiveDeclaration(formatElement);
                break;

            case astlib::ItemFormat::Compound:
                loadCompoundDeclaration(formatElement);
                break;

            case astlib::ItemFormat::Explicit:
                loadExplicitDeclaration(formatElement);
                break;

            default:
                throw Poco::Exception("CodecDeclarationLoader::loadDataItem(): unknown item type " + format.toString());
        }
    }

    void loadFixedDeclaration(const Poco::XML::Element& element)
    {
        loadFixed(element);
    }

    void loadFixed(const Poco::XML::Element& element)
    {
        loadBitsDeclaration(element);
    }

    void loadVariableDeclaration(const Poco::XML::Element& parent)
    {
        for (auto node = parent.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element && element->nodeName() == "Fixed")
            {
                loadFixed(*element);
            }
        }
    }

    void loadRepetitiveDeclaration(const Poco::XML::Element& parent)
    {
        for (auto node = parent.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element && element->nodeName() == "Fixed")
            {
                loadFixed(*element);
            }
        }
    }

    void loadCompoundDeclaration(const Poco::XML::Element& parent)
    {
        for (auto node = parent.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element)
            {
                loadFormatElement(*element);
            }
        }
    }

    void loadExplicitDeclaration(const Poco::XML::Element& element)
    {
        // TODO:
    }

    void loadBitsDeclaration(const Poco::XML::Element& parent)
    {
        for (auto node = parent.firstChild(); node; node = node->nextSibling())
        {
            const Poco::XML::Element* element = dynamic_cast<Poco::XML::Element*>(node);
            if (element && element->nodeType() == Poco::XML::Node::ELEMENT_NODE && element->nodeName() == "Bits")
            {
                astlib::BitsDescription bits;

                if (element->hasAttribute("bit"))
                {
                    bits.bit = Poco::NumberParser::parse(element->getAttribute("bit"));
                    if (element->hasAttribute("fx"))
                    {
                        bits.fx = Poco::NumberParser::parse(element->getAttribute("fx"));
                    }
                }
                else
                {
                    bits.from = Poco::NumberParser::parse(element->getAttribute("from"));
                    bits.to = Poco::NumberParser::parse(element->getAttribute("to"));
                    if (bits.from < bits.to)
                        std::swap(bits.from, bits.to);

                    // Enumerations
                    const Poco::XML::Element* node = dynamic_cast<const Poco::XML::Element*>(element->getChildElement("BitsValue"));
                    for(; node; node = dynamic_cast<const Poco::XML::Element*>(node->nextSibling()))
                    {
                        if (node->nodeName() == "BitsValue")
                        {
                            int value = Poco::NumberParser::parse(node->getAttribute("val"));
                            std::string key = node->innerText();
                            bits.addEnumeration(key, value);
                            //std::cout << "     enum " << key << " = " << value << std::endl;
                        }
                    }
                }

                if (element->hasAttribute("encode"))
                {
                    auto str = element->getAttribute("encode");
                    str[0] = Poco::Ascii::toUpper(str[0]);
                    if (str == "6bitschar")
                        str = "SixBitsChar";
                    bits.encoding = astlib::Encoding(str);
                }

                bits.name = dynamic_cast<const Poco::XML::Element*>(element->getChildElement("BitsShortName"))->innerText();
                Poco::toLowerInPlace(bits.name);
                Poco::replaceInPlace(bits.name, "_", ".");
                Poco::replaceInPlace(bits.name, "/", "_");

                const Poco::XML::Element* descrNode = dynamic_cast<const Poco::XML::Element*>(element->getChildElement("BitsName"));
                if (descrNode)
                {
                    bits.description = descrNode->innerText();
                }

                const Poco::XML::Element* unitNode = dynamic_cast<const Poco::XML::Element*>(element->getChildElement("BitsUnit"));
                if (unitNode)
                {
                    auto units = unitNode->innerText();
                    if (Poco::icompare(units, "M") == 0)
                    {
                        bits.units = astlib::Units::M;
                    }
                    else if (Poco::icompare(units, "NM") == 0)
                    {
                        bits.units = astlib::Units::NM;
                    }
                    else if (Poco::icompare(units, "FL") == 0)
                    {
                        bits.units = astlib::Units::FL;
                    }
                    else if (Poco::icompare(units, "FT") == 0)
                    {
                        bits.units = astlib::Units::FT;
                    }
                    else
                    {
                        //throw Exception("Unknown unit type in " + bits.name);
                    }

                    if (unitNode->hasAttribute("scale"))
                    {
                        bits.scale = Poco::NumberParser::parseFloat(unitNode->getAttribute("scale"));
                    }

                    if (unitNode->hasAttribute("min"))
                    {
                        bits.min = Poco::NumberParser::parseFloat(unitNode->getAttribute("min"));
                    }

                    if (unitNode->hasAttribute("max"))
                    {
                        bits.max = Poco::NumberParser::parseFloat(unitNode->getAttribute("max"));
                    }
                }

                //std::cout << "      " << bits.toString() << " enc " << bits.encoding.toString() << std::endl;
                addPrimitiveItem(bits);
            }
        }
    }

    void addPrimitiveItem(const astlib::BitsDescription& bits)
    {
        if (Poco::icompare(bits.name,"FX") == 0 ||
            Poco::icompare(bits.name, "spare") == 0 ||
            Poco::icompare(bits.name, "unused") == 0 ||
            bits.name.find(std::string(".presence")) != std::string::npos
        )
            return;

        astlib::PrimitiveType type;

        if (bits.effectiveBitsWidth() == 1)
        {
            type = astlib::PrimitiveType::Boolean;
        }
        else
        {
            if (bits.scale != 1.0)
            {
                type = astlib::PrimitiveType::Real;
            }
            else if (bits.encoding == astlib::Encoding::Signed)
            {
                type = astlib::PrimitiveType::Integer;
            }
            else if (bits.encoding == astlib::Encoding::Unsigned)
            {
                type = astlib::PrimitiveType::Unsigned;
            }
            else
            {
                type = astlib::PrimitiveType::String;
            }

        }

        if (symbols.find(bits.name) == symbols.end())
        {
            symbols[bits.name] = astlib::PrimitiveItem(bits.name, bits.description, type);
        }
        else
        {
            astlib::PrimitiveItem item = symbols[bits.name];
            if (item.getDescription().size() < bits.description.size())
                symbols[bits.name] = astlib::PrimitiveItem(bits.name, bits.description, type);
            // TODO: test type equality, other error
        }
    }

    std::map<std::string, astlib::PrimitiveItem> symbols;
};

int main(int argc, char* argv[])
{
    std::string specs = "specs";
    std::string module = "AsterixItemDictionary";

    if (argc > 1)
    {
        specs = argv[1];

        if (argc > 2)
            module = argv[2];
    }

    std::cout << "Reading specs: " << specs << std::endl;
    std::cout << "Generating source: " << module << "[.cpp .h]" << std::endl;

    try
    {
        BitsRegister bits;
        auto files = bits.populateCodecsFromDirectory(specs);

        Poco::FileOutputStream header(module + ".h");
        header << "/// @brief file generated from XML asterix descriptions" << std::endl << std::endl;
        header << "#pragma once" << std::endl << std::endl;
        header << "#include \"astlib/AsterixItemCode.h\"" << std::endl << std::endl;
        header << "namespace astlib {" << std::endl << std::endl;

        for(auto file: files)
        {
            bits.load(file);
        }

        auto& globals = bits.symbols;

        int index = 1;
        for (const auto& entry : globals)
        {
            astlib::PrimitiveItem item = entry.second;
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            header << "constexpr AsterixItemCode ASTERIX_CODE_" << upperName << "(" << Poco::NumberFormatter::formatHex(index, 4, true) << ", PrimitiveType::" << item.getType().toString() << ");  ///< " << item.getDescription() << std::endl;
            index++;
        }

        header << std::endl;

        for (const auto& entry : globals)
        {
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            header << "extern const std::string ASTERIX_SYMBOL_" << upperName << ";" << std::endl;
        }
        header << std::endl << "constexpr int ASTERIX_ITEM_COUNT = " << Poco::NumberFormatter::format(globals.size()) << ";" << std::endl << std::endl;

        header << "AsterixItemCode asterixSymbolToCode(const std::string& symbol);" << std::endl;
        header << "const std::string& asterixCodeToSymbol(AsterixItemCode code);" << std::endl;
        header << std::endl << "}" << std::endl;

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

        Poco::FileOutputStream source(module + ".cpp");
        source << "/// @brief file generated from XML asterix descriptions" << std::endl << std::endl;
        source << "#include \"" << module << ".h\"" << std::endl;
        source << "#include <unordered_map>" << std::endl << std::endl;
        source << "namespace astlib {" << std::endl << std::endl;

        for (const auto& entry : globals)
        {
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            source << "const std::string ASTERIX_SYMBOL_" << upperName << " = \"" << entry.first << "\";" << std::endl;
        }

        source << std::endl << std::endl;
        source << "static struct AsterixGeneratedEntry { const std::string& name; const std::string description; } codeToNameTable[ASTERIX_ITEM_COUNT] = {\n";

        for (const auto& entry : globals)
        {
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            source << "    { ASTERIX_SYMBOL_" << upperName << ", \"\" }," << std::endl;
        }
        source << "};" << std::endl << std::endl;

        source << "static std::unordered_map<std::string, AsterixItemCode> symbolToCodeMap = {" << std::endl;
        for (const auto& entry : globals)
        {
            std::string upperName = Poco::toUpper(entry.first);
            Poco::replaceInPlace(upperName, ".", "_");

            source << "    { ASTERIX_SYMBOL_" << upperName << ", ASTERIX_CODE_" << upperName << " }," << std::endl;
        }
        source << "};" << std::endl << std::endl;

        const char functions[] = "AsterixItemCode asterixSymbolToCode(const std::string& symbol)\n"
            "{\n"
            "    return symbolToCodeMap[symbol];\n"
            "}\n"
            "\n"
            "const std::string& asterixCodeToSymbol(AsterixItemCode code)\n"
            "{\n"
            "    int index = code.code();\n"
            "    poco_assert(index < ASTERIX_ITEM_COUNT);\n"
            "    return codeToNameTable[index+1].name;\n"
            "}\n";

        source << functions << std::endl;

        source << "}" << std::endl;
    }
    catch(Poco::Exception& e)
    {
        std::cerr << e.displayText() << std::endl;
        return 1;
    }

    return 0;
}

<|endoftext|>