<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *  Copyright (c) 2012-, Open Perception, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <pcl/pcl_config.h>
#define HAVE_PXCAPI
#ifdef HAVE_PXCAPI

#include <pcl/io/pxc_grabber.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/time.h>
#include <pcl/common/io.h>
#include <pcl/console/print.h>
#include <pcl/io/boost.h>
#include <pcl/exceptions.h>

#include <boost/thread.hpp>

#include <iostream>
#include <queue>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pcl::PXCGrabber::PXCGrabber ()
  : pp_ ()
  , running_ (false)
  , fps_ (0.0f)
{
  point_cloud_signal_      = createSignal<sig_cb_pxc_point_cloud> ();
  point_cloud_rgb_signal_  = createSignal<sig_cb_pxc_point_cloud_rgb> ();
  point_cloud_rgba_signal_ = createSignal<sig_cb_pxc_point_cloud_rgba> ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pcl::PXCGrabber::~PXCGrabber () throw ()
{
  stop ();

  disconnect_all_slots<sig_cb_pxc_point_cloud> ();
  disconnect_all_slots<sig_cb_pxc_point_cloud_rgb> ();
  disconnect_all_slots<sig_cb_pxc_point_cloud_rgba> ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PXCGrabber::init ()
{
  // enable rgb and 3d data and initialize
  pp_.EnableImage(PXCImage::COLOR_FORMAT_RGB32);
  pp_.EnableImage(PXCImage::COLOR_FORMAT_VERTICES);
  pp_.Init ();

  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PXCGrabber::close ()
{
  pp_.Close ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PXCGrabber::start ()
{
  init ();
  running_ = true;

  grabber_thread_ = boost::thread(&pcl::PXCGrabber::processGrabbing, this);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PXCGrabber::stop ()
{
  running_ = false;
  grabber_thread_.join ();

  close ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PXCGrabber::isRunning () const
{
  return (running_);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::string
pcl::PXCGrabber::getName () const
{
  return (std::string ("PXCGrabber"));
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float
pcl::PXCGrabber::getFramesPerSecond () const
{
  fps_mutex_.lock ();
  float fps = fps_;
  fps_mutex_.unlock ();

  return (fps);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PXCGrabber::processGrabbing ()
{
  UtilCapture * cap = pp_.QueryCapture ();
  PXCCapture * capture = cap->QueryCapture ();
  PXCSession * session = pp_.QuerySession ();

  // special depth values for saturated and low-confidence pixels
  pxcF32 dvalues[2];

  // projection serializable identifier
  pxcUID prj_value;
  PXCSmartPtr<PXCProjection> projection;

  //PXCCapture::VideoStream::ProfileInfo rgbStreamInfo;
  //PXCCapture::VideoStream::ProfileInfo depthStreamInfo;

  // stream profile for the color stream
  //cap->QueryVideoStream(0)->QueryProfile(&rgbStreamInfo);
  //cout << "rgbStreamInfo.imageInfo.width: " << rgbStreamInfo.imageInfo.width << endl;

  // stream profile for the depth stream
  //cap->QueryVideoStream(1)->QueryProfile(&depthStreamInfo);
  //cout << "depthStreamInfo.imageInfo.width: " << depthStreamInfo.imageInfo.width << endl;

  // set the desired value for smoothing the depth data
  //cap->QueryDevice()->SetProperty(PXCCapture::Device::PROPERTY_DEPTH_SMOOTHING, 1);

  // setup the projection info for getting a nice depth map
  pxcStatus sts = cap->QueryDevice()->QueryPropertyAsUID(PXCCapture::Device::PROPERTY_PROJECTION_SERIALIZABLE, &prj_value);
  if (sts >= PXC_STATUS_NO_ERROR)
  {
    // create properties for checking if depth values are bad (by low confidence and by saturation)
    cap->QueryDevice()->QueryProperty(PXCCapture::Device::PROPERTY_DEPTH_LOW_CONFIDENCE_VALUE, &dvalues[0]);
    cap->QueryDevice()->QueryProperty(PXCCapture::Device::PROPERTY_DEPTH_SATURATION_VALUE, &dvalues[1]);

    session->DynamicCast<PXCMetadata>()->CreateSerializable<PXCProjection>(prj_value, &projection);
  }

  pcl::StopWatch stop_watch;
  std::queue<double> capture_time_queue;
  double total_time = 0.0f;

  stop_watch.reset ();

  bool continue_grabbing = true;
  while (continue_grabbing)
  {
    if (!pp_.AcquireFrame(true))
    {
      boost::this_thread::sleep (boost::posix_time::milliseconds(1));
      continue;
    }

    // query rgb and 3d data
    PXCImage *color_image=pp_.QueryImage(PXCImage::IMAGE_TYPE_COLOR);
    PXCImage *vertex_image=pp_.QueryImage(PXCImage::IMAGE_TYPE_DEPTH);

    // acquiure access to data
    PXCImage::ImageData ddata;
    vertex_image->AcquireAccess(PXCImage::ACCESS_READ, &ddata);
    short * vertices = (short*) ddata.planes[0];

    PXCImage::ImageData idata;
    color_image->AcquireAccess(PXCImage::ACCESS_READ, &idata);
    unsigned char * rgb_image_data = (unsigned char*) idata.planes[0];

    // get image information
    PXCImage::ImageInfo vertImageInfo;
    pxcStatus stat = vertex_image->QueryInfo(&vertImageInfo);
    const int w = vertImageInfo.width;
    const int h = vertImageInfo.height;

    PXCImage::ImageInfo rgb_image_info;
    stat = color_image->QueryInfo(&rgb_image_info);
    const int image_width = rgb_image_info.width;
    const int image_height = rgb_image_info.height;

    // convert to point cloud
    const float nan_value = std::numeric_limits<float>::quiet_NaN ();

    int dwidth2=ddata.pitches[0]/sizeof(pxcU16);
    float *uvmap=(float*)ddata.planes[2];
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA> (w, h));
    for (int j = 0, k = 0; j < h; j++)
    {
      for (int i = 0; i < w; i++, k++)
      {
        int xx=(int)(uvmap[(j*w+i)*2+0]*image_width+0.5f);
        int yy=(int)(uvmap[(j*w+i)*2+1]*image_height+0.5f);

        unsigned int idx = 3*(j*w + i);
        short x = vertices[idx];
        short y = vertices[idx+1];
        short z = vertices[idx+2];

        unsigned char r = 255;
        unsigned char g = 255;
        unsigned char b = 255;

        if (xx < 0 || xx >= image_width || yy < 0 || yy >= image_height)
        {
          r = 255;
          g = 255;
          b = 255;
        }
        else
        {
          unsigned char * rgb_ptr = rgb_image_data + 3*(yy*image_width+xx);
          r = rgb_ptr[2];
          g = rgb_ptr[1];
          b = rgb_ptr[0];
        }

        if (z == dvalues[0] || z == dvalues[1])
        {
          cloud->points[k].x = nan_value;
          cloud->points[k].y = nan_value;
          cloud->points[k].z = nan_value;
          cloud->points[k].r = r;
          cloud->points[k].g = g;
          cloud->points[k].b = b;
          cloud->points[k].a = 255;
        }
        else
        {
          // normalize vertices to meters
          cloud->points[k].x = x / 1000.0f;
          cloud->points[k].y = y / 1000.0f;
          cloud->points[k].z = z / 1000.0f;
          cloud->points[k].r = r;
          cloud->points[k].g = g;
          cloud->points[k].b = b;
          cloud->points[k].a = 255;
        }
      }
    }

    // publish cloud
    if (num_slots<sig_cb_pxc_point_cloud_rgba> () > 0)
    {
      point_cloud_rgba_signal_->operator() (cloud);
    }
    if (num_slots<sig_cb_pxc_point_cloud_rgb> () > 0)
    {
      pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZRGB> ());
      cloud->resize (w*h);
      cloud->width = w;
      cloud->height = h;
      cloud->is_dense = false;

      pcl::copyPointCloud<pcl::PointXYZRGBA, pcl::PointXYZRGB> (*cloud, *tmp_cloud);

      point_cloud_rgb_signal_->operator() (tmp_cloud);
    }
    if (num_slots<sig_cb_pxc_point_cloud> () > 0)
    {
      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_tmp (new pcl::PointCloud<pcl::PointXYZ> ());
      cloud->resize (w*h);
      cloud->width = w;
      cloud->height = h;
      cloud->is_dense = false;

      pcl::copyPointCloud<pcl::PointXYZRGBA, pcl::PointXYZ> (*cloud, *cloud_tmp);

      point_cloud_signal_->operator() (cloud_tmp);
    }

    pp_.ReleaseFrame();

    const double capture_time = stop_watch.getTimeSeconds ();
    total_time += capture_time;

    capture_time_queue.push (capture_time);

    if (capture_time_queue.size () >= 30)
    {
      double removed_time = capture_time_queue.front ();
      capture_time_queue.pop ();

      total_time -= removed_time;
    }

    fps_mutex_.lock ();
    fps_ = static_cast<float> (total_time / capture_time_queue.size ());
    fps_mutex_.unlock ();
  }
}

#endif
<commit_msg>fixed some coding-standard issues and removed some commented code<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2012-, Open Perception, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <pcl/pcl_config.h>
#define HAVE_PXCAPI
#ifdef HAVE_PXCAPI

#include <pcl/io/pxc_grabber.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/time.h>
#include <pcl/common/io.h>
#include <pcl/console/print.h>
#include <pcl/io/boost.h>
#include <pcl/exceptions.h>

#include <boost/thread.hpp>

#include <iostream>
#include <queue>

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pcl::PXCGrabber::PXCGrabber ()
  : pp_ ()
  , running_ (false)
  , fps_ (0.0f)
{
  point_cloud_signal_      = createSignal<sig_cb_pxc_point_cloud> ();
  point_cloud_rgb_signal_  = createSignal<sig_cb_pxc_point_cloud_rgb> ();
  point_cloud_rgba_signal_ = createSignal<sig_cb_pxc_point_cloud_rgba> ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pcl::PXCGrabber::~PXCGrabber () throw ()
{
  stop ();

  disconnect_all_slots<sig_cb_pxc_point_cloud> ();
  disconnect_all_slots<sig_cb_pxc_point_cloud_rgb> ();
  disconnect_all_slots<sig_cb_pxc_point_cloud_rgba> ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PXCGrabber::init ()
{
  // enable rgb and 3d data and initialize
  pp_.EnableImage (PXCImage::COLOR_FORMAT_RGB32);
  pp_.EnableImage (PXCImage::COLOR_FORMAT_VERTICES);
  pp_.Init ();

  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PXCGrabber::close ()
{
  pp_.Close ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PXCGrabber::start ()
{
  init ();
  running_ = true;

  grabber_thread_ = boost::thread (&pcl::PXCGrabber::processGrabbing, this);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PXCGrabber::stop ()
{
  running_ = false;
  grabber_thread_.join ();

  close ();
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PXCGrabber::isRunning () const
{
  return (running_);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
std::string
pcl::PXCGrabber::getName () const
{
  return (std::string ("PXCGrabber"));
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float
pcl::PXCGrabber::getFramesPerSecond () const
{
  fps_mutex_.lock ();
  float fps = fps_;
  fps_mutex_.unlock ();

  return (fps);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PXCGrabber::processGrabbing ()
{
  UtilCapture * cap = pp_.QueryCapture ();
  PXCCapture * capture = cap->QueryCapture ();
  PXCSession * session = pp_.QuerySession ();

  // special depth values for saturated and low-confidence pixels
  pxcF32 dvalues[2];

  // projection serializable identifier
  pxcUID prj_value;
  PXCSmartPtr<PXCProjection> projection;

  // setup the projection info for getting a nice depth map
  pxcStatus sts = cap->QueryDevice ()->QueryPropertyAsUID (PXCCapture::Device::PROPERTY_PROJECTION_SERIALIZABLE, &prj_value);
  if (sts >= PXC_STATUS_NO_ERROR)
  {
    // create properties for checking if depth values are bad (by low confidence and by saturation)
    cap->QueryDevice ()->QueryProperty (PXCCapture::Device::PROPERTY_DEPTH_LOW_CONFIDENCE_VALUE, &dvalues[0]);
    cap->QueryDevice ()->QueryProperty (PXCCapture::Device::PROPERTY_DEPTH_SATURATION_VALUE, &dvalues[1]);

    session->DynamicCast<PXCMetadata> ()->CreateSerializable<PXCProjection> (prj_value, &projection);
  }

  pcl::StopWatch stop_watch;
  std::queue<double> capture_time_queue;
  double total_time = 0.0f;

  stop_watch.reset ();

  bool continue_grabbing = true;
  while (continue_grabbing)
  {
    if (!pp_.AcquireFrame (true))
    {
      boost::this_thread::sleep (boost::posix_time::milliseconds (1));
      continue;
    }

    // query rgb and 3d data
    PXCImage *color_image=pp_.QueryImage (PXCImage::IMAGE_TYPE_COLOR);
    PXCImage *vertex_image=pp_.QueryImage (PXCImage::IMAGE_TYPE_DEPTH);

    // acquiure access to data
    PXCImage::ImageData ddata;
    vertex_image->AcquireAccess (PXCImage::ACCESS_READ, &ddata);
    short * vertices = (short*) ddata.planes[0];

    PXCImage::ImageData idata;
    color_image->AcquireAccess (PXCImage::ACCESS_READ, &idata);
    unsigned char * rgb_image_data = (unsigned char*) idata.planes[0];

    // get image information
    PXCImage::ImageInfo vertImageInfo;
    pxcStatus stat = vertex_image->QueryInfo (&vertImageInfo);
    const int w = vertImageInfo.width;
    const int h = vertImageInfo.height;

    PXCImage::ImageInfo rgb_image_info;
    stat = color_image->QueryInfo (&rgb_image_info);
    const int image_width = rgb_image_info.width;
    const int image_height = rgb_image_info.height;

    // convert to point cloud
    const float nan_value = std::numeric_limits<float>::quiet_NaN ();

    int dwidth2 = ddata.pitches[0] / sizeof (pxcU16);
    float *uvmap = (float*)ddata.planes[2];
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA> (w, h));
    for (int j = 0, k = 0; j < h; j++)
    {
      for (int i = 0; i < w; i++, k++)
      {
        int xx = (int) (uvmap[(j*w+i)*2+0]*image_width+0.5f);
        int yy = (int) (uvmap[(j*w+i)*2+1]*image_height+0.5f);

        unsigned int idx = 3*(j*w + i);
        short x = vertices[idx];
        short y = vertices[idx+1];
        short z = vertices[idx+2];

        unsigned char r = 255;
        unsigned char g = 255;
        unsigned char b = 255;

        if (xx < 0 || xx >= image_width || yy < 0 || yy >= image_height)
        {
          r = 255;
          g = 255;
          b = 255;
        }
        else
        {
          unsigned char * rgb_ptr = rgb_image_data + 3*(yy*image_width+xx);
          r = rgb_ptr[2];
          g = rgb_ptr[1];
          b = rgb_ptr[0];
        }

        if (z == dvalues[0] || z == dvalues[1])
        {
          cloud->points[k].x = nan_value;
          cloud->points[k].y = nan_value;
          cloud->points[k].z = nan_value;
          cloud->points[k].r = r;
          cloud->points[k].g = g;
          cloud->points[k].b = b;
          cloud->points[k].a = 255;
        }
        else
        {
          // normalize vertices to meters
          cloud->points[k].x = x / 1000.0f;
          cloud->points[k].y = y / 1000.0f;
          cloud->points[k].z = z / 1000.0f;
          cloud->points[k].r = r;
          cloud->points[k].g = g;
          cloud->points[k].b = b;
          cloud->points[k].a = 255;
        }
      }
    }

    // publish cloud
    if (num_slots<sig_cb_pxc_point_cloud_rgba> () > 0)
    {
      point_cloud_rgba_signal_->operator() (cloud);
    }
    if (num_slots<sig_cb_pxc_point_cloud_rgb> () > 0)
    {
      pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp_cloud (new pcl::PointCloud<pcl::PointXYZRGB> ());
      cloud->resize (w*h);
      cloud->width = w;
      cloud->height = h;
      cloud->is_dense = false;

      pcl::copyPointCloud<pcl::PointXYZRGBA, pcl::PointXYZRGB> (*cloud, *tmp_cloud);

      point_cloud_rgb_signal_->operator() (tmp_cloud);
    }
    if (num_slots<sig_cb_pxc_point_cloud> () > 0)
    {
      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_tmp (new pcl::PointCloud<pcl::PointXYZ> ());
      cloud->resize (w*h);
      cloud->width = w;
      cloud->height = h;
      cloud->is_dense = false;

      pcl::copyPointCloud<pcl::PointXYZRGBA, pcl::PointXYZ> (*cloud, *cloud_tmp);

      point_cloud_signal_->operator() (cloud_tmp);
    }

    pp_.ReleaseFrame();

    const double capture_time = stop_watch.getTimeSeconds ();
    total_time += capture_time;

    capture_time_queue.push (capture_time);

    if (capture_time_queue.size () >= 30)
    {
      double removed_time = capture_time_queue.front ();
      capture_time_queue.pop ();

      total_time -= removed_time;
    }

    fps_mutex_.lock ();
    fps_ = static_cast<float> (total_time / capture_time_queue.size ());
    fps_mutex_.unlock ();
  }
}

#endif
<|endoftext|>


<commit_before>#ifndef unicode_hh_INCLUDED
#define unicode_hh_INCLUDED

#include <cstdint>
#include <locale>

namespace Kakoune
{

using Codepoint = uint32_t;

inline bool is_word(Codepoint c)
{
    return c == '_' or std::isalnum((wchar_t)c, std::locale());
}

inline bool is_eol(Codepoint c)
{
    return c == '\n';
}

inline bool is_blank(Codepoint c)
{
    return c == ' ' or c == '\t';
}

}

#endif // unicode_hh_INCLUDED
<commit_msg>use C isalnum instead of C++ std::isalnum<commit_after>#ifndef unicode_hh_INCLUDED
#define unicode_hh_INCLUDED

#include <cstdint>
#include <ctype.h>

namespace Kakoune
{

using Codepoint = uint32_t;

inline bool is_word(Codepoint c)
{
    return c == '_' or isalnum(c);
}

inline bool is_eol(Codepoint c)
{
    return c == '\n';
}

inline bool is_blank(Codepoint c)
{
    return c == ' ' or c == '\t';
}

}

#endif // unicode_hh_INCLUDED
<|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2015 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: user_fs.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hoojamis@gmail.com
 *  Date: Jun  4, 2015
 *  Time: 22:52:30
 *  Description: main class of this GSFS
 *****************************************************************************/
#include "user_fs.h"
#include <stdexcept>
#include <ctime>
#include "bytes_order.h"

// calling order of functions below:
// master node: setMaster -> initDirTree -> initHost -> initTCPNetwork
// slave node: initDirTree -> initHost -> initTCPNetwork

void UserFS::setMaster() { _host_id = 1; }

// this function may throw exceptions
void UserFS::initDirTree(const std::string& working_dir) {
    using namespace boost::filesystem;

    boost::unique_lock< boost::shared_mutex > lock(_access);

    _working_dir = absolute(working_dir).string();

    _dir_tree.initialize();
    _dir_tree.root()->type = DirTree::TreeNode::DIRECTORY;
    // It seems there's is a portable way to get dir size, just set it to 0
    // If anybody knows how to do that, please tell me. Thanks.
    _dir_tree.root()->size = 0;
    _dir_tree.root()->host_id = _host_id;
    _dir_tree.root()->mtime = time(nullptr);
    _dir_tree.root()->num_links = hard_link_count(_working_dir);

    // here
    std::function< void (const path&, const DirTree::TreeNode&) > traverseDirectory;
    traverseDirectory = [this, &traverseDirectory]
        (const path& dir, const DirTree::TreeNode& parent)->void {
        for (auto& f: directory_iterator(dir)) {
            auto file_type = symlink_status(f).type();

            decltype(DirTree::TreeNode::type) treenode_type;

            switch (file_type) {
                case boost::filesystem::file_type::directory_file:
                    treenode_type = DirTree::TreeNode::DIRECTORY;
                    break;
                case boost::filesystem::file_type::regular_file:
                    treenode_type = DirTree::TreeNode::REGULAR;
                    break;
                case boost::filesystem::file_type::character_file:
                    treenode_type = DirTree::TreeNode::CHRDEVICE;
                    break;
                case boost::filesystem::file_type::block_file:
                    treenode_type = DirTree::TreeNode::BLKDEVICE;
                    break;
                case boost::filesystem::file_type::fifo_file:
                    treenode_type = DirTree::TreeNode::FIFO;
                    break;
                case boost::filesystem::file_type::symlink_file:
                    treenode_type = DirTree::TreeNode::SYMLINK;
                    break;
                case boost::filesystem::file_type::socket_file:
                    treenode_type = DirTree::TreeNode::SOCKET;
                    break;
                case boost::filesystem::file_type::type_unknown:
                default:
                    treenode_type = DirTree::TreeNode::UNKNOWN;
            }

            if (treenode_type == DirTree::TreeNode::UNKNOWN)
                continue;
            else if (treenode_type == DirTree::TreeNode::DIRECTORY) {
                DirTree::TreeNode dirnode;
                dirnode.type = treenode_type;
                dirnode.name = f.path().filename().string();
                dirnode.size = 0;
                dirnode.mtime = last_write_time(f.path());
                dirnode.host_id = _host_id;
                dirnode.num_links = hard_link_count(f.path());

                auto insert_rtv = parent.children.insert(dirnode);

                traverseDirectory(f, *(insert_rtv.first));
            } else {
                DirTree::TreeNode filenode;
                filenode.type = treenode_type;
                filenode.name = f.path().filename().string();
                filenode.size = file_size(f);
                filenode.mtime = last_write_time(f.path());
                filenode.host_id = _host_id;
                filenode.num_links = hard_link_count(f.path());

                parent.children.insert(filenode);
            }
        }
    };

    traverseDirectory(_working_dir, *_dir_tree.root());
}

void UserFS::initHost(const std::string& addr, const uint16_t tcp_port, const uint16_t ssh_port) {
    boost::unique_lock< boost::shared_mutex > lock(_access);

    // this functions should only be called when program initializes

    Hosts::Host host;
    host.id = _host_id;
    host.address = addr;
    host.working_dir = _working_dir;
    host.tcp_port = tcp_port;
    host.ssh_port = ssh_port;

    // push self's host at 0
    _hosts.push(host);
}

// returns true on error
bool UserFS::initTCPNetwork(const std::string& addr, const uint16_t port) {
    bool is_master = _host_id == 1;

    bool init_rtv = _tcp_manager.initialize(is_master, addr, port);

    if (init_rtv) return 1;

    _tcp_manager.start();

    // push master's host
    if (is_master)
        _hosts.push(_hosts[0]);
    // else wait for master's recognition or rejection
    else {
        std::string dir_tree_seq;
        std::string host_seq;

        {
            boost::shared_lock< boost::shared_mutex > lock(_access);
            dir_tree_seq = DirTree::serialize(_dir_tree);
            host_seq = Hosts::Host::serialize(_hosts[0]);
        }

        std::string dir_tree_seq_len = host_to_network_64(dir_tree_seq.length());
        std::string host_seq_len = host_to_network_64(host_seq.length());
        std::string protocol_type = host_to_network_64(0x00);

        std::string message = protocol_type +
                              dir_tree_seq_len + dir_tree_seq +
                              host_seq_len + host_seq;

        _tcp_manager.write(message);

        _slave_wait_sem.wait();
    }

    return 0;
}

const DirTree::TreeNode* UserFS::find(const std::string& path) {
    boost::shared_lock< boost::shared_mutex > lock(_access);
    return _dir_tree.find(path);
}

// returns num of bytes read on success
// returns < 0 on error
intmax_t UserFS::read(const uint64_t node_id, const std::string path,
              const size_t offset, const size_t size, char* buff) {
    // remote node isn't inserted into ssh manager
    if (!_ssh_manager.findHost(node_id)) {
        bool rtv = _ssh_manager.insertHost(node_id, _hosts[node_id].address, _hosts[node_id].ssh_port);
        if (rtv) return -1;
    }

    boost::filesystem::path remote_path = _hosts[node_id].working_dir;
    remote_path /= path;

    std::string remote_path_string = remote_path.string();

    // read local file
    if (node_id == _host_id) {
        std::ifstream fin(remote_path_string);
        fin.seekg(offset);
        fin.readsome(buff, size);
        if (fin.fail() || fin.bad()) return -1;
        size_t bytes_read = fin.gcount();
        return bytes_read;
    }

    // read remote file
    return _ssh_manager.read(node_id, remote_path_string, offset, size, buff);
}

// send update packet to all slaves
void UserFS::sendUpdate() {
    std::string dir_tree_seq;
    std::string hosts_seq;

    {
        boost::shared_lock< boost::shared_mutex > lock(_access);
        dir_tree_seq = DirTree::serialize(_dir_tree);
        hosts_seq = Hosts::serialize(_hosts);
    }

    sendUpdate(dir_tree_seq, hosts_seq);
}

void UserFS::sendUpdate(const std::string& dir_tree_seq, const std::string& hosts_seq) {
    std::string message = host_to_network_64(0x02);
    message += host_to_network_64(dir_tree_seq.length());
    message += dir_tree_seq;
    message += host_to_network_64(hosts_seq.length());
    message += hosts_seq;

    // send to all slaves
    _tcp_manager.write(message);
}

// Callback Functions for slaves' tcp manager:

// slave get recognized from master
void UserFS::slaveRecognized(const uint64_t slave_id, const std::string& dir_tree_seq, const std::string& hosts_seq) {
    // deploy dir tree
    DirTree merged_tree = DirTree::deserialize(dir_tree_seq);

    // deploy hosts
    _host_id = slave_id;
    Hosts merged_hosts = Hosts::deserialize(hosts_seq);

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.root()->children = merged_tree.root()->children;
        _hosts = merged_hosts;
    }
    // wake up main thread
    _main_thread_is_waiting = 0;
    _slave_wait_sem.post();
}

// master sent a update packet, update dirtree and hosts
void UserFS::updateInfo(const std::string& dir_tree_seq, const std::string& hosts_seq) {
    DirTree new_tree = DirTree::deserialize(dir_tree_seq);
    Hosts merged_hosts = Hosts::deserialize(hosts_seq);

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.root()->children = new_tree.root()->children;
        _hosts = merged_hosts;
    }
}

// connect failed or slave disconnect from master
void UserFS::disconnect() {
    // clear dir tree
    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.removeNotOf(_host_id);
    }
    // if the first attempt to connect to master is failed,
    // recognition message will never come, and main thread will forever wait.
    // wake up the waiting main thread
    if (_main_thread_is_waiting) {
        _main_thread_is_waiting = 0;
        _slave_wait_sem.post();
    }
}

// Callback Functions for master' tcp manager:

// slave disconnect from master
void UserFS::disconnect(const TCPMasterMessager::Connection::iterator handle) {
    uint64_t& slave_id = std::get<4>(*handle);

    // slave is initializting
    if (slave_id == 0) return;

    // remove this slave's node in dir tree
    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.removeOf(slave_id);
    }

    slave_id = 0;
    sendUpdate();
}

// new slave coming, chekc dirtree, allocate host_id, merge dir_tree and hosts
void UserFS::newConnection(const std::string& dir_tree_seq,
                   const std::string& host_seq,
                   const TCPMasterMessager::Connection::iterator handle) {
    // deserialize
    DirTree slave_dir_tree = DirTree::deserialize(dir_tree_seq);
    Hosts::Host slave_host = Hosts::Host::deserialize(host_seq);

    // check conflicts
    std::vector<std::string> conflicts;

    {
       boost::shared_lock< boost::shared_mutex > lock(_access);
       conflicts = _dir_tree.hasConflict(slave_dir_tree);
    }

    // there's conflict, close connection
    if (conflicts.size()) return _tcp_manager.close(handle);
    // else

    // alloc slave id
    uint64_t slave_id = _max_host_id++;
    slave_host.id = slave_id;
    slave_dir_tree.root()->setHostID(slave_id);

    std::get<4>(*handle) = slave_id;

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);

        // merge dir tree
        _dir_tree.merge(slave_dir_tree);

        // merge host
        _hosts.push(slave_host);
    }

    // construct response message

    std::string merged_dir_tree_seq;
    std::string merged_hosts_seq;

    {
        boost::shared_lock< boost::shared_mutex > lock(_access);
        merged_dir_tree_seq = DirTree::serialize(_dir_tree);
        merged_hosts_seq = Hosts::serialize(_hosts);
    }

    std::string merged_dir_tree_seq_len = host_to_network_64(merged_dir_tree_seq.length());
    std::string merged_hosts_seq_len = host_to_network_64(merged_hosts_seq.length());
    std::string protocol_type = host_to_network_64(0x01);
    std::string slave_id_seq = host_to_network_64(slave_id);

    std::string message = protocol_type + slave_id_seq +
                          merged_dir_tree_seq_len + merged_dir_tree_seq +
                          merged_hosts_seq_len + merged_hosts_seq;

    // send to slave
    _tcp_manager.writeTo(message, handle);
    sendUpdate(merged_dir_tree_seq, merged_hosts_seq);
}

<commit_msg>fix bugs<commit_after>/******************************************************************************
 *  Copyright (c) 2015 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: user_fs.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hoojamis@gmail.com
 *  Date: Jun  4, 2015
 *  Time: 22:52:30
 *  Description: main class of this GSFS
 *****************************************************************************/
#include "user_fs.h"
#include <stdexcept>
#include <ctime>
#include "bytes_order.h"

// calling order of functions below:
// master node: setMaster -> initDirTree -> initHost -> initTCPNetwork
// slave node: initDirTree -> initHost -> initTCPNetwork

void UserFS::setMaster() { _host_id = 1; }

// this function may throw exceptions
void UserFS::initDirTree(const std::string& working_dir) {
    using namespace boost::filesystem;

    boost::unique_lock< boost::shared_mutex > lock(_access);

    _working_dir = absolute(working_dir).string();
    // add trailing slash
    if (_working_dir.size() && _working_dir.back() != '/')
        _working_dir.push_back('/');

    _dir_tree.initialize();
    _dir_tree.root()->type = DirTree::TreeNode::DIRECTORY;
    // It seems there's is a portable way to get dir size, just set it to 0
    // If anybody knows how to do that, please tell me. Thanks.
    _dir_tree.root()->size = 0;
    _dir_tree.root()->host_id = _host_id;
    _dir_tree.root()->mtime = time(nullptr);
    _dir_tree.root()->num_links = hard_link_count(_working_dir);

    // here
    std::function< void (const path&, const DirTree::TreeNode&) > traverseDirectory;
    traverseDirectory = [this, &traverseDirectory]
        (const path& dir, const DirTree::TreeNode& parent)->void {
        for (auto& f: directory_iterator(dir)) {
            auto file_type = symlink_status(f).type();

            decltype(DirTree::TreeNode::type) treenode_type;

            switch (file_type) {
                case boost::filesystem::file_type::directory_file:
                    treenode_type = DirTree::TreeNode::DIRECTORY;
                    break;
                case boost::filesystem::file_type::regular_file:
                    treenode_type = DirTree::TreeNode::REGULAR;
                    break;
                case boost::filesystem::file_type::character_file:
                    treenode_type = DirTree::TreeNode::CHRDEVICE;
                    break;
                case boost::filesystem::file_type::block_file:
                    treenode_type = DirTree::TreeNode::BLKDEVICE;
                    break;
                case boost::filesystem::file_type::fifo_file:
                    treenode_type = DirTree::TreeNode::FIFO;
                    break;
                case boost::filesystem::file_type::symlink_file:
                    treenode_type = DirTree::TreeNode::SYMLINK;
                    break;
                case boost::filesystem::file_type::socket_file:
                    treenode_type = DirTree::TreeNode::SOCKET;
                    break;
                case boost::filesystem::file_type::type_unknown:
                default:
                    treenode_type = DirTree::TreeNode::UNKNOWN;
            }

            if (treenode_type == DirTree::TreeNode::UNKNOWN)
                continue;
            else if (treenode_type == DirTree::TreeNode::DIRECTORY) {
                DirTree::TreeNode dirnode;
                dirnode.type = treenode_type;
                dirnode.name = f.path().filename().string();
                dirnode.size = 0;
                dirnode.mtime = last_write_time(f.path());
                dirnode.host_id = _host_id;
                dirnode.num_links = hard_link_count(f.path());

                auto insert_rtv = parent.children.insert(dirnode);

                traverseDirectory(f, *(insert_rtv.first));
            } else {
                DirTree::TreeNode filenode;
                filenode.type = treenode_type;
                filenode.name = f.path().filename().string();
                filenode.size = file_size(f);
                filenode.mtime = last_write_time(f.path());
                filenode.host_id = _host_id;
                filenode.num_links = hard_link_count(f.path());

                parent.children.insert(filenode);
            }
        }
    };

    traverseDirectory(_working_dir, *_dir_tree.root());
}

void UserFS::initHost(const std::string& addr, const uint16_t tcp_port, const uint16_t ssh_port) {
    boost::unique_lock< boost::shared_mutex > lock(_access);

    // this functions should only be called when program initializes

    Hosts::Host host;
    host.id = _host_id;
    host.address = addr;
    host.working_dir = _working_dir;
    host.tcp_port = tcp_port;
    host.ssh_port = ssh_port;

    // push self's host at 0
    _hosts.push(host);
}

// returns true on error
bool UserFS::initTCPNetwork(const std::string& addr, const uint16_t port) {
    bool is_master = _host_id == 1;

    bool init_rtv = _tcp_manager.initialize(is_master, addr, port);

    if (init_rtv) return 1;

    _tcp_manager.start();

    // push master's host
    if (is_master)
        _hosts.push(_hosts[0]);
    // else wait for master's recognition or rejection
    else {
        std::string dir_tree_seq;
        std::string host_seq;

        {
            boost::shared_lock< boost::shared_mutex > lock(_access);
            dir_tree_seq = DirTree::serialize(_dir_tree);
            host_seq = Hosts::Host::serialize(_hosts[0]);
        }

        std::string dir_tree_seq_len = host_to_network_64(dir_tree_seq.length());
        std::string host_seq_len = host_to_network_64(host_seq.length());
        std::string protocol_type = host_to_network_64(0x00);

        std::string message = protocol_type +
                              dir_tree_seq_len + dir_tree_seq +
                              host_seq_len + host_seq;

        _tcp_manager.write(message);

        _slave_wait_sem.wait();
    }

    return 0;
}

const DirTree::TreeNode* UserFS::find(const std::string& path) {
    boost::shared_lock< boost::shared_mutex > lock(_access);
    return _dir_tree.find(path);
}

// returns num of bytes read on success
// returns < 0 on error
intmax_t UserFS::read(const uint64_t node_id, const std::string path,
              const size_t offset, const size_t size, char* buff) {
    // remote node isn't inserted into ssh manager
    if (!_ssh_manager.findHost(node_id)) {
        bool rtv = _ssh_manager.insertHost(node_id, _hosts[node_id].address, _hosts[node_id].ssh_port);
        if (rtv) return -1;
    }

    boost::filesystem::path remote_path = _hosts[node_id].working_dir;
    remote_path /= path.substr(path.front() == '/'? 1: 0);

    std::string remote_path_string = remote_path.string();

    // read local file
    if (node_id == _host_id) {
        std::ifstream fin(remote_path_string);
        fin.seekg(offset);
        fin.read(buff, size);
        if (fin.bad()) return -1;
        size_t bytes_read = fin.gcount();
        return bytes_read;
    }

    // read remote file
    return _ssh_manager.read(node_id, remote_path_string, offset, size, buff);
}

// send update packet to all slaves
void UserFS::sendUpdate() {
    std::string dir_tree_seq;
    std::string hosts_seq;

    {
        boost::shared_lock< boost::shared_mutex > lock(_access);
        dir_tree_seq = DirTree::serialize(_dir_tree);
        hosts_seq = Hosts::serialize(_hosts);
    }

    sendUpdate(dir_tree_seq, hosts_seq);
}

void UserFS::sendUpdate(const std::string& dir_tree_seq, const std::string& hosts_seq) {
    std::string message = host_to_network_64(0x02);
    message += host_to_network_64(dir_tree_seq.length());
    message += dir_tree_seq;
    message += host_to_network_64(hosts_seq.length());
    message += hosts_seq;

    // send to all slaves
    _tcp_manager.write(message);
}

// Callback Functions for slaves' tcp manager:

// slave get recognized from master
void UserFS::slaveRecognized(const uint64_t slave_id, const std::string& dir_tree_seq, const std::string& hosts_seq) {
    // deploy dir tree
    DirTree merged_tree = DirTree::deserialize(dir_tree_seq);

    // deploy hosts
    _host_id = slave_id;
    Hosts merged_hosts = Hosts::deserialize(hosts_seq);

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.root()->children = merged_tree.root()->children;
        _hosts = merged_hosts;
    }
    // wake up main thread
    _main_thread_is_waiting = 0;
    _slave_wait_sem.post();
}

// master sent a update packet, update dirtree and hosts
void UserFS::updateInfo(const std::string& dir_tree_seq, const std::string& hosts_seq) {
    DirTree new_tree = DirTree::deserialize(dir_tree_seq);
    Hosts merged_hosts = Hosts::deserialize(hosts_seq);

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.root()->children = new_tree.root()->children;
        _hosts = merged_hosts;
    }
}

// connect failed or slave disconnect from master
void UserFS::disconnect() {
    // clear dir tree
    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.removeNotOf(_host_id);
    }
    // if the first attempt to connect to master is failed,
    // recognition message will never come, and main thread will forever wait.
    // wake up the waiting main thread
    if (_main_thread_is_waiting) {
        _main_thread_is_waiting = 0;
        _slave_wait_sem.post();
    }
}

// Callback Functions for master' tcp manager:

// slave disconnect from master
void UserFS::disconnect(const TCPMasterMessager::Connection::iterator handle) {
    uint64_t& slave_id = std::get<4>(*handle);

    // slave is initializting
    if (slave_id == 0) return;

    // remove this slave's node in dir tree
    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.removeOf(slave_id);
    }

    slave_id = 0;
    sendUpdate();
}

// new slave coming, chekc dirtree, allocate host_id, merge dir_tree and hosts
void UserFS::newConnection(const std::string& dir_tree_seq,
                   const std::string& host_seq,
                   const TCPMasterMessager::Connection::iterator handle) {
    // deserialize
    DirTree slave_dir_tree = DirTree::deserialize(dir_tree_seq);
    Hosts::Host slave_host = Hosts::Host::deserialize(host_seq);

    // check conflicts
    std::vector<std::string> conflicts;

    {
       boost::shared_lock< boost::shared_mutex > lock(_access);
       conflicts = _dir_tree.hasConflict(slave_dir_tree);
    }

    // there's conflict, close connection
    if (conflicts.size()) return _tcp_manager.close(handle);
    // else

    // alloc slave id
    uint64_t slave_id = _max_host_id++;
    slave_host.id = slave_id;
    slave_dir_tree.root()->setHostID(slave_id);

    std::get<4>(*handle) = slave_id;

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);

        // merge dir tree
        _dir_tree.merge(slave_dir_tree);

        // merge host
        _hosts.push(slave_host);
    }

    // construct response message

    std::string merged_dir_tree_seq;
    std::string merged_hosts_seq;

    {
        boost::shared_lock< boost::shared_mutex > lock(_access);
        merged_dir_tree_seq = DirTree::serialize(_dir_tree);
        merged_hosts_seq = Hosts::serialize(_hosts);
    }

    std::string merged_dir_tree_seq_len = host_to_network_64(merged_dir_tree_seq.length());
    std::string merged_hosts_seq_len = host_to_network_64(merged_hosts_seq.length());
    std::string protocol_type = host_to_network_64(0x01);
    std::string slave_id_seq = host_to_network_64(slave_id);

    std::string message = protocol_type + slave_id_seq +
                          merged_dir_tree_seq_len + merged_dir_tree_seq +
                          merged_hosts_seq_len + merged_hosts_seq;

    // send to slave
    _tcp_manager.writeTo(message, handle);
    sendUpdate(merged_dir_tree_seq, merged_hosts_seq);
}

<|endoftext|>


<commit_before>#include "quickgridstar.h"

QuickGridStarAttached::QuickGridStarAttached(QObject *object) :
    QObject(object),
    _row(0),
    _column(0),
    _rowSpan(1),
    _columnSpan(1)
{
}

QuickGridStar::QuickGridStar(QQuickItem *parent) :
    QQuickItem(parent)
{
}

QuickGridStar::~QuickGridStar()
{
    for(QuickGridItem *item : _items)
    {
        delete item;
    }
}

void QuickGridStar::componentComplete()
{
    QList<QQuickItem *>
        children = childItems();

    for(QQuickItem *child : children)
    {
        QString
            className(child->metaObject()->className());

        if(!className.compare("QuickRowDefinition"))
        {
            QuickRowDefinition
                *def = qobject_cast<QuickRowDefinition *>(child);

            _gridDefinition.addRowDefinition(def->_weight);
        }
        else if(!className.compare("QuickColumnDefinition"))
        {
            QuickColumnDefinition
                *def = qobject_cast<QuickColumnDefinition *>(child);

            _gridDefinition.addColumnDefinition(def->_weight);
        }
        else
        {
            QuickGridStarAttached
                *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(child));

            _gridDefinition.calculateBounds(attached->_row, attached->_column, attached->_rowSpan, attached->_columnSpan);

            _items << new QuickGridItem(child, attached->_row, attached->_column, attached->_rowSpan, attached->_columnSpan);
        }
    }

    QRectF
        rect;

    if(QString(parent()->metaObject()->className()).contains("ApplicationWindow"))
    {
        QQuickWindow
            *p = qobject_cast<QQuickWindow *>(parent());

        rect = QRectF(p->position(), QSizeF(p->width(), p->height()));
    }
    else
    {
        QQuickItem
            *p = qobject_cast<QQuickItem *>(parent());

        rect = QRectF(p->position(), QSizeF(p->width(), p->height()));
    }

    for(QuickGridItem *item : _items)
    {
        QRectF
            cellRect(_gridDefinition.cellRect(rect, item->_row, item->_column, item->_rowSpan, item->_columnSpan));

        item->_item->setPosition(cellRect.topLeft());
        item->_item->setWidth(cellRect.width());
        item->_item->setHeight(cellRect.height());
    }

    QQuickItem::componentComplete();
}

QuickGridStarAttached *QuickGridStar::qmlAttachedProperties(QObject *object)
{
    return new QuickGridStarAttached(object);
}

QuickRowDefinition::QuickRowDefinition(QQuickItem *parent) :
    QQuickItem(parent)
{
}

QuickColumnDefinition::QuickColumnDefinition(QQuickItem *parent) :
    QQuickItem(parent)
{
}
<commit_msg>Update quickgridstar.cpp<commit_after>#include "quickgridstar.h"

QuickRowDefinition::QuickRowDefinition(QQuickItem *parent) :
    QQuickItem(parent),
    _weight(1.0f)
{
}

QuickColumnDefinition::QuickColumnDefinition(QQuickItem *parent) :
    QQuickItem(parent),
    _weight(1.0f)
{
}

QuickGridStarAttached::QuickGridStarAttached(QObject *object) :
    QObject(object),
    _row(0),
    _column(0),
    _rowSpan(1),
    _columnSpan(1)
{
}

QuickGridStar::QuickGridStar(QQuickItem *parent) :
    QQuickItem(parent)
{
}

QuickGridStar::~QuickGridStar()
{
    for(QuickGridItem *item : _items)
    {
        delete item;
    }
}

void QuickGridStar::componentComplete()
{
    QList<QQuickItem *>
        children = childItems();

    for(QQuickItem *child : children)
    {
        QString
            className(child->metaObject()->className());

        if(!className.compare("QuickRowDefinition"))
        {
            QuickRowDefinition
                *definition = qobject_cast<QuickRowDefinition *>(child);

            _gridDefinition.addRowDefinition(definition->_weight);
        }
        else if(!className.compare("QuickColumnDefinition"))
        {
            QuickColumnDefinition
                *definition = qobject_cast<QuickColumnDefinition *>(child);

            _gridDefinition.addColumnDefinition(definition->_weight);
        }
        else
        {
            QuickGridStarAttached
                *attached = qobject_cast<QuickGridStarAttached *>(qmlAttachedPropertiesObject<QuickGridStar>(child));

            _items << new QuickGridItem(child, attached->_row, attached->_column, attached->_rowSpan, attached->_columnSpan);
        }
    }

    for(QuickGridItem *item : _items)
    {
        _gridDefinition.calculateBounds(item->_row, item->_column, item->_rowSpan, item->_columnSpan);
    }

    QQuickItem::componentComplete();
}

void QuickGridStar::itemChange(ItemChange change, const ItemChangeData &value)
{
    QCoreApplication::postEvent(this, new QEvent(QEvent::LayoutRequest));

    QQuickItem::itemChange(change, value);
}

bool QuickGridStar::event(QEvent *e)
{
    if(e->type() == QEvent::LayoutRequest)
    {
        updateGeometry();
    }

    return QQuickItem::event(e);
}

void QuickGridStar::updateGeometry()
{
    QRectF
        rect;

    if(QString(parent()->metaObject()->className()).contains("ApplicationWindow"))
    {
        QQuickWindow
            *p = qobject_cast<QQuickWindow *>(parent());

        rect = QRectF(QPointF(0.f, 0.f), QSizeF(p->width(), p->height()));
    }
    else
    {
        rect = QRectF(QPointF(0.f, 0.f), QSizeF(width(), height()));
    }

    for(QuickGridItem *item : _items)
    {
        QRectF
            cellRect(_gridDefinition.cellRect(rect, item->_row, item->_column, item->_rowSpan, item->_columnSpan));

        item->_item->setPosition(cellRect.topLeft());
        item->_item->setWidth(cellRect.width());
        item->_item->setHeight(cellRect.height());
    }
}

QuickGridStarAttached *QuickGridStar::qmlAttachedProperties(QObject *object)
{
    return new QuickGridStarAttached(object);
}

void QuickGridStar::registerTypes()
{
    qmlRegisterType<QuickGridStar>("com.quick.gridStar", 1, 0, "GridStar");
    qmlRegisterType<QuickRowDefinition>("com.quick.gridStar", 1, 0, "RowDefinition");
    qmlRegisterType<QuickColumnDefinition>("com.quick.gridStar", 1, 0, "ColumnDefinition");
}
<|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2015 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: user_fs.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hoojamis@gmail.com
 *  Date: Jun  4, 2015
 *  Time: 22:52:30
 *  Description: main class of this GSFS
 *****************************************************************************/
#include "user_fs.h"
#include <stdexcept>
#include <ctime>
#include "bytes_order.h"

// calling order of functions below:
// master node: setMaster -> initDirTree -> initHost -> initTCPNetwork
// slave node: initDirTree -> initHost -> initTCPNetwork

void UserFS::setMaster() { _host_id = 1; }

// this function may throw exceptions
void UserFS::initDirTree(const std::string& working_dir) {
    using namespace boost::filesystem;

    boost::unique_lock< boost::shared_mutex > lock(_access);

    _working_dir = absolute(working_dir).string();
    // add trailing slash
    if (_working_dir.size() && _working_dir.back() != '/')
        _working_dir.push_back('/');

    _dir_tree.initialize();
    _dir_tree.root()->type = DirTree::TreeNode::DIRECTORY;
    // It seems there's is a portable way to get dir size, just set it to 0
    // If anybody knows how to do that, please tell me. Thanks.
    _dir_tree.root()->size = 0;
    _dir_tree.root()->host_id = _host_id;
    _dir_tree.root()->mtime = time(nullptr);
    _dir_tree.root()->num_links = hard_link_count(_working_dir);

    // here
    std::function< void (const path&, const DirTree::TreeNode&) > traverseDirectory;
    traverseDirectory = [this, &traverseDirectory]
        (const path& dir, const DirTree::TreeNode& parent)->void {
        for (auto& f: directory_iterator(dir)) {
            auto file_type = symlink_status(f).type();

            decltype(DirTree::TreeNode::type) treenode_type;

            switch (file_type) {
                case boost::filesystem::file_type::directory_file:
                    treenode_type = DirTree::TreeNode::DIRECTORY;
                    break;
                case boost::filesystem::file_type::regular_file:
                    treenode_type = DirTree::TreeNode::REGULAR;
                    break;
                case boost::filesystem::file_type::character_file:
                    treenode_type = DirTree::TreeNode::CHRDEVICE;
                    break;
                case boost::filesystem::file_type::block_file:
                    treenode_type = DirTree::TreeNode::BLKDEVICE;
                    break;
                case boost::filesystem::file_type::fifo_file:
                    treenode_type = DirTree::TreeNode::FIFO;
                    break;
                case boost::filesystem::file_type::symlink_file:
                    treenode_type = DirTree::TreeNode::SYMLINK;
                    break;
                case boost::filesystem::file_type::socket_file:
                    treenode_type = DirTree::TreeNode::SOCKET;
                    break;
                case boost::filesystem::file_type::type_unknown:
                default:
                    treenode_type = DirTree::TreeNode::UNKNOWN;
            }

            if (treenode_type == DirTree::TreeNode::UNKNOWN)
                continue;
            else if (treenode_type == DirTree::TreeNode::DIRECTORY) {
                DirTree::TreeNode dirnode;
                dirnode.type = treenode_type;
                dirnode.name = f.path().filename().string();
                dirnode.size = 0;
                dirnode.mtime = last_write_time(f.path());
                dirnode.host_id = _host_id;
                dirnode.num_links = hard_link_count(f.path());

                auto insert_rtv = parent.children.insert(dirnode);

                traverseDirectory(f, *(insert_rtv.first));
            } else {
                DirTree::TreeNode filenode;
                filenode.type = treenode_type;
                filenode.name = f.path().filename().string();
                filenode.size = file_size(f);
                filenode.mtime = last_write_time(f.path());
                filenode.host_id = _host_id;
                filenode.num_links = hard_link_count(f.path());

                parent.children.insert(filenode);
            }
        }
    };

    traverseDirectory(_working_dir, *_dir_tree.root());
}

void UserFS::initHost(const std::string& addr, const uint16_t tcp_port, const uint16_t ssh_port) {
    boost::unique_lock< boost::shared_mutex > lock(_access);

    // this functions should only be called when program initializes

    Hosts::Host host;
    host.id = _host_id;
    host.address = addr;
    host.working_dir = _working_dir;
    host.tcp_port = tcp_port;
    host.ssh_port = ssh_port;

    // push self's host at 0
    _hosts.push(host);
}

// returns true on error
bool UserFS::initTCPNetwork(const std::string& addr, const uint16_t port) {
    bool is_master = _host_id == 1;

    bool init_rtv = _tcp_manager.initialize(is_master, addr, port);

    if (init_rtv) return 1;

    _tcp_manager.start();

    // push master's host
    if (is_master)
        _hosts.push(_hosts[0]);
    // else wait for master's recognition or rejection
    else {
        std::string dir_tree_seq;
        std::string host_seq;

        {
            boost::shared_lock< boost::shared_mutex > lock(_access);
            dir_tree_seq = DirTree::serialize(_dir_tree);
            host_seq = Hosts::Host::serialize(_hosts[0]);
        }

        std::string dir_tree_seq_len = host_to_network_64(dir_tree_seq.length());
        std::string host_seq_len = host_to_network_64(host_seq.length());
        std::string protocol_type = host_to_network_64(0x00);

        std::string message = protocol_type +
                              dir_tree_seq_len + dir_tree_seq +
                              host_seq_len + host_seq;

        _tcp_manager.write(message);

        _slave_wait_sem.wait();
    }

    return 0;
}

const DirTree::TreeNode* UserFS::find(const std::string& path) {
    boost::shared_lock< boost::shared_mutex > lock(_access);
    return _dir_tree.find(path);
}

// returns num of bytes read on success
// returns < 0 on error
intmax_t UserFS::read(const uint64_t node_id, const std::string path,
              const size_t offset, const size_t size, char* buff) {
    // remote node isn't inserted into ssh manager
    if (!_ssh_manager.findHost(node_id)) {
        bool rtv = _ssh_manager.insertHost(node_id, _hosts[node_id].address, _hosts[node_id].ssh_port);
        if (rtv) return -1;
    }

    boost::filesystem::path remote_path = _hosts[node_id].working_dir;
    remote_path /= path.substr(path.front() == '/'? 1: 0);

    std::string remote_path_string = remote_path.string();

    // read local file
    if (node_id == _host_id) {
        std::ifstream fin(remote_path_string);
        fin.seekg(offset);
        fin.read(buff, size);
        if (fin.bad()) return -1;
        size_t bytes_read = fin.gcount();
        return bytes_read;
    }

    // read remote file
    return _ssh_manager.read(node_id, remote_path_string, offset, size, buff);
}

// send update packet to all slaves
void UserFS::sendUpdate() {
    std::string dir_tree_seq;
    std::string hosts_seq;

    {
        boost::shared_lock< boost::shared_mutex > lock(_access);
        dir_tree_seq = DirTree::serialize(_dir_tree);
        hosts_seq = Hosts::serialize(_hosts);
    }

    sendUpdate(dir_tree_seq, hosts_seq);
}

void UserFS::sendUpdate(const std::string& dir_tree_seq, const std::string& hosts_seq) {
    std::string message = host_to_network_64(0x02);
    message += host_to_network_64(dir_tree_seq.length());
    message += dir_tree_seq;
    message += host_to_network_64(hosts_seq.length());
    message += hosts_seq;

    // send to all slaves
    _tcp_manager.write(message);
}

// Callback Functions for slaves' tcp manager:

// slave get recognized from master
void UserFS::slaveRecognized(const uint64_t slave_id, const std::string& dir_tree_seq, const std::string& hosts_seq) {
    // deploy dir tree
    DirTree merged_tree = DirTree::deserialize(dir_tree_seq);

    // deploy hosts
    _host_id = slave_id;
    Hosts merged_hosts = Hosts::deserialize(hosts_seq);

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.root()->children = merged_tree.root()->children;
        _hosts = merged_hosts;
    }
    // wake up main thread
    _main_thread_is_waiting = 0;
    _slave_wait_sem.post();
}

// master sent a update packet, update dirtree and hosts
void UserFS::updateInfo(const std::string& dir_tree_seq, const std::string& hosts_seq) {
    DirTree new_tree = DirTree::deserialize(dir_tree_seq);
    Hosts merged_hosts = Hosts::deserialize(hosts_seq);

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.root()->children = new_tree.root()->children;
        _hosts = merged_hosts;
    }
}

// connect failed or slave disconnect from master
void UserFS::disconnect() {
    // clear dir tree
    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.removeNotOf(_host_id);
    }
    // if the first attempt to connect to master is failed,
    // recognition message will never come, and main thread will forever wait.
    // wake up the waiting main thread
    if (_main_thread_is_waiting) {
        _main_thread_is_waiting = 0;
        _slave_wait_sem.post();
    }
}

// Callback Functions for master' tcp manager:

// slave disconnect from master
void UserFS::disconnect(const TCPMasterMessager::Connection::iterator handle) {
    uint64_t& slave_id = std::get<4>(*handle);

    // slave is initializting
    if (slave_id == 0) return;

    // remove this slave's node in dir tree
    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.removeOf(slave_id);
    }

    slave_id = 0;
    sendUpdate();
}

// new slave coming, chekc dirtree, allocate host_id, merge dir_tree and hosts
void UserFS::newConnection(const std::string& dir_tree_seq,
                   const std::string& host_seq,
                   const TCPMasterMessager::Connection::iterator handle) {
    // deserialize
    DirTree slave_dir_tree = DirTree::deserialize(dir_tree_seq);
    Hosts::Host slave_host = Hosts::Host::deserialize(host_seq);

    // check conflicts
    std::vector<std::string> conflicts;

    {
       boost::shared_lock< boost::shared_mutex > lock(_access);
       conflicts = _dir_tree.hasConflict(slave_dir_tree);
    }

    // there's conflict, close connection
    if (conflicts.size()) return _tcp_manager.close(handle);
    // else

    // alloc slave id
    uint64_t slave_id = _max_host_id++;
    slave_host.id = slave_id;
    slave_dir_tree.root()->setHostID(slave_id);

    std::get<4>(*handle) = slave_id;

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);

        // merge dir tree
        _dir_tree.merge(slave_dir_tree);

        // merge host
        _hosts.push(slave_host);
    }

    // construct response message

    std::string merged_dir_tree_seq;
    std::string merged_hosts_seq;

    {
        boost::shared_lock< boost::shared_mutex > lock(_access);
        merged_dir_tree_seq = DirTree::serialize(_dir_tree);
        merged_hosts_seq = Hosts::serialize(_hosts);
    }

    std::string merged_dir_tree_seq_len = host_to_network_64(merged_dir_tree_seq.length());
    std::string merged_hosts_seq_len = host_to_network_64(merged_hosts_seq.length());
    std::string protocol_type = host_to_network_64(0x01);
    std::string slave_id_seq = host_to_network_64(slave_id);

    std::string message = protocol_type + slave_id_seq +
                          merged_dir_tree_seq_len + merged_dir_tree_seq +
                          merged_hosts_seq_len + merged_hosts_seq;

    // send to slave
    _tcp_manager.writeTo(message, handle);
    sendUpdate(merged_dir_tree_seq, merged_hosts_seq);
}

<commit_msg>fix bug: wrong standby host ip<commit_after>/******************************************************************************
 *  Copyright (c) 2015 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: user_fs.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hoojamis@gmail.com
 *  Date: Jun  4, 2015
 *  Time: 22:52:30
 *  Description: main class of this GSFS
 *****************************************************************************/
#include "user_fs.h"
#include <stdexcept>
#include <ctime>
#include "bytes_order.h"

// calling order of functions below:
// master node: setMaster -> initDirTree -> initHost -> initTCPNetwork
// slave node: initDirTree -> initHost -> initTCPNetwork

void UserFS::setMaster() { _host_id = 1; }

// this function may throw exceptions
void UserFS::initDirTree(const std::string& working_dir) {
    using namespace boost::filesystem;

    boost::unique_lock< boost::shared_mutex > lock(_access);

    _working_dir = absolute(working_dir).string();
    // add trailing slash
    if (_working_dir.size() && _working_dir.back() != '/')
        _working_dir.push_back('/');

    _dir_tree.initialize();
    _dir_tree.root()->type = DirTree::TreeNode::DIRECTORY;
    // It seems there's is a portable way to get dir size, just set it to 0
    // If anybody knows how to do that, please tell me. Thanks.
    _dir_tree.root()->size = 0;
    _dir_tree.root()->host_id = _host_id;
    _dir_tree.root()->mtime = time(nullptr);
    _dir_tree.root()->num_links = hard_link_count(_working_dir);

    // here
    std::function< void (const path&, const DirTree::TreeNode&) > traverseDirectory;
    traverseDirectory = [this, &traverseDirectory]
        (const path& dir, const DirTree::TreeNode& parent)->void {
        for (auto& f: directory_iterator(dir)) {
            auto file_type = symlink_status(f).type();

            decltype(DirTree::TreeNode::type) treenode_type;

            switch (file_type) {
                case boost::filesystem::file_type::directory_file:
                    treenode_type = DirTree::TreeNode::DIRECTORY;
                    break;
                case boost::filesystem::file_type::regular_file:
                    treenode_type = DirTree::TreeNode::REGULAR;
                    break;
                case boost::filesystem::file_type::character_file:
                    treenode_type = DirTree::TreeNode::CHRDEVICE;
                    break;
                case boost::filesystem::file_type::block_file:
                    treenode_type = DirTree::TreeNode::BLKDEVICE;
                    break;
                case boost::filesystem::file_type::fifo_file:
                    treenode_type = DirTree::TreeNode::FIFO;
                    break;
                case boost::filesystem::file_type::symlink_file:
                    treenode_type = DirTree::TreeNode::SYMLINK;
                    break;
                case boost::filesystem::file_type::socket_file:
                    treenode_type = DirTree::TreeNode::SOCKET;
                    break;
                case boost::filesystem::file_type::type_unknown:
                default:
                    treenode_type = DirTree::TreeNode::UNKNOWN;
            }

            if (treenode_type == DirTree::TreeNode::UNKNOWN)
                continue;
            else if (treenode_type == DirTree::TreeNode::DIRECTORY) {
                DirTree::TreeNode dirnode;
                dirnode.type = treenode_type;
                dirnode.name = f.path().filename().string();
                dirnode.size = 0;
                dirnode.mtime = last_write_time(f.path());
                dirnode.host_id = _host_id;
                dirnode.num_links = hard_link_count(f.path());

                auto insert_rtv = parent.children.insert(dirnode);

                traverseDirectory(f, *(insert_rtv.first));
            } else {
                DirTree::TreeNode filenode;
                filenode.type = treenode_type;
                filenode.name = f.path().filename().string();
                filenode.size = file_size(f);
                filenode.mtime = last_write_time(f.path());
                filenode.host_id = _host_id;
                filenode.num_links = hard_link_count(f.path());

                parent.children.insert(filenode);
            }
        }
    };

    traverseDirectory(_working_dir, *_dir_tree.root());
}

void UserFS::initHost(const std::string& addr, const uint16_t tcp_port, const uint16_t ssh_port) {
    boost::unique_lock< boost::shared_mutex > lock(_access);

    // this functions should only be called when program initializes

    Hosts::Host host;
    host.id = _host_id;
    host.address = addr;
    host.working_dir = _working_dir;
    host.tcp_port = tcp_port;
    host.ssh_port = ssh_port;

    // push self's host at 0
    _hosts.push(host);
}

// returns true on error
bool UserFS::initTCPNetwork(const std::string& addr, const uint16_t port) {
    bool is_master = _host_id == 1;

    bool init_rtv = _tcp_manager.initialize(is_master, addr, port);

    if (init_rtv) return 1;

    _tcp_manager.start();

    // push master's host
    if (is_master)
        _hosts.push(_hosts[0]);
    // else wait for master's recognition or rejection
    else {
        std::string dir_tree_seq;
        std::string host_seq;

        {
            boost::shared_lock< boost::shared_mutex > lock(_access);
            dir_tree_seq = DirTree::serialize(_dir_tree);
            host_seq = Hosts::Host::serialize(_hosts[0]);
        }

        std::string dir_tree_seq_len = host_to_network_64(dir_tree_seq.length());
        std::string host_seq_len = host_to_network_64(host_seq.length());
        std::string protocol_type = host_to_network_64(0x00);

        std::string message = protocol_type +
                              dir_tree_seq_len + dir_tree_seq +
                              host_seq_len + host_seq;

        _tcp_manager.write(message);

        _slave_wait_sem.wait();
    }

    return 0;
}

const DirTree::TreeNode* UserFS::find(const std::string& path) {
    boost::shared_lock< boost::shared_mutex > lock(_access);
    return _dir_tree.find(path);
}

// returns num of bytes read on success
// returns < 0 on error
intmax_t UserFS::read(const uint64_t node_id, const std::string path,
              const size_t offset, const size_t size, char* buff) {
    // remote node isn't inserted into ssh manager
    if (!_ssh_manager.findHost(node_id)) {
        bool rtv = _ssh_manager.insertHost(node_id, _hosts[node_id].address, _hosts[node_id].ssh_port);
        if (rtv) return -1;
    }

    boost::filesystem::path remote_path = _hosts[node_id].working_dir;
    remote_path /= path.substr(path.front() == '/'? 1: 0);

    std::string remote_path_string = remote_path.string();

    // read local file
    if (node_id == _host_id) {
        std::ifstream fin(remote_path_string);
        fin.seekg(offset);
        fin.read(buff, size);
        if (fin.bad()) return -1;
        size_t bytes_read = fin.gcount();
        return bytes_read;
    }

    // read remote file
    return _ssh_manager.read(node_id, remote_path_string, offset, size, buff);
}

// send update packet to all slaves
void UserFS::sendUpdate() {
    std::string dir_tree_seq;
    std::string hosts_seq;

    {
        boost::shared_lock< boost::shared_mutex > lock(_access);
        dir_tree_seq = DirTree::serialize(_dir_tree);
        hosts_seq = Hosts::serialize(_hosts);
    }

    sendUpdate(dir_tree_seq, hosts_seq);
}

void UserFS::sendUpdate(const std::string& dir_tree_seq, const std::string& hosts_seq) {
    std::string message = host_to_network_64(0x02);
    message += host_to_network_64(dir_tree_seq.length());
    message += dir_tree_seq;
    message += host_to_network_64(hosts_seq.length());
    message += hosts_seq;

    // send to all slaves
    _tcp_manager.write(message);
}

// Callback Functions for slaves' tcp manager:

// slave get recognized from master
void UserFS::slaveRecognized(const uint64_t slave_id, const std::string& dir_tree_seq, const std::string& hosts_seq) {
    // deploy dir tree
    DirTree merged_tree = DirTree::deserialize(dir_tree_seq);

    // deploy hosts
    _host_id = slave_id;
    Hosts merged_hosts = Hosts::deserialize(hosts_seq);

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.root()->children = merged_tree.root()->children;
        _hosts = merged_hosts;
    }
    // wake up main thread
    _main_thread_is_waiting = 0;
    _slave_wait_sem.post();
}

// master sent a update packet, update dirtree and hosts
void UserFS::updateInfo(const std::string& dir_tree_seq, const std::string& hosts_seq) {
    DirTree new_tree = DirTree::deserialize(dir_tree_seq);
    Hosts merged_hosts = Hosts::deserialize(hosts_seq);

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.root()->children = new_tree.root()->children;
        _hosts = merged_hosts;
    }
}

// connect failed or slave disconnect from master
void UserFS::disconnect() {
    // clear dir tree
    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.removeNotOf(_host_id);
    }
    // if the first attempt to connect to master is failed,
    // recognition message will never come, and main thread will forever wait.
    // wake up the waiting main thread
    if (_main_thread_is_waiting) {
        _main_thread_is_waiting = 0;
        _slave_wait_sem.post();
    }
}

// Callback Functions for master' tcp manager:

// slave disconnect from master
void UserFS::disconnect(const TCPMasterMessager::Connection::iterator handle) {
    uint64_t& slave_id = std::get<4>(*handle);

    // slave is initializting
    if (slave_id == 0) return;

    // remove this slave's node in dir tree
    {
        boost::unique_lock< boost::shared_mutex > lock(_access);
        _dir_tree.removeOf(slave_id);
    }

    slave_id = 0;
    sendUpdate();
}

// new slave coming, chekc dirtree, allocate host_id, merge dir_tree and hosts
void UserFS::newConnection(const std::string& dir_tree_seq,
                   const std::string& host_seq,
                   const TCPMasterMessager::Connection::iterator handle) {
    // deserialize
    DirTree slave_dir_tree = DirTree::deserialize(dir_tree_seq);
    Hosts::Host slave_host = Hosts::Host::deserialize(host_seq);

    // check conflicts
    std::vector<std::string> conflicts;

    {
       boost::shared_lock< boost::shared_mutex > lock(_access);
       conflicts = _dir_tree.hasConflict(slave_dir_tree);
    }

    // there's conflict, close connection
    if (conflicts.size()) return _tcp_manager.close(handle);
    // else

    // alloc slave id
    boost::system::error_code ec;
    uint64_t slave_id = _max_host_id++;
    slave_host.address = std::get<0>(*handle).remote_endpoint(ec).address().to_string(ec);
    slave_host.id = slave_id;
    slave_dir_tree.root()->setHostID(slave_id);

    std::get<4>(*handle) = slave_id;

    {
        boost::unique_lock< boost::shared_mutex > lock(_access);

        // merge dir tree
        _dir_tree.merge(slave_dir_tree);

        // merge host
        _hosts.push(slave_host);
    }

    // construct response message

    std::string merged_dir_tree_seq;
    std::string merged_hosts_seq;

    {
        boost::shared_lock< boost::shared_mutex > lock(_access);
        merged_dir_tree_seq = DirTree::serialize(_dir_tree);
        merged_hosts_seq = Hosts::serialize(_hosts);
    }

    std::string merged_dir_tree_seq_len = host_to_network_64(merged_dir_tree_seq.length());
    std::string merged_hosts_seq_len = host_to_network_64(merged_hosts_seq.length());
    std::string protocol_type = host_to_network_64(0x01);
    std::string slave_id_seq = host_to_network_64(slave_id);

    std::string message = protocol_type + slave_id_seq +
                          merged_dir_tree_seq_len + merged_dir_tree_seq +
                          merged_hosts_seq_len + merged_hosts_seq;

    // send to slave
    _tcp_manager.writeTo(message, handle);
    sendUpdate(merged_dir_tree_seq, merged_hosts_seq);
}

<|endoftext|>


<commit_before>// Copyright 2012 the V8 project 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 "src/v8.h"

#include "src/version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     28
#define BUILD_NUMBER      61
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 1

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    SNPrintF(str, "%d.%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
             is_simulator);
  } else {
    SNPrintF(str, "%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), candidate,
             is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      SNPrintF(str, "libv8-%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<commit_msg>[Auto-roll] Bump up version to 3.28.63.0<commit_after>// Copyright 2012 the V8 project 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 "src/v8.h"

#include "src/version.h"

// These macros define the version number for the current version.
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION     3
#define MINOR_VERSION     28
#define BUILD_NUMBER      63
#define PATCH_LEVEL       0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 1

// Define SONAME to have the build system put a specific SONAME into the
// shared library instead the generic SONAME generated from the V8 version
// number. This define is mainly used by the build system script.
#define SONAME            ""

#if IS_CANDIDATE_VERSION
#define CANDIDATE_STRING " (candidate)"
#else
#define CANDIDATE_STRING ""
#endif

#define SX(x) #x
#define S(x) SX(x)

#if PATCH_LEVEL > 0
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER) "."              \
        S(PATCH_LEVEL) CANDIDATE_STRING
#else
#define VERSION_STRING                                                         \
    S(MAJOR_VERSION) "." S(MINOR_VERSION) "." S(BUILD_NUMBER)                  \
        CANDIDATE_STRING
#endif

namespace v8 {
namespace internal {

int Version::major_ = MAJOR_VERSION;
int Version::minor_ = MINOR_VERSION;
int Version::build_ = BUILD_NUMBER;
int Version::patch_ = PATCH_LEVEL;
bool Version::candidate_ = (IS_CANDIDATE_VERSION != 0);
const char* Version::soname_ = SONAME;
const char* Version::version_string_ = VERSION_STRING;

// Calculate the V8 version string.
void Version::GetString(Vector<char> str) {
  const char* candidate = IsCandidate() ? " (candidate)" : "";
#ifdef USE_SIMULATOR
  const char* is_simulator = " SIMULATOR";
#else
  const char* is_simulator = "";
#endif  // USE_SIMULATOR
  if (GetPatch() > 0) {
    SNPrintF(str, "%d.%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate,
             is_simulator);
  } else {
    SNPrintF(str, "%d.%d.%d%s%s",
             GetMajor(), GetMinor(), GetBuild(), candidate,
             is_simulator);
  }
}

// Calculate the SONAME for the V8 shared library.
void Version::GetSONAME(Vector<char> str) {
  if (soname_ == NULL || *soname_ == '\0') {
    // Generate generic SONAME if no specific SONAME is defined.
    const char* candidate = IsCandidate() ? "-candidate" : "";
    if (GetPatch() > 0) {
      SNPrintF(str, "libv8-%d.%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), GetPatch(), candidate);
    } else {
      SNPrintF(str, "libv8-%d.%d.%d%s.so",
               GetMajor(), GetMinor(), GetBuild(), candidate);
    }
  } else {
    // Use specific SONAME.
    SNPrintF(str, "%s", soname_);
  }
}

} }  // namespace v8::internal
<|endoftext|>


<commit_before>#include "StdAfx.h"
#include "ArwDecoder.h"
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009 Klaus Post

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

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

ArwDecoder::ArwDecoder( TiffIFD *rootIFD, FileMap* file ) :
 RawDecoder(file), mRootIFD(rootIFD)
{

}

ArwDecoder::~ArwDecoder(void)
{
}

RawImage ArwDecoder::decodeRaw()
{
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(STRIPOFFSETS);

  data = mRootIFD->getIFDsWithTag(STRIPOFFSETS);

  if (data.empty())
    ThrowRDE("ARW Decoder: No image data found");

  TiffIFD* raw = data[0];
  int compression = raw->getEntry(COMPRESSION)->getInt();
  if (32767 != compression)
    ThrowRDE("ARW Decoder: Unsupported compression");

  TiffEntry *offsets = raw->getEntry(STRIPOFFSETS);
  TiffEntry *counts = raw->getEntry(STRIPBYTECOUNTS);

  if (offsets->count != 1) {
    ThrowRDE("ARW Decoder: Multiple Strips found: %u",offsets->count);
  }
  if (counts->count != offsets->count) {
    ThrowRDE("ARW Decoder: Byte count number does not match strip size: count:%u, strips:%u ",counts->count, offsets->count);
  }
  guint width = raw->getEntry(IMAGEWIDTH)->getInt();
  guint height = raw->getEntry(IMAGELENGTH)->getInt();
  guint bitPerPixel = raw->getEntry(BITSPERSAMPLE)->getInt();

  gboolean arw1 = counts->getInt()*8 != width*height*bitPerPixel;
  if (arw1)
    height += 8;

  mRaw->dim = iPoint2D(width, height);
  mRaw->bpp = 2;
  mRaw->createData();

  const gushort* c = raw->getEntry(SONY_CURVE)->getShortArray();
  guint sony_curve[] = { 0,0,0,0,0,4095 };

  for (guint i = 0; i < 4; i++)
    sony_curve[i+1] = (c[i]>> 2) & 0xfff;

  for (guint i = 0; i < 0x4001; i++)
    curve[i] = i;

  for (guint i=0; i < 5; i++)
    for (guint j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
      curve[j] = curve[j-1] + (1 << i);

  guint c2 = counts->getInt();
  guint off = offsets->getInt();
  if (!mFile->isValid(off+c2))
    c2 = mFile->getSize()-off;

  ByteStream input(mFile->getData(off), c2);

  if (arw1)
    DecodeARW(input,width,height);
  else
    DecodeARW2(input,width,height,bitPerPixel);

  return mRaw;
}

void ArwDecoder::DecodeARW(ByteStream &input, guint w, guint h) {
  BitPumpMSB bits(&input);
  guchar* data = mRaw->getData();
  gushort* dest = (gushort*)&data[0];
  guint pitch = mRaw->pitch/sizeof(gushort);
  gint sum = 0;
  for (guint x = w; x--; )
    for (guint y=0; y < h+1; y+=2) {
      bits.checkPos();
      bits.fill();
      if (y == h) y = 1;
      guint len = 4 - bits.getBitsNoFill(2);
      if (len == 3 && bits.getBitNoFill()) len = 0;
      if (len == 4)
        while (len < 17 && !bits.getBitNoFill()) len++;
      bits.fill();
      gint diff = bits.getBitsNoFill(len);
      if ((diff & (1 << (len-1))) == 0)
        diff -= (1 << len) - 1;
      sum += diff;
      _ASSERTE(!(sum >> 12));
      if (y < h) dest[x+y*pitch] = sum;
    }
}

void ArwDecoder::DecodeARW2(ByteStream &input, guint w, guint h, guint bpp) {
  guchar* data = mRaw->getData();
  guint pitch = mRaw->pitch;
  if (bpp == 8) {
    gushort pix[16];
    BitPumpPlain bits(&input);
    for (guint y = 0; y < h; y++ ) {
      gushort* dest = (gushort*)&data[y*pitch];
      bits.setAbsoluteOffset((w*bpp*y)>>3); // Realign
      for (guint x = 0; x < w-30; ) { // Process 32 pixels (16x2) per loop.
        bits.checkPos();
        gint _max = bits.getBits(11);
        gint _min = bits.getBits(11);
        gint _imax = bits.getBits(4);
        gint _imin = bits.getBits(4);
        guint sh;
        for (sh=0; sh < 4 && 0x80 << sh <= _max-_min; sh++);
        for (guint i=0; i < 16; i++) {
          if      ((gint)i == _imax) pix[i] = _max;
          else if ((gint)i == _imin) pix[i] = _min;
          else {
            pix[i] = (bits.getBits(7) << sh) + _min;
            if (pix[i] > 0x7ff) pix[i] = 0x7ff;
          }
        }
        for (guint i=0; i < 16; i++)
          dest[x+i*2] = curve[pix[i] << 1] >> 1;
        x += x & 1 ? 31 : 1;  // Skip to next 32 pixels
      }
    }
    return;
  } // End bpp = 8
  if (bpp==12) {
    guchar* data = mRaw->getData();
    guint pitch = mRaw->pitch;
    const guchar *in = input.getData();
    if (input.getRemainSize()< (w*h*3/2) ) {
      h = input.getRemainSize() / (w*3/2) - 1;
    }
    for (guint y=0; y < h; y++) {
      gushort* dest = (gushort*)&data[y*pitch];
      for(guint x =0 ; x < w; x+=2) {
        guint g1 = curve[*in++];
        guint g2 = curve[*in++];
        dest[x] = g1 | ((g2&0xf)<<8);
        guint g3 = curve[*in++];
        dest[x+1] = (g2>>2) | (g3<<4);
      }
    }
    return;
  }
  ThrowRDE("Unsupported bit depth");
}

void ArwDecoder::checkSupport(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
  if (data.empty())
    ThrowRDE("ARW Support check: Model name found");
  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  this->checkCameraSupported(meta, make, model, "");
}

void ArwDecoder::decodeMetaData(CameraMetaData *meta)
{
  //Default
  mRaw->cfa.setCFA(CFA_RED, CFA_GREEN, CFA_GREEN2, CFA_BLUE);
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("ARW Meta Decoder: Model name found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();

  setMetaData(meta, make, model, "");
}<commit_msg>- Fixed curve mistake. Still not sure if it should be applied.<commit_after>#include "StdAfx.h"
#include "ArwDecoder.h"
/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2009 Klaus Post

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

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

    http://www.klauspost.com
*/

ArwDecoder::ArwDecoder( TiffIFD *rootIFD, FileMap* file ) :
 RawDecoder(file), mRootIFD(rootIFD)
{

}

ArwDecoder::~ArwDecoder(void)
{
}

RawImage ArwDecoder::decodeRaw()
{
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(STRIPOFFSETS);

  data = mRootIFD->getIFDsWithTag(STRIPOFFSETS);

  if (data.empty())
    ThrowRDE("ARW Decoder: No image data found");

  TiffIFD* raw = data[0];
  int compression = raw->getEntry(COMPRESSION)->getInt();
  if (32767 != compression)
    ThrowRDE("ARW Decoder: Unsupported compression");

  TiffEntry *offsets = raw->getEntry(STRIPOFFSETS);
  TiffEntry *counts = raw->getEntry(STRIPBYTECOUNTS);

  if (offsets->count != 1) {
    ThrowRDE("ARW Decoder: Multiple Strips found: %u",offsets->count);
  }
  if (counts->count != offsets->count) {
    ThrowRDE("ARW Decoder: Byte count number does not match strip size: count:%u, strips:%u ",counts->count, offsets->count);
  }
  guint width = raw->getEntry(IMAGEWIDTH)->getInt();
  guint height = raw->getEntry(IMAGELENGTH)->getInt();
  guint bitPerPixel = raw->getEntry(BITSPERSAMPLE)->getInt();

  gboolean arw1 = counts->getInt()*8 != width*height*bitPerPixel;
  if (arw1)
    height += 8;

  mRaw->dim = iPoint2D(width, height);
  mRaw->bpp = 2;
  mRaw->createData();

  const gushort* c = raw->getEntry(SONY_CURVE)->getShortArray();
  guint sony_curve[] = { 0,0,0,0,0,4095 };

  for (guint i = 0; i < 4; i++)
    sony_curve[i+1] = (c[i]>> 2) & 0xfff;

  for (guint i = 0; i < 0x4001; i++)
    curve[i] = i;

  for (guint i=0; i < 5; i++)
    for (guint j = sony_curve[i]+1; j <= sony_curve[i+1]; j++)
      curve[j] = curve[j-1] + (1 << i);

  guint c2 = counts->getInt();
  guint off = offsets->getInt();
  if (!mFile->isValid(off+c2))
    c2 = mFile->getSize()-off;

  ByteStream input(mFile->getData(off), c2);

  if (arw1)
    DecodeARW(input,width,height);
  else
    DecodeARW2(input,width,height,bitPerPixel);

  return mRaw;
}

void ArwDecoder::DecodeARW(ByteStream &input, guint w, guint h) {
  BitPumpMSB bits(&input);
  guchar* data = mRaw->getData();
  gushort* dest = (gushort*)&data[0];
  guint pitch = mRaw->pitch/sizeof(gushort);
  gint sum = 0;
  for (guint x = w; x--; )
    for (guint y=0; y < h+1; y+=2) {
      bits.checkPos();
      bits.fill();
      if (y == h) y = 1;
      guint len = 4 - bits.getBitsNoFill(2);
      if (len == 3 && bits.getBitNoFill()) len = 0;
      if (len == 4)
        while (len < 17 && !bits.getBitNoFill()) len++;
      bits.fill();
      gint diff = bits.getBitsNoFill(len);
      if ((diff & (1 << (len-1))) == 0)
        diff -= (1 << len) - 1;
      sum += diff;
      _ASSERTE(!(sum >> 12));
      if (y < h) dest[x+y*pitch] = sum;
    }
}

void ArwDecoder::DecodeARW2(ByteStream &input, guint w, guint h, guint bpp) {
  guchar* data = mRaw->getData();
  guint pitch = mRaw->pitch;
  if (bpp == 8) {
    gushort pix[16];
    BitPumpPlain bits(&input);
    for (guint y = 0; y < h; y++ ) {
      gushort* dest = (gushort*)&data[y*pitch];
      bits.setAbsoluteOffset((w*bpp*y)>>3); // Realign
      for (guint x = 0; x < w-30; ) { // Process 32 pixels (16x2) per loop.
        bits.checkPos();
        gint _max = bits.getBits(11);
        gint _min = bits.getBits(11);
        gint _imax = bits.getBits(4);
        gint _imin = bits.getBits(4);
        guint sh;
        for (sh=0; sh < 4 && 0x80 << sh <= _max-_min; sh++);
        for (guint i=0; i < 16; i++) {
          if      ((gint)i == _imax) pix[i] = _max;
          else if ((gint)i == _imin) pix[i] = _min;
          else {
            pix[i] = (bits.getBits(7) << sh) + _min;
            if (pix[i] > 0x7ff) pix[i] = 0x7ff;
          }
        }
        for (guint i=0; i < 16; i++)
          dest[x+i*2] = curve[pix[i] << 1] >> 1;
        x += x & 1 ? 31 : 1;  // Skip to next 32 pixels
      }
    }
    return;
  } // End bpp = 8
  if (bpp==12) {
    guchar* data = mRaw->getData();
    guint pitch = mRaw->pitch;
    const guchar *in = input.getData();
    if (input.getRemainSize()< (w*h*3/2) ) {
      h = input.getRemainSize() / (w*3/2) - 1;
    }
    for (guint y=0; y < h; y++) {
      gushort* dest = (gushort*)&data[y*pitch];
      for(guint x =0 ; x < w; x+=2) {
        guint g1 = *in++;
        guint g2 = *in++;
        dest[x] = curve[g1 | ((g2&0xf)<<8)];
        guint g3 = *in++;
        dest[x+1] = curve[(g2>>2) | (g3<<4)];
      }
    }
    return;
  }
  ThrowRDE("Unsupported bit depth");
}

void ArwDecoder::checkSupport(CameraMetaData *meta) {
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
  if (data.empty())
    ThrowRDE("ARW Support check: Model name found");
  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();
  this->checkCameraSupported(meta, make, model, "");
}

void ArwDecoder::decodeMetaData(CameraMetaData *meta)
{
  //Default
  mRaw->cfa.setCFA(CFA_RED, CFA_GREEN, CFA_GREEN2, CFA_BLUE);
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);

  if (data.empty())
    ThrowRDE("ARW Meta Decoder: Model name found");

  string make = data[0]->getEntry(MAKE)->getString();
  string model = data[0]->getEntry(MODEL)->getString();

  setMetaData(meta, make, model, "");
}<|endoftext|>