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

#include "chrome/browser/sync_file_system/sync_file_system_service.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_dependency_manager.h"
#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
#include "chrome/browser/sync_file_system/local_file_sync_service.h"
#include "chrome/browser/sync_file_system/sync_event_observer.h"
#include "content/public/browser/browser_thread.h"
#include "googleurl/src/gurl.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/syncable/sync_file_metadata.h"
#include "webkit/fileapi/syncable/sync_status_code.h"

using content::BrowserThread;
using fileapi::ConflictFileInfoCallback;
using fileapi::FileSystemURL;
using fileapi::SyncFileMetadata;
using fileapi::SyncStatusCallback;
using fileapi::SyncStatusCode;

namespace sync_file_system {

namespace {

// Run the given join_callback when all the callbacks created by this runner
// are run, or may dispatch it earlier if we get an error in any of the sub
// callbacks.
class SharedCallbackRunner
    : public base::RefCountedThreadSafe<SharedCallbackRunner> {
 public:
  explicit SharedCallbackRunner(const SyncStatusCallback& join_callback)
      : join_callback_(join_callback),
        num_shared_callbacks_(0) {}

  SyncStatusCallback CreateCallback() {
    ++num_shared_callbacks_;
    return base::Bind(&SharedCallbackRunner::Done, this);
  }

  template <typename R>
  base::Callback<void(SyncStatusCode, const R& in)>
  CreateAssignAndRunCallback(R* out) {
    ++num_shared_callbacks_;
    return base::Bind(&SharedCallbackRunner::AssignAndRun<R>, this, out);
  }

 private:
  virtual ~SharedCallbackRunner() {}
  friend class base::RefCountedThreadSafe<SharedCallbackRunner>;

  template <typename R>
  void AssignAndRun(R* out, SyncStatusCode status, const R& in) {
    DCHECK(out);
    DCHECK_GT(num_shared_callbacks_, 0);
    if (join_callback_.is_null())
      return;
    *out = in;
    Done(status);
  }

  void Done(SyncStatusCode status) {
    if (status != fileapi::SYNC_STATUS_OK) {
      join_callback_.Run(status);
      join_callback_.Reset();
      return;
    }
    if (--num_shared_callbacks_ > 0)
      return;
    join_callback_.Run(status);
    join_callback_.Reset();
  }

  SyncStatusCallback join_callback_;
  int num_shared_callbacks_;
};

void VerifyFileSystemURLSetCallback(
    base::WeakPtr<SyncFileSystemService> service,
    const GURL& app_origin,
    const std::string& service_name,
    const fileapi::SyncFileSetCallback& callback,
    fileapi::SyncStatusCode status,
    const fileapi::FileSystemURLSet& urls) {
  if (!service.get())
    return;

#ifndef NDEBUG
  if (status == fileapi::SYNC_STATUS_OK) {
    for (fileapi::FileSystemURLSet::const_iterator iter = urls.begin();
         iter != urls.end(); ++iter) {
      DCHECK(iter->origin() == app_origin);
      DCHECK(iter->filesystem_id() == service_name);
    }
  }
#endif

  callback.Run(status, urls);
}

SyncEventObserver::SyncServiceState RemoteStateToSyncServiceState(
    RemoteServiceState state) {
  switch (state) {
    case REMOTE_SERVICE_OK:
      return SyncEventObserver::SYNC_SERVICE_RUNNING;
    case REMOTE_SERVICE_TEMPORARY_UNAVAILABLE:
      return SyncEventObserver::SYNC_SERVICE_TEMPORARY_UNAVAILABLE;
    case REMOTE_SERVICE_AUTHENTICATION_REQUIRED:
      return SyncEventObserver::SYNC_SERVICE_AUTHENTICATION_REQUIRED;
    case REMOTE_SERVICE_DISABLED:
      return SyncEventObserver::SYNC_SERVICE_DISABLED;
  }
  NOTREACHED();
  return SyncEventObserver::SYNC_SERVICE_DISABLED;
}

}  // namespace

void SyncFileSystemService::Shutdown() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  local_file_service_->Shutdown();
  local_file_service_.reset();

  remote_file_service_.reset();

  profile_ = NULL;
}

SyncFileSystemService::~SyncFileSystemService() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(!profile_);
  STLDeleteContainerPairSecondPointers(observer_map_.begin(),
                                       observer_map_.end());
}

void SyncFileSystemService::InitializeForApp(
    fileapi::FileSystemContext* file_system_context,
    const std::string& service_name,
    const GURL& app_origin,
    const SyncStatusCallback& callback) {
  DCHECK(local_file_service_);
  DCHECK(remote_file_service_);
  DCHECK(app_origin == app_origin.GetOrigin());

  bool inserted = initialized_app_origins_.insert(app_origin).second;
  if (!inserted) {
    callback.Run(fileapi::SYNC_STATUS_OK);
    return;
  }

  if (ContainsKey(observer_map_, app_origin)) {
    FOR_EACH_OBSERVER(
        SyncEventObserver, *observer_map_[app_origin],
        OnSyncStateUpdated(SyncEventObserver::SYNC_SERVICE_INITIALIZING,
                           "Registering the application"));
  }

  scoped_refptr<SharedCallbackRunner> callback_runner(
      new SharedCallbackRunner(callback));

  local_file_service_->MaybeInitializeFileSystemContext(
      app_origin, service_name, file_system_context,
      callback_runner->CreateCallback());
  remote_file_service_->RegisterOriginForTrackingChanges(
      app_origin,
      base::Bind(&SyncFileSystemService::DidRegisterOrigin,
                 AsWeakPtr(), app_origin,
                 callback_runner->CreateCallback()));
}

void SyncFileSystemService::GetConflictFiles(
    const GURL& app_origin,
    const std::string& service_name,
    const fileapi::SyncFileSetCallback& callback) {
  DCHECK(remote_file_service_);
  DCHECK(app_origin == app_origin.GetOrigin());

  // TODO(kinuko): Should we just call Initialize first?
  if (!ContainsKey(initialized_app_origins_, app_origin)) {
    callback.Run(fileapi::SYNC_STATUS_NOT_INITIALIZED,
                 fileapi::FileSystemURLSet());
    return;
  }

  remote_file_service_->GetConflictFiles(
      app_origin, base::Bind(&VerifyFileSystemURLSetCallback,
                             AsWeakPtr(), app_origin, service_name, callback));
}

void SyncFileSystemService::GetConflictFileInfo(
    const GURL& app_origin,
    const std::string& service_name,
    const FileSystemURL& url,
    const ConflictFileInfoCallback& callback) {
  DCHECK(local_file_service_);
  DCHECK(remote_file_service_);
  DCHECK(app_origin == app_origin.GetOrigin());

  // TODO(kinuko): Should we just call Initialize first?
  if (!ContainsKey(initialized_app_origins_, app_origin)) {
    callback.Run(fileapi::SYNC_STATUS_NOT_INITIALIZED,
                 fileapi::ConflictFileInfo());
    return;
  }

  // Call DidGetConflictFileInfo when both remote and local service's
  // GetFileMetadata calls are done.
  SyncFileMetadata* remote_metadata = new SyncFileMetadata;
  SyncFileMetadata* local_metadata = new SyncFileMetadata;
  SyncStatusCallback completion_callback =
      base::Bind(&SyncFileSystemService::DidGetConflictFileInfo,
                 AsWeakPtr(), callback, url,
                 base::Owned(local_metadata),
                 base::Owned(remote_metadata));
  scoped_refptr<SharedCallbackRunner> callback_runner(
      new SharedCallbackRunner(completion_callback));
  local_file_service_->GetLocalFileMetadata(
      url, callback_runner->CreateAssignAndRunCallback(local_metadata));
  remote_file_service_->GetRemoteFileMetadata(
      url, callback_runner->CreateAssignAndRunCallback(remote_metadata));
}

void SyncFileSystemService::AddSyncEventObserver(
    const GURL& app_origin,
    SyncEventObserver* observer) {
  if (!ContainsKey(observer_map_, app_origin))
    observer_map_[app_origin] = new EventObserverList;
  observer_map_[app_origin]->AddObserver(observer);
}

void SyncFileSystemService::RemoveSyncEventObserver(
    const GURL& app_origin,
    SyncEventObserver* observer) {
  if (!ContainsKey(observer_map_, app_origin))
    return;
  observer_map_[app_origin]->RemoveObserver(observer);
}

void SyncFileSystemService::OnLocalChangeAvailable(int64 pending_changes) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK_GE(pending_changes, 0);
  pending_local_changes_ = pending_changes;
}

void SyncFileSystemService::OnRemoteChangeAvailable(int64 pending_changes) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK_GE(pending_changes, 0);
  pending_remote_changes_ = pending_changes;
}

void SyncFileSystemService::OnRemoteServiceStateUpdated(
    RemoteServiceState state,
    const std::string& description) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  for (ObserverMap::iterator iter = observer_map_.begin();
       iter != observer_map_.end(); ++iter) {
    FOR_EACH_OBSERVER(SyncEventObserver, *iter->second,
                      OnSyncStateUpdated(RemoteStateToSyncServiceState(state),
                                         description));
  }
}

SyncFileSystemService::SyncFileSystemService(Profile* profile)
    : profile_(profile),
      pending_local_changes_(0),
      pending_remote_changes_(0) {}

void SyncFileSystemService::Initialize(
    scoped_ptr<LocalFileSyncService> local_file_service,
    scoped_ptr<RemoteFileSyncService> remote_file_service) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(local_file_service);
  DCHECK(remote_file_service);
  DCHECK(profile_);

  local_file_service_ = local_file_service.Pass();
  remote_file_service_ = remote_file_service.Pass();

  remote_file_service_->AddObserver(this);
}

void SyncFileSystemService::DidGetConflictFileInfo(
    const ConflictFileInfoCallback& callback,
    const FileSystemURL& url,
    const SyncFileMetadata* local_metadata,
    const SyncFileMetadata* remote_metadata,
    SyncStatusCode status) {
  DCHECK(local_metadata);
  DCHECK(remote_metadata);
  fileapi::ConflictFileInfo info;
  info.url = url;
  info.local_metadata = *local_metadata;
  info.remote_metadata = *remote_metadata;
  callback.Run(status, info);
}

void SyncFileSystemService::DidRegisterOrigin(
    const GURL& app_origin,
    const fileapi::SyncStatusCallback& callback,
    fileapi::SyncStatusCode status) {
  if (status == fileapi::SYNC_STATUS_AUTHENTICATION_FAILED ||
      status == fileapi::SYNC_STATUS_RETRY ||
      status == fileapi::SYNC_STATUS_NETWORK_ERROR) {
    // We're having temporary network errors or authentication errors.
    // We're not yet sure if they're resolvable, but queue them up so that
    // we can retry.
    pending_register_origins_.insert(app_origin);
    status = fileapi::SYNC_STATUS_OK;
  }
  callback.Run(status);
}

// SyncFileSystemServiceFactory -----------------------------------------------

// static
SyncFileSystemService* SyncFileSystemServiceFactory::GetForProfile(
    Profile* profile) {
  return static_cast<SyncFileSystemService*>(
      GetInstance()->GetServiceForProfile(profile, true));
}

// static
SyncFileSystemServiceFactory* SyncFileSystemServiceFactory::GetInstance() {
  return Singleton<SyncFileSystemServiceFactory>::get();
}

void SyncFileSystemServiceFactory::set_mock_remote_file_service(
    scoped_ptr<RemoteFileSyncService> mock_remote_service) {
  mock_remote_file_service_ = mock_remote_service.Pass();
}

SyncFileSystemServiceFactory::SyncFileSystemServiceFactory()
    : ProfileKeyedServiceFactory("SyncFileSystemService",
                                 ProfileDependencyManager::GetInstance()) {
}

SyncFileSystemServiceFactory::~SyncFileSystemServiceFactory() {}

ProfileKeyedService* SyncFileSystemServiceFactory::BuildServiceInstanceFor(
    Profile* profile) const {
  SyncFileSystemService* service = new SyncFileSystemService(profile);

  scoped_ptr<LocalFileSyncService> local_file_service(
      new LocalFileSyncService);

  scoped_ptr<RemoteFileSyncService> remote_file_service;
  if (mock_remote_file_service_)
    remote_file_service = mock_remote_file_service_.Pass();
  else
    remote_file_service.reset(new DriveFileSyncService(profile));

  service->Initialize(local_file_service.Pass(),
                      remote_file_service.Pass());
  return service;
}

}  // namespace sync_file_system
<commit_msg>Wait until all callbacks run in SharedCallbackRunner<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync_file_system/sync_file_system_service.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/stl_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_dependency_manager.h"
#include "chrome/browser/sync_file_system/drive_file_sync_service.h"
#include "chrome/browser/sync_file_system/local_file_sync_service.h"
#include "chrome/browser/sync_file_system/sync_event_observer.h"
#include "content/public/browser/browser_thread.h"
#include "googleurl/src/gurl.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/syncable/sync_file_metadata.h"
#include "webkit/fileapi/syncable/sync_status_code.h"

using content::BrowserThread;
using fileapi::ConflictFileInfoCallback;
using fileapi::FileSystemURL;
using fileapi::SyncFileMetadata;
using fileapi::SyncStatusCallback;
using fileapi::SyncStatusCode;

namespace sync_file_system {

namespace {

// Run the given join_callback when all the callbacks created by this runner
// are run. If any of the callbacks return non-OK state the given join_callback
// will be dispatched with the non-OK state that comes first.
class SharedCallbackRunner
    : public base::RefCountedThreadSafe<SharedCallbackRunner> {
 public:
  explicit SharedCallbackRunner(const SyncStatusCallback& join_callback)
      : join_callback_(join_callback),
        num_shared_callbacks_(0),
        status_(fileapi::SYNC_STATUS_OK) {}

  SyncStatusCallback CreateCallback() {
    ++num_shared_callbacks_;
    return base::Bind(&SharedCallbackRunner::Done, this);
  }

  template <typename R>
  base::Callback<void(SyncStatusCode, const R& in)>
  CreateAssignAndRunCallback(R* out) {
    ++num_shared_callbacks_;
    return base::Bind(&SharedCallbackRunner::AssignAndRun<R>, this, out);
  }

 private:
  virtual ~SharedCallbackRunner() {}
  friend class base::RefCountedThreadSafe<SharedCallbackRunner>;

  template <typename R>
  void AssignAndRun(R* out, SyncStatusCode status, const R& in) {
    DCHECK(out);
    DCHECK_GT(num_shared_callbacks_, 0);
    if (join_callback_.is_null())
      return;
    *out = in;
    Done(status);
  }

  void Done(SyncStatusCode status) {
    if (status != fileapi::SYNC_STATUS_OK &&
        status_ == fileapi::SYNC_STATUS_OK) {
      status_ = status;
    }
    if (--num_shared_callbacks_ > 0)
      return;
    join_callback_.Run(status_);
    join_callback_.Reset();
  }

  SyncStatusCallback join_callback_;
  int num_shared_callbacks_;
  SyncStatusCode status_;
};

void VerifyFileSystemURLSetCallback(
    base::WeakPtr<SyncFileSystemService> service,
    const GURL& app_origin,
    const std::string& service_name,
    const fileapi::SyncFileSetCallback& callback,
    fileapi::SyncStatusCode status,
    const fileapi::FileSystemURLSet& urls) {
  if (!service.get())
    return;

#ifndef NDEBUG
  if (status == fileapi::SYNC_STATUS_OK) {
    for (fileapi::FileSystemURLSet::const_iterator iter = urls.begin();
         iter != urls.end(); ++iter) {
      DCHECK(iter->origin() == app_origin);
      DCHECK(iter->filesystem_id() == service_name);
    }
  }
#endif

  callback.Run(status, urls);
}

SyncEventObserver::SyncServiceState RemoteStateToSyncServiceState(
    RemoteServiceState state) {
  switch (state) {
    case REMOTE_SERVICE_OK:
      return SyncEventObserver::SYNC_SERVICE_RUNNING;
    case REMOTE_SERVICE_TEMPORARY_UNAVAILABLE:
      return SyncEventObserver::SYNC_SERVICE_TEMPORARY_UNAVAILABLE;
    case REMOTE_SERVICE_AUTHENTICATION_REQUIRED:
      return SyncEventObserver::SYNC_SERVICE_AUTHENTICATION_REQUIRED;
    case REMOTE_SERVICE_DISABLED:
      return SyncEventObserver::SYNC_SERVICE_DISABLED;
  }
  NOTREACHED();
  return SyncEventObserver::SYNC_SERVICE_DISABLED;
}

}  // namespace

void SyncFileSystemService::Shutdown() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  local_file_service_->Shutdown();
  local_file_service_.reset();

  remote_file_service_.reset();

  profile_ = NULL;
}

SyncFileSystemService::~SyncFileSystemService() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(!profile_);
  STLDeleteContainerPairSecondPointers(observer_map_.begin(),
                                       observer_map_.end());
}

void SyncFileSystemService::InitializeForApp(
    fileapi::FileSystemContext* file_system_context,
    const std::string& service_name,
    const GURL& app_origin,
    const SyncStatusCallback& callback) {
  DCHECK(local_file_service_);
  DCHECK(remote_file_service_);
  DCHECK(app_origin == app_origin.GetOrigin());

  bool inserted = initialized_app_origins_.insert(app_origin).second;
  if (!inserted) {
    callback.Run(fileapi::SYNC_STATUS_OK);
    return;
  }

  if (ContainsKey(observer_map_, app_origin)) {
    FOR_EACH_OBSERVER(
        SyncEventObserver, *observer_map_[app_origin],
        OnSyncStateUpdated(SyncEventObserver::SYNC_SERVICE_INITIALIZING,
                           "Registering the application"));
  }

  scoped_refptr<SharedCallbackRunner> callback_runner(
      new SharedCallbackRunner(callback));

  local_file_service_->MaybeInitializeFileSystemContext(
      app_origin, service_name, file_system_context,
      callback_runner->CreateCallback());
  remote_file_service_->RegisterOriginForTrackingChanges(
      app_origin,
      base::Bind(&SyncFileSystemService::DidRegisterOrigin,
                 AsWeakPtr(), app_origin,
                 callback_runner->CreateCallback()));
}

void SyncFileSystemService::GetConflictFiles(
    const GURL& app_origin,
    const std::string& service_name,
    const fileapi::SyncFileSetCallback& callback) {
  DCHECK(remote_file_service_);
  DCHECK(app_origin == app_origin.GetOrigin());

  // TODO(kinuko): Should we just call Initialize first?
  if (!ContainsKey(initialized_app_origins_, app_origin)) {
    callback.Run(fileapi::SYNC_STATUS_NOT_INITIALIZED,
                 fileapi::FileSystemURLSet());
    return;
  }

  remote_file_service_->GetConflictFiles(
      app_origin, base::Bind(&VerifyFileSystemURLSetCallback,
                             AsWeakPtr(), app_origin, service_name, callback));
}

void SyncFileSystemService::GetConflictFileInfo(
    const GURL& app_origin,
    const std::string& service_name,
    const FileSystemURL& url,
    const ConflictFileInfoCallback& callback) {
  DCHECK(local_file_service_);
  DCHECK(remote_file_service_);
  DCHECK(app_origin == app_origin.GetOrigin());

  // TODO(kinuko): Should we just call Initialize first?
  if (!ContainsKey(initialized_app_origins_, app_origin)) {
    callback.Run(fileapi::SYNC_STATUS_NOT_INITIALIZED,
                 fileapi::ConflictFileInfo());
    return;
  }

  // Call DidGetConflictFileInfo when both remote and local service's
  // GetFileMetadata calls are done.
  SyncFileMetadata* remote_metadata = new SyncFileMetadata;
  SyncFileMetadata* local_metadata = new SyncFileMetadata;
  SyncStatusCallback completion_callback =
      base::Bind(&SyncFileSystemService::DidGetConflictFileInfo,
                 AsWeakPtr(), callback, url,
                 base::Owned(local_metadata),
                 base::Owned(remote_metadata));
  scoped_refptr<SharedCallbackRunner> callback_runner(
      new SharedCallbackRunner(completion_callback));
  local_file_service_->GetLocalFileMetadata(
      url, callback_runner->CreateAssignAndRunCallback(local_metadata));
  remote_file_service_->GetRemoteFileMetadata(
      url, callback_runner->CreateAssignAndRunCallback(remote_metadata));
}

void SyncFileSystemService::AddSyncEventObserver(
    const GURL& app_origin,
    SyncEventObserver* observer) {
  if (!ContainsKey(observer_map_, app_origin))
    observer_map_[app_origin] = new EventObserverList;
  observer_map_[app_origin]->AddObserver(observer);
}

void SyncFileSystemService::RemoveSyncEventObserver(
    const GURL& app_origin,
    SyncEventObserver* observer) {
  if (!ContainsKey(observer_map_, app_origin))
    return;
  observer_map_[app_origin]->RemoveObserver(observer);
}

void SyncFileSystemService::OnLocalChangeAvailable(int64 pending_changes) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK_GE(pending_changes, 0);
  pending_local_changes_ = pending_changes;
}

void SyncFileSystemService::OnRemoteChangeAvailable(int64 pending_changes) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK_GE(pending_changes, 0);
  pending_remote_changes_ = pending_changes;
}

void SyncFileSystemService::OnRemoteServiceStateUpdated(
    RemoteServiceState state,
    const std::string& description) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  for (ObserverMap::iterator iter = observer_map_.begin();
       iter != observer_map_.end(); ++iter) {
    FOR_EACH_OBSERVER(SyncEventObserver, *iter->second,
                      OnSyncStateUpdated(RemoteStateToSyncServiceState(state),
                                         description));
  }
}

SyncFileSystemService::SyncFileSystemService(Profile* profile)
    : profile_(profile),
      pending_local_changes_(0),
      pending_remote_changes_(0) {}

void SyncFileSystemService::Initialize(
    scoped_ptr<LocalFileSyncService> local_file_service,
    scoped_ptr<RemoteFileSyncService> remote_file_service) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DCHECK(local_file_service);
  DCHECK(remote_file_service);
  DCHECK(profile_);

  local_file_service_ = local_file_service.Pass();
  remote_file_service_ = remote_file_service.Pass();

  remote_file_service_->AddObserver(this);
}

void SyncFileSystemService::DidGetConflictFileInfo(
    const ConflictFileInfoCallback& callback,
    const FileSystemURL& url,
    const SyncFileMetadata* local_metadata,
    const SyncFileMetadata* remote_metadata,
    SyncStatusCode status) {
  DCHECK(local_metadata);
  DCHECK(remote_metadata);
  fileapi::ConflictFileInfo info;
  info.url = url;
  info.local_metadata = *local_metadata;
  info.remote_metadata = *remote_metadata;
  callback.Run(status, info);
}

void SyncFileSystemService::DidRegisterOrigin(
    const GURL& app_origin,
    const fileapi::SyncStatusCallback& callback,
    fileapi::SyncStatusCode status) {
  if (status == fileapi::SYNC_STATUS_AUTHENTICATION_FAILED ||
      status == fileapi::SYNC_STATUS_RETRY ||
      status == fileapi::SYNC_STATUS_NETWORK_ERROR) {
    // We're having temporary network errors or authentication errors.
    // We're not yet sure if they're resolvable, but queue them up so that
    // we can retry.
    pending_register_origins_.insert(app_origin);
    status = fileapi::SYNC_STATUS_OK;
  }
  callback.Run(status);
}

// SyncFileSystemServiceFactory -----------------------------------------------

// static
SyncFileSystemService* SyncFileSystemServiceFactory::GetForProfile(
    Profile* profile) {
  return static_cast<SyncFileSystemService*>(
      GetInstance()->GetServiceForProfile(profile, true));
}

// static
SyncFileSystemServiceFactory* SyncFileSystemServiceFactory::GetInstance() {
  return Singleton<SyncFileSystemServiceFactory>::get();
}

void SyncFileSystemServiceFactory::set_mock_remote_file_service(
    scoped_ptr<RemoteFileSyncService> mock_remote_service) {
  mock_remote_file_service_ = mock_remote_service.Pass();
}

SyncFileSystemServiceFactory::SyncFileSystemServiceFactory()
    : ProfileKeyedServiceFactory("SyncFileSystemService",
                                 ProfileDependencyManager::GetInstance()) {
}

SyncFileSystemServiceFactory::~SyncFileSystemServiceFactory() {}

ProfileKeyedService* SyncFileSystemServiceFactory::BuildServiceInstanceFor(
    Profile* profile) const {
  SyncFileSystemService* service = new SyncFileSystemService(profile);

  scoped_ptr<LocalFileSyncService> local_file_service(
      new LocalFileSyncService);

  scoped_ptr<RemoteFileSyncService> remote_file_service;
  if (mock_remote_file_service_)
    remote_file_service = mock_remote_file_service_.Pass();
  else
    remote_file_service.reset(new DriveFileSyncService(profile));

  service->Initialize(local_file_service.Pass(),
                      remote_file_service.Pass());
  return service;
}

}  // namespace sync_file_system
<|endoftext|>


<commit_before><commit_msg>[Password Manger] Fix bug in link to passwords.google.com<commit_after><|endoftext|>


<commit_before>#include <algorithm>
#include <string>
#include <stdio.h>
#include <assert.h>
#include <stdint.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

using namespace std;

string readFile(const char* file)
{
  string result;
  int fd = open(file, O_RDONLY);
  if (fd >= 0) {
    char buf[256*1024];
    ssize_t nr = 0;
    while ( (nr = read(fd, buf, sizeof buf)) > 0) {
      result.append(buf, nr);
    }
    close(fd);
  } else {
    perror(file);
    abort();
  }
  return result;
}

enum Encoding
{
  kUnknown, kUnicode, kGBK, kUTF8,
};

const char* getEncodingName(Encoding enc)
{
  if (enc == kUTF8) {
    return "UTF-8";
  } else if (enc == kUnicode) {
    return "Unicode";
  } else {
    return "Unknown";
  }
}

Encoding detectEncoding(const string& content)
{
  if (content.size() < 2)
    return kGBK;

  if (content[0] == '\xFF' && content[1] == '\xFE') {
    return kUnicode;
  } else {
    for (size_t i = 0; i < content.size()-2;) {
      if (content[i] & 0x80) {
        if ((content[i+1] & 0x80) == 0) {
          return kGBK;
        } else if ((content[i] & 0xE0) == 0xC0) {
          if ((content[i+1] & 0xC0) == 0x80) {
            return kGBK;
          } else {
            i += 2;
          }
        } else if ((content[i] & 0xF0) == 0xE0) {
          if ((content[i+1] & 0xC0) == 0x80) {
            if ((content[i+2] & 0xC0) == 0x80) {
              //printf("UTF-8 !!!\n");
              return kUTF8;
            } else {
              return kGBK;
            }
          } else {
            return kGBK;
          }
        } else {
          return kGBK;
        }
      } else {
        ++i;
      }
    }
    return kUTF8;
  }
}

int countChineseCharsGbk(const string& content)
{
  int cnt = 0;
  for (size_t i = 0; i < content.size(); ++i) {
    if (content[i] & 0x80) {
      ++cnt;
      ++i;
    }
  }
  return cnt;
}

int countChineseCharsUcs2(const string& content)
{
  assert(content.size() % 2 == 0);
  int cnt = 0;
  const uint16_t* p = reinterpret_cast<const uint16_t*>(content.c_str());
  ++p;
  for (size_t i = 2; i < content.size()/2; ++i) {
    if (*p++ > 127)
      ++cnt;
  }
  return cnt;
}

int countChineseCharsUtf8(const string& content)
{
  int cnt = 0;
  for (size_t i = 0; i < content.size();) {
    char c = content[i];
    if ((c & 0x80) == 0) {
      ++i;
    } else if ((c & 0xe0) == 0xc0) {
      i += 2;
    } else if ((c & 0xf0) == 0xe0) {
      i += 3;
      ++cnt;
    } else {
      abort();
    }
  }
  return cnt;
}

int main(int argc, char* argv[])
{
  int totalLines = 0;
  int totalChinese = 0;
  size_t totalBytes = 0;
  for (int i = 1; i < argc; ++i) {
    const char* file = argv[i];
    string content = readFile(file);
    Encoding enc = detectEncoding(content);
    int chinese = 0;
    if (enc == kGBK) {
      chinese = countChineseCharsGbk(content);
    } else if (enc == kUnicode) {
      chinese = countChineseCharsUcs2(content);
    } else {
      chinese = countChineseCharsUtf8(content);
    }
    int lines = std::count(content.begin(), content.end(), '\n');
    printf("%6d %6d %7zd %s (%s)\n",
        lines, chinese, content.size(), file, getEncodingName(enc));
    totalLines += lines;
    totalChinese += chinese;
    totalBytes += content.size();
  }
  printf("%6d %6d %7zd total\n", totalLines, totalChinese, totalBytes);
}

<commit_msg>cwc supports reading stdin.<commit_after>#include <algorithm>
#include <string>
#include <stdio.h>
#include <assert.h>
#include <stdint.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

using namespace std;

string readFile(const char* file)
{
  string result;
  // 128 KiB is from:
  // http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ioblksize.h
  // > As of May 2014, 128KiB is determined to be the minimium
  // > blksize to best minimize system call overhead.
  char buf[128*1024];
  if (strcmp(file, "-") == 0) {
    size_t nr = 0;
    while ( (nr = fread(buf, 1, sizeof buf, stdin)) > 0) {
      // printf("%zd\n", nr);
      result.append(buf, nr);
      if (feof(stdin))
        break;
    }
    return result;
  }
  int fd = open(file, O_RDONLY);
  if (fd >= 0) {
    ssize_t nr = 0;
    while ( (nr = read(fd, buf, sizeof buf)) > 0) {
      result.append(buf, nr);
    }
    close(fd);
  } else {
    perror(file);
    abort();
  }
  return result;
}

enum Encoding
{
  kUnknown, kUnicode, kGBK, kUTF8,
};

const char* getEncodingName(Encoding enc)
{
  switch (enc) {
    case kUnicode:
      return "Unicode";
    case kUTF8:
      return "UTF-8";
    case kGBK:
      return "GBK";
    default:
      return "Unknown";
  }
}

Encoding detectEncoding(const string& content)
{
  if (content.size() < 2)
    return kGBK;

  if (content[0] == '\xFF' && content[1] == '\xFE') {
    return kUnicode;
  } else {
    for (size_t i = 0; i < content.size()-2;) {
      if (content[i] & 0x80) {
        if ((content[i+1] & 0x80) == 0) {
          return kGBK;
        } else if ((content[i] & 0xE0) == 0xC0) {
          if ((content[i+1] & 0xC0) == 0x80) {
            return kGBK;
          } else {
            i += 2;
          }
        } else if ((content[i] & 0xF0) == 0xE0) {
          if ((content[i+1] & 0xC0) == 0x80) {
            if ((content[i+2] & 0xC0) == 0x80) {
              //printf("UTF-8 !!!\n");
              return kUTF8;
            } else {
              return kGBK;
            }
          } else {
            return kGBK;
          }
        } else {
          return kGBK;
        }
      } else {
        ++i;
      }
    }
    return kUTF8;
  }
}

int countChineseCharsGbk(const string& content)
{
  int cnt = 0;
  for (size_t i = 0; i < content.size(); ++i) {
    if (content[i] & 0x80) {
      ++cnt;
      ++i;
    }
  }
  return cnt;
}

int countChineseCharsUcs2(const string& content)
{
  assert(content.size() % 2 == 0);
  int cnt = 0;
  const uint16_t* p = reinterpret_cast<const uint16_t*>(content.c_str());
  ++p;
  for (size_t i = 2; i < content.size()/2; ++i) {
    if (*p++ > 127)
      ++cnt;
  }
  return cnt;
}

int countChineseCharsUtf8(const string& content)
{
  int cnt = 0;
  for (size_t i = 0; i < content.size();) {
    char c = content[i];
    if ((c & 0x80) == 0) {
      ++i;
    } else if ((c & 0xe0) == 0xc0) {
      i += 2;
    } else if ((c & 0xf0) == 0xe0) {
      i += 3;
      ++cnt;
    } else {
      abort();
    }
  }
  return cnt;
}

int countChinese(const string& content, Encoding* enc)
{
  *enc = detectEncoding(content);
  int chinese = 0;
  if (*enc == kGBK) {
    chinese = countChineseCharsGbk(content);
  } else if (*enc == kUnicode) {
    chinese = countChineseCharsUcs2(content);
  } else {
    chinese = countChineseCharsUtf8(content);
  }

  return chinese;
}

int main(int argc, char* argv[])
{
  int totalLines = 0;
  int totalChinese = 0;
  size_t totalBytes = 0;
  if (argc <= 1) {
    const char* file = "-";
    string content = readFile(file);
    Encoding enc = kUnknown;
    int chinese = countChinese(content, &enc);
    int lines = std::count(content.begin(), content.end(), '\n');
    printf("%6d %6d %7zd %s (%s)\n",
        lines, chinese, content.size(), file, getEncodingName(enc));
    return 0;
  }
  for (int i = 1; i < argc; ++i) {
    const char* file = argv[i];
    string content = readFile(file);
    Encoding enc = kUnknown;
    int chinese = countChinese(content, &enc);
    int lines = std::count(content.begin(), content.end(), '\n');
    printf("%6d %6d %7zd %s (%s)\n",
        lines, chinese, content.size(), file, getEncodingName(enc));
    totalLines += lines;
    totalChinese += chinese;
    totalBytes += content.size();
  }
  printf("%6d %6d %7zd total\n", totalLines, totalChinese, totalBytes);
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <swtypes.hxx>
#include <selectdbtabledialog.hxx>
#include <dbtablepreviewdialog.hxx>
#include "svtools/treelistentry.hxx"
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>

#include <unomid.h>

#include <selectdbtabledialog.hrc>
#include <dbui.hrc>
#include <helpid.h>

using namespace ::com::sun::star;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;

SwSelectDBTableDialog::SwSelectDBTableDialog(Window* pParent,
        const uno::Reference< sdbc::XConnection>& rConnection) :
    SfxModalDialog(pParent, SW_RES(DLG_MM_SELECTDBTABLEDDIALOG)),
    m_aSelectFI( this, SW_RES(       FI_SELECT     )),
    m_aTableHB( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER),
    m_aTableLB( this, SW_RES(        LB_TABLE      )),
    m_aPreviewPB( this, SW_RES(      PB_PREVIEW    )),
    m_aSeparatorFL(this, SW_RES(    FL_SEPARATOR      )),
    m_aOK( this, SW_RES(             PB_OK         )),
    m_aCancel( this, SW_RES(         PB_CANCEL     )),
    m_aHelp( this, SW_RES(           PB_HELP       )),
    m_sName( SW_RES( ST_NAME )),
    m_sType( SW_RES( ST_TYPE )),
    m_sTable( SW_RES( ST_TABLE )),
    m_sQuery( SW_RES( ST_QUERY )),
    m_xConnection(rConnection)
{
    FreeResource();

    Size aLBSize(m_aTableLB.GetSizePixel());
    m_aTableHB.SetSizePixel(aLBSize);
    Size aHeadSize(m_aTableHB.CalcWindowSizePixel());
    aHeadSize.Width() = aLBSize.Width();
    m_aTableHB.SetSizePixel(aHeadSize);
    Point aLBPos(m_aTableLB.GetPosPixel());
    m_aTableHB.SetPosPixel(aLBPos);
    aLBPos.Y() += aHeadSize.Height();
    aLBSize.Height() -= aHeadSize.Height();
    m_aTableLB.SetPosSizePixel(aLBPos, aLBSize);

    Size aSz(m_aTableHB.GetOutputSizePixel());
    m_aTableHB.InsertItem( 1, m_sName,
                            aSz.Width()/2,
                            HIB_LEFT | HIB_VCENTER /*| HIB_CLICKABLE | HIB_UPARROW */);
    m_aTableHB.InsertItem( 2, m_sType,
                            aSz.Width()/2,
                            HIB_LEFT | HIB_VCENTER /*| HIB_CLICKABLE | HIB_UPARROW */);
    m_aTableHB.SetHelpId(HID_MM_ADDRESSLIST_HB );
    m_aTableHB.Show();

    static long nTabs[] = {3, 0, aSz.Width()/2, aSz.Width() };
    m_aTableLB.SetTabs(&nTabs[0], MAP_PIXEL);
    m_aTableLB.SetHelpId(HID_MM_SELECTDBTABLEDDIALOG_LISTBOX);
    m_aTableLB.SetStyle( m_aTableLB.GetStyle() | WB_CLIPCHILDREN );
    m_aTableLB.SetSpaceBetweenEntries(3);
    m_aTableLB.SetSelectionMode( SINGLE_SELECTION );
    m_aTableLB.SetDragDropMode(   0 );
    m_aTableLB.EnableAsyncDrag(sal_False);

    m_aPreviewPB.SetClickHdl(LINK(this, SwSelectDBTableDialog, PreviewHdl));

    Reference<XTablesSupplier> xTSupplier(m_xConnection, UNO_QUERY);
    if(xTSupplier.is())
    {
        Reference<XNameAccess> xTbls = xTSupplier->getTables();
        Sequence<OUString> aTbls = xTbls->getElementNames();
        const OUString* pTbls = aTbls.getConstArray();
        for(long i = 0; i < aTbls.getLength(); i++)
        {
            OUString sEntry = pTbls[i];
            sEntry += "\t";
            sEntry += m_sTable;
            SvTreeListEntry* pEntry = m_aTableLB.InsertEntry(sEntry);
            pEntry->SetUserData((void*)0);
        }
    }
    Reference<XQueriesSupplier> xQSupplier(m_xConnection, UNO_QUERY);
    if(xQSupplier.is())
    {
        Reference<XNameAccess> xQueries = xQSupplier->getQueries();
        Sequence<OUString> aQueries = xQueries->getElementNames();
        const OUString* pQueries = aQueries.getConstArray();
        for(long i = 0; i < aQueries.getLength(); i++)
        {
            OUString sEntry = pQueries[i];
            sEntry += "\t";
            sEntry += m_sQuery;
            SvTreeListEntry* pEntry = m_aTableLB.InsertEntry(sEntry);
            pEntry->SetUserData((void*)1);
        }
    }
}

SwSelectDBTableDialog::~SwSelectDBTableDialog()
{
}

IMPL_LINK(SwSelectDBTableDialog, PreviewHdl, PushButton*, pButton)
{
    SvTreeListEntry* pEntry = m_aTableLB.FirstSelected();
    if(pEntry)
    {
        OUString sTableOrQuery = m_aTableLB.GetEntryText(pEntry, 0);
        sal_Int32 nCommandType = 0 == pEntry->GetUserData() ? 0 : 1;

        OUString sDataSourceName;
        Reference<XChild> xChild(m_xConnection, UNO_QUERY);
        if(xChild.is())
        {
            Reference<XDataSource> xSource(xChild->getParent(), UNO_QUERY);
            Reference<XPropertySet> xPrSet(xSource, UNO_QUERY);
            xPrSet->getPropertyValue("Name") >>= sDataSourceName;
        }
        OSL_ENSURE(!sDataSourceName.isEmpty(), "no data source found");
        Sequence<PropertyValue> aProperties(5);
        PropertyValue* pProperties = aProperties.getArray();
        pProperties[0].Name = "DataSourceName";
        pProperties[0].Value <<= sDataSourceName;
        pProperties[1].Name = "Command";
        pProperties[1].Value <<= sTableOrQuery;
        pProperties[2].Name = "CommandType";
        pProperties[2].Value <<= nCommandType;
        pProperties[3].Name = "ShowTreeView";
        pProperties[3].Value <<= sal_False;
        pProperties[4].Name = "ShowTreeViewButton";
        pProperties[4].Value <<= sal_False;

        SwDBTablePreviewDialog* pDlg = new SwDBTablePreviewDialog(pButton, aProperties);
        pDlg->Execute();
        delete pDlg;
    }

    return 0;
}

OUString    SwSelectDBTableDialog::GetSelectedTable(bool& bIsTable)
{
    SvTreeListEntry* pEntry = m_aTableLB.FirstSelected();
    bIsTable = pEntry->GetUserData() ? false : true;
    return pEntry ? m_aTableLB.GetEntryText(pEntry, 0) : OUString();
}

void   SwSelectDBTableDialog::SetSelectedTable(const OUString& rTable, bool bIsTable)
{
    SvTreeListEntry*    pEntry = m_aTableLB.First();
    while(pEntry)
    {
        if((m_aTableLB.GetEntryText(pEntry, 0) == rTable) &&
                 ((pEntry->GetUserData() == 0 ) == bIsTable))
        {
            m_aTableLB.Select(pEntry);
            break;
        }
        pEntry = m_aTableLB.Next( pEntry );
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>cid#705949 dereference before null check<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <swtypes.hxx>
#include <selectdbtabledialog.hxx>
#include <dbtablepreviewdialog.hxx>
#include "svtools/treelistentry.hxx"
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/sdbc/XDataSource.hpp>

#include <unomid.h>

#include <selectdbtabledialog.hrc>
#include <dbui.hrc>
#include <helpid.h>

using namespace ::com::sun::star;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;

SwSelectDBTableDialog::SwSelectDBTableDialog(Window* pParent,
        const uno::Reference< sdbc::XConnection>& rConnection) :
    SfxModalDialog(pParent, SW_RES(DLG_MM_SELECTDBTABLEDDIALOG)),
    m_aSelectFI( this, SW_RES(       FI_SELECT     )),
    m_aTableHB( this, WB_BUTTONSTYLE | WB_BOTTOMBORDER),
    m_aTableLB( this, SW_RES(        LB_TABLE      )),
    m_aPreviewPB( this, SW_RES(      PB_PREVIEW    )),
    m_aSeparatorFL(this, SW_RES(    FL_SEPARATOR      )),
    m_aOK( this, SW_RES(             PB_OK         )),
    m_aCancel( this, SW_RES(         PB_CANCEL     )),
    m_aHelp( this, SW_RES(           PB_HELP       )),
    m_sName( SW_RES( ST_NAME )),
    m_sType( SW_RES( ST_TYPE )),
    m_sTable( SW_RES( ST_TABLE )),
    m_sQuery( SW_RES( ST_QUERY )),
    m_xConnection(rConnection)
{
    FreeResource();

    Size aLBSize(m_aTableLB.GetSizePixel());
    m_aTableHB.SetSizePixel(aLBSize);
    Size aHeadSize(m_aTableHB.CalcWindowSizePixel());
    aHeadSize.Width() = aLBSize.Width();
    m_aTableHB.SetSizePixel(aHeadSize);
    Point aLBPos(m_aTableLB.GetPosPixel());
    m_aTableHB.SetPosPixel(aLBPos);
    aLBPos.Y() += aHeadSize.Height();
    aLBSize.Height() -= aHeadSize.Height();
    m_aTableLB.SetPosSizePixel(aLBPos, aLBSize);

    Size aSz(m_aTableHB.GetOutputSizePixel());
    m_aTableHB.InsertItem( 1, m_sName,
                            aSz.Width()/2,
                            HIB_LEFT | HIB_VCENTER /*| HIB_CLICKABLE | HIB_UPARROW */);
    m_aTableHB.InsertItem( 2, m_sType,
                            aSz.Width()/2,
                            HIB_LEFT | HIB_VCENTER /*| HIB_CLICKABLE | HIB_UPARROW */);
    m_aTableHB.SetHelpId(HID_MM_ADDRESSLIST_HB );
    m_aTableHB.Show();

    static long nTabs[] = {3, 0, aSz.Width()/2, aSz.Width() };
    m_aTableLB.SetTabs(&nTabs[0], MAP_PIXEL);
    m_aTableLB.SetHelpId(HID_MM_SELECTDBTABLEDDIALOG_LISTBOX);
    m_aTableLB.SetStyle( m_aTableLB.GetStyle() | WB_CLIPCHILDREN );
    m_aTableLB.SetSpaceBetweenEntries(3);
    m_aTableLB.SetSelectionMode( SINGLE_SELECTION );
    m_aTableLB.SetDragDropMode(   0 );
    m_aTableLB.EnableAsyncDrag(sal_False);

    m_aPreviewPB.SetClickHdl(LINK(this, SwSelectDBTableDialog, PreviewHdl));

    Reference<XTablesSupplier> xTSupplier(m_xConnection, UNO_QUERY);
    if(xTSupplier.is())
    {
        Reference<XNameAccess> xTbls = xTSupplier->getTables();
        Sequence<OUString> aTbls = xTbls->getElementNames();
        const OUString* pTbls = aTbls.getConstArray();
        for(long i = 0; i < aTbls.getLength(); i++)
        {
            OUString sEntry = pTbls[i];
            sEntry += "\t";
            sEntry += m_sTable;
            SvTreeListEntry* pEntry = m_aTableLB.InsertEntry(sEntry);
            pEntry->SetUserData((void*)0);
        }
    }
    Reference<XQueriesSupplier> xQSupplier(m_xConnection, UNO_QUERY);
    if(xQSupplier.is())
    {
        Reference<XNameAccess> xQueries = xQSupplier->getQueries();
        Sequence<OUString> aQueries = xQueries->getElementNames();
        const OUString* pQueries = aQueries.getConstArray();
        for(long i = 0; i < aQueries.getLength(); i++)
        {
            OUString sEntry = pQueries[i];
            sEntry += "\t";
            sEntry += m_sQuery;
            SvTreeListEntry* pEntry = m_aTableLB.InsertEntry(sEntry);
            pEntry->SetUserData((void*)1);
        }
    }
}

SwSelectDBTableDialog::~SwSelectDBTableDialog()
{
}

IMPL_LINK(SwSelectDBTableDialog, PreviewHdl, PushButton*, pButton)
{
    SvTreeListEntry* pEntry = m_aTableLB.FirstSelected();
    if(pEntry)
    {
        OUString sTableOrQuery = m_aTableLB.GetEntryText(pEntry, 0);
        sal_Int32 nCommandType = 0 == pEntry->GetUserData() ? 0 : 1;

        OUString sDataSourceName;
        Reference<XChild> xChild(m_xConnection, UNO_QUERY);
        if(xChild.is())
        {
            Reference<XDataSource> xSource(xChild->getParent(), UNO_QUERY);
            Reference<XPropertySet> xPrSet(xSource, UNO_QUERY);
            xPrSet->getPropertyValue("Name") >>= sDataSourceName;
        }
        OSL_ENSURE(!sDataSourceName.isEmpty(), "no data source found");
        Sequence<PropertyValue> aProperties(5);
        PropertyValue* pProperties = aProperties.getArray();
        pProperties[0].Name = "DataSourceName";
        pProperties[0].Value <<= sDataSourceName;
        pProperties[1].Name = "Command";
        pProperties[1].Value <<= sTableOrQuery;
        pProperties[2].Name = "CommandType";
        pProperties[2].Value <<= nCommandType;
        pProperties[3].Name = "ShowTreeView";
        pProperties[3].Value <<= sal_False;
        pProperties[4].Name = "ShowTreeViewButton";
        pProperties[4].Value <<= sal_False;

        SwDBTablePreviewDialog* pDlg = new SwDBTablePreviewDialog(pButton, aProperties);
        pDlg->Execute();
        delete pDlg;
    }

    return 0;
}

OUString    SwSelectDBTableDialog::GetSelectedTable(bool& bIsTable)
{
    SvTreeListEntry* pEntry = m_aTableLB.FirstSelected();
    bIsTable = pEntry->GetUserData() ? false : true;
    return m_aTableLB.GetEntryText(pEntry, 0);
}

void   SwSelectDBTableDialog::SetSelectedTable(const OUString& rTable, bool bIsTable)
{
    SvTreeListEntry*    pEntry = m_aTableLB.First();
    while(pEntry)
    {
        if((m_aTableLB.GetEntryText(pEntry, 0) == rTable) &&
                 ((pEntry->GetUserData() == 0 ) == bIsTable))
        {
            m_aTableLB.Select(pEntry);
            break;
        }
        pEntry = m_aTableLB.Next( pEntry );
    }
}

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


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

#include "app.hxx"
#include "wrapper.hxx"

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#include <offmgr/app.hxx>
#include <comphelper/processfactory.hxx>
#ifndef _UTL_CONFIGMGR_HXX_
#include <unotools/configmgr.hxx>
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif

#include <setup2/installer.hxx>
#include <svtools/pathoptions.hxx>
#include "svtools/cjkoptions.hxx"
#include <unotools/configmgr.hxx>
#include <vcl/msgbox.hxx>

#ifndef _COM_SUN_STAR_UNO_EXCEPTION_HPP_
#include <com/sun/star/uno/Exception.hpp>
#endif

#define DEFINE_CONST_UNICODE(CONSTASCII)        UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII##))

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;

void PreloadConfigTrees()
{
    // these tree are preloaded to get a faster startup for the office
    Sequence <rtl::OUString> aPreloadPathList(6);
    aPreloadPathList[0] =  rtl::OUString::createFromAscii("org.openoffice.Office.Common");
    aPreloadPathList[1] =  rtl::OUString::createFromAscii("org.openoffice.ucb.Configuration");
    aPreloadPathList[2] =  rtl::OUString::createFromAscii("org.openoffice.Office.Writer");
    aPreloadPathList[3] =  rtl::OUString::createFromAscii("org.openoffice.Office.WriterWeb");
    aPreloadPathList[4] =  rtl::OUString::createFromAscii("org.openoffice.Office.Calc");
    aPreloadPathList[5] =  rtl::OUString::createFromAscii("org.openoffice.Office.Impress");

    Reference< XMultiServiceFactory > xProvider(
            ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), UNO_QUERY);

    Any aValue;
    aValue <<= aPreloadPathList;

    Reference < com::sun::star::beans::XPropertySet > (xProvider, UNO_QUERY)->setPropertyValue(rtl::OUString::createFromAscii("PrefetchNodes"), aValue );
}

void ReplaceStringHookProc( UniString& rStr )
{
    static String aBrandName;
    static String aVersion;
    static String aExtension;

    static int nAll = 0, nPro = 0;

    if ( !aBrandName.Len() )
    {
        Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
        rtl::OUString aTmp;
        aRet >>= aTmp;
        aBrandName = aTmp;

        aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
        aRet >>= aTmp;
        aVersion = aTmp;

        aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
        aRet >>= aTmp;
        aExtension = aTmp;
    }

    nAll++;
    if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
    {
        nPro++;
        rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", aBrandName );
        rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", aVersion );
        rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", aExtension );
    }
}

Desktop aDesktop;

Desktop::Desktop()
{
}

void Desktop::Main()
{
    ResMgr::SetReadStringHook( ReplaceStringHookProc );
    SetAppName( DEFINE_CONST_UNICODE("soffice") );

#ifdef TIMEBOMB
    Date aDate;
    Date aFinalDate( 31, 8, 2001 );
    if ( aFinalDate < aDate )
    {
        String aMsg;
        aMsg += DEFINE_CONST_UNICODE("This Early Access Version has expired!\n");
        InfoBox aBox( NULL, aMsg );
        aBox.Execute();
        return;
    }
#endif

    bool bTerminate = false;
    int nParamCount = GetCommandLineParamCount();

    for( int nActParam = 0; nActParam < nParamCount ; nActParam++ )
    {
        String sActParam = GetCommandLineParam( nActParam );
        if( sActParam.EqualsIgnoreCaseAscii("-terminate_after_init") )
        {
            bTerminate = true;
            break;
        }
    }

//  Read the common configuration items for optimization purpose
//  do not do it if terminate flag was specified, to avoid exception
    if( !bTerminate )
    {
        try
        {
            PreloadConfigTrees();
        }
        catch(com::sun::star::uno::Exception &e)
        {
            bTerminate = true;
            rtl::OUString sError = rtl::OUString::createFromAscii("Unable to retrieve application configuration data: ");
            sError += e.Message;
            Application::Abort(sError);
        }
    }

//  The only step that should be done if terminate flag was specified
//  Typically called by the plugin only
    Installer* pInstaller = new Installer;
    pInstaller->InitializeInstallation( Application::GetAppFileName() );
    delete pInstaller;

    if( !bTerminate )
    {
        SvtPathOptions* pPathOptions = new SvtPathOptions;
        SvtCJKOptions* pCJKOPptions = new SvtCJKOptions(sal_True);
        RegisterServices();
        OfficeWrapper* pWrapper = new OfficeWrapper( ::comphelper::getProcessServiceFactory() );
//      Reference < XComponent > xWrapper( ::utl::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.office.OfficeWrapper" ) ), UNO_QUERY );
        SfxApplicationClass::Main();
//      xWrapper->dispose();

        if( pWrapper!=NULL)
        {
            delete pWrapper;
            pWrapper=NULL;
        }

        delete pCJKOPptions;
        delete pPathOptions;
    }

    // instead of removing of the configManager jast let it commit all the changes
    utl::ConfigManager::GetConfigManager()->StoreConfigItems();

    //utl::ConfigManager::RemoveConfigManager();
}

void Desktop::SystemSettingsChanging( AllSettings& rSettings, Window* pFrame )
{
    OFF_APP()->SystemSettingsChanging( rSettings, pFrame );
}

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

#include "app.hxx"
#include "wrapper.hxx"

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif

#include <offmgr/app.hxx>
#include <comphelper/processfactory.hxx>
#ifndef _UTL_CONFIGMGR_HXX_
#include <unotools/configmgr.hxx>
#endif
#ifndef _UTL_CONFIGITEM_HXX_
#include <unotools/configitem.hxx>
#endif

#include <setup2/installer.hxx>
#include <svtools/pathoptions.hxx>
#include "svtools/cjkoptions.hxx"
#include <unotools/configmgr.hxx>
#include <vcl/msgbox.hxx>

#ifndef _COM_SUN_STAR_UNO_EXCEPTION_HPP_
#include <com/sun/star/uno/Exception.hpp>
#endif

#define DEFINE_CONST_UNICODE(CONSTASCII)        UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII##))

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;

void PreloadConfigTrees()
{
    // these tree are preloaded to get a faster startup for the office
    Sequence <rtl::OUString> aPreloadPathList(6);
    aPreloadPathList[0] =  rtl::OUString::createFromAscii("org.openoffice.Office.Common");
    aPreloadPathList[1] =  rtl::OUString::createFromAscii("org.openoffice.ucb.Configuration");
    aPreloadPathList[2] =  rtl::OUString::createFromAscii("org.openoffice.Office.Writer");
    aPreloadPathList[3] =  rtl::OUString::createFromAscii("org.openoffice.Office.WriterWeb");
    aPreloadPathList[4] =  rtl::OUString::createFromAscii("org.openoffice.Office.Calc");
    aPreloadPathList[5] =  rtl::OUString::createFromAscii("org.openoffice.Office.Impress");

    Reference< XMultiServiceFactory > xProvider(
            ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), UNO_QUERY);

    Any aValue;
    aValue <<= aPreloadPathList;

    Reference < com::sun::star::beans::XPropertySet > (xProvider, UNO_QUERY)->setPropertyValue(rtl::OUString::createFromAscii("PrefetchNodes"), aValue );
}

void ReplaceStringHookProc( UniString& rStr )
{
    static String aBrandName;
    static String aVersion;
    static String aExtension;

    static int nAll = 0, nPro = 0;

    if ( !aBrandName.Len() )
    {
        Any aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME );
        rtl::OUString aTmp;
        aRet >>= aTmp;
        aBrandName = aTmp;

        aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTVERSION );
        aRet >>= aTmp;
        aVersion = aTmp;

        aRet = ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTEXTENSION );
        aRet >>= aTmp;
        aExtension = aTmp;
    }

    nAll++;
    if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND )
    {
        nPro++;
        rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", aBrandName );
        rStr.SearchAndReplaceAllAscii( "%PRODUCTVERSION", aVersion );
        rStr.SearchAndReplaceAllAscii( "%PRODUCTEXTENSION", aExtension );
    }
}

Desktop aDesktop;

Desktop::Desktop()
{
}

void Desktop::Main()
{
    ResMgr::SetReadStringHook( ReplaceStringHookProc );
    SetAppName( DEFINE_CONST_UNICODE("soffice") );

#ifdef TIMEBOMB
    Date aDate;
    Date aFinalDate( 31, 10, 2001 );
    if ( aFinalDate < aDate )
    {
        String aMsg;
        aMsg += DEFINE_CONST_UNICODE("This Early Access Version has expired!\n");
        InfoBox aBox( NULL, aMsg );
        aBox.Execute();
        return;
    }
#endif

    bool bTerminate = false;
    int nParamCount = GetCommandLineParamCount();

    for( int nActParam = 0; nActParam < nParamCount ; nActParam++ )
    {
        String sActParam = GetCommandLineParam( nActParam );
        if( sActParam.EqualsIgnoreCaseAscii("-terminate_after_init") )
        {
            bTerminate = true;
            break;
        }
    }

//  Read the common configuration items for optimization purpose
//  do not do it if terminate flag was specified, to avoid exception
    if( !bTerminate )
    {
        try
        {
            PreloadConfigTrees();
        }
        catch(com::sun::star::uno::Exception &e)
        {
            bTerminate = true;
            rtl::OUString sError = rtl::OUString::createFromAscii("Unable to retrieve application configuration data: ");
            sError += e.Message;
            Application::Abort(sError);
        }
    }

//  The only step that should be done if terminate flag was specified
//  Typically called by the plugin only
    Installer* pInstaller = new Installer;
    pInstaller->InitializeInstallation( Application::GetAppFileName() );
    delete pInstaller;

    if( !bTerminate )
    {
        SvtPathOptions* pPathOptions = new SvtPathOptions;
        SvtCJKOptions* pCJKOPptions = new SvtCJKOptions(sal_True);
        RegisterServices();
        OfficeWrapper* pWrapper = new OfficeWrapper( ::comphelper::getProcessServiceFactory() );
//      Reference < XComponent > xWrapper( ::utl::getProcessServiceFactory()->createInstance( DEFINE_CONST_UNICODE("com.sun.star.office.OfficeWrapper" ) ), UNO_QUERY );
        SfxApplicationClass::Main();
//      xWrapper->dispose();

        if( pWrapper!=NULL)
        {
            delete pWrapper;
            pWrapper=NULL;
        }

        delete pCJKOPptions;
        delete pPathOptions;
    }

    // instead of removing of the configManager jast let it commit all the changes
    utl::ConfigManager::GetConfigManager()->StoreConfigItems();

    //utl::ConfigManager::RemoveConfigManager();
}

void Desktop::SystemSettingsChanging( AllSettings& rSettings, Window* pFrame )
{
    OFF_APP()->SystemSettingsChanging( rSettings, pFrame );
}

<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2011, Howard Butler, hobu.inc@gmail.com
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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 <pdal/drivers/text/Writer.hpp>
#include <pdal/PointBuffer.hpp>

#include <iostream>
#include <algorithm>

#include <boost/algorithm/string.hpp>

#ifdef USE_PDAL_PLUGIN_TEXT
PDAL_C_START

PDAL_DLL void PDALRegister_writer_text(void* factory)
{
    pdal::StageFactory& f = *(pdal::StageFactory*) factory;
    f.registerWriter(pdal::drivers::text::Writer::s_getName(), createTextWriter);
}

PDAL_C_END

pdal::Writer* createTextWriter(pdal::Stage& prevStage, const pdal::Options& options)
{
    return new pdal::drivers::text::Writer(prevStage, options);
}
#endif

namespace pdal
{
namespace drivers
{
namespace text
{

struct FileStreamDeleter
{

    template <typename T>
    void operator()(T* ptr)
    {
        ptr->flush();
        FileUtils::closeFile(ptr);
    }
};

Writer::Writer(Stage& prevStage, const Options& options)
    : pdal::Writer(prevStage, options)
    , m_wrote_header(false)

{

    return;
}

Writer::~Writer()
{
    return;
}

void Writer::initialize()
{
    pdal::Writer::initialize();

    std::string filename = getOptions().getValueOrThrow<std::string>("filename");

    // This is so the stream gets closed down if we throw any sort of
    // exception
    m_stream = FileStreamPtr(FileUtils::createFile(filename, true), FileStreamDeleter());

    return;
}

const Options Writer::getDefaultOptions() const
{
    Options options;

    Option delimiter("delimiter", ",", "Delimiter to use for writing text");
    Option newline("newline", "\n", "Newline character to use for additional lines");
    Option quote_header("quote_header", true, "Write dimension names in quotes");
    Option filename("filename", "", "Filename to write CSV file to");

    options.add(filename);
    options.add(delimiter);
    options.add(newline);
    options.add(quote_header);

    return options;
}

void Writer::writeBegin(boost::uint64_t /*targetNumPointsToWrite*/)
{
    return;
}

void Writer::writeEnd(boost::uint64_t /*actualNumPointsWritten*/)
{
    m_stream.reset();
    m_stream = FileStreamPtr();
    m_wrote_header = false;
    return;
}

void Writer::WriteHeader(pdal::Schema const& schema)
{

    schema::index_by_index const& dims = schema.getDimensions().get<schema::index>();

    bool isQuoted = getOptions().getValueOrDefault<bool>("quote_header", true);
    bool bWriteHeader = getOptions().getValueOrDefault<bool>("write_header", true);
    std::string newline = getOptions().getValueOrDefault<std::string>("newline", "\n");
    std::string delimiter = getOptions().getValueOrDefault<std::string>("delimiter",",");

    if (!bWriteHeader)
        return;

    if (delimiter.size() == 0)
        delimiter = " ";

    schema::index_by_index::const_iterator iter = dims.begin();
    while (iter != dims.end())
    {
        if (iter->isIgnored())
        {
            iter++;
            continue;
        }
        if (isQuoted)
            *m_stream << "\"";
        *m_stream << iter->getName();
        if (isQuoted)
            *m_stream<< "\"";
        iter++;
        if (iter != dims.end())
            *m_stream << delimiter;
    }
    *m_stream << newline;

    return;
}

std::string Writer::getStringRepresentation(PointBuffer const& data,
        Dimension const& d,
        std::size_t pointIndex) const
{
    std::ostringstream output;

    float flt(0.0);
    boost::int8_t i8(0);
    boost::uint8_t u8(0);
    boost::int16_t i16(0);
    boost::uint16_t u16(0);
    boost::int32_t i32(0);
    boost::uint32_t u32(0);
    boost::int64_t i64(0);
    boost::uint64_t u64(0);

    boost::uint32_t size = d.getByteSize();

    bool bHaveScaling = !Utils::compare_distance(d.getNumericScale(), 0.0);

    // FIXME: Allow selective scaling of requested dimensions
    if (bHaveScaling)
    {
        output.setf(std::ios::fixed, std::ios::floatfield);
        output.precision(Utils::getStreamPrecision(d.getNumericScale()));
    }
    switch (d.getInterpretation())
    {
        case dimension::Float:
            if (size == 4)
            {
                flt = data.getField<float>(d, pointIndex);
                output << static_cast<double>(flt);
            }
            if (size == 8)
            {
                output << data.getField<double>(d, pointIndex);
            }
            break;

        case dimension::SignedInteger:
        case dimension::SignedByte:
            if (size == 1)
            {
                i8 = data.getField<boost::int8_t>(d, pointIndex);
                output << d.applyScaling<boost::int8_t>(i8);
            }
            if (size == 2)
            {
                i16 = data.getField<boost::int16_t>(d, pointIndex);
                output << d.applyScaling<boost::int16_t>(i16);
            }
            if (size == 4)
            {
                i32 = data.getField<boost::int32_t>(d, pointIndex);
                output << d.applyScaling<boost::int32_t>(i32);
            }
            if (size == 8)
            {
                i64 = data.getField<boost::int64_t>(d, pointIndex);
                output << d.applyScaling<boost::int64_t>(i64);
            }
            break;

        case dimension::UnsignedInteger:
        case dimension::UnsignedByte:
            if (size == 1)
            {
                u8 = data.getField<boost::uint8_t>(d, pointIndex);
                output << d.applyScaling<boost::uint8_t>(u8);
            }
            if (size == 2)
            {
                u16 = data.getField<boost::uint16_t>(d, pointIndex);
                output << d.applyScaling<boost::uint16_t>(u16);
            }
            if (size == 4)
            {
                u32 = data.getField<boost::uint32_t>(d, pointIndex);
                output << d.applyScaling<boost::uint32_t>(u32);
            }
            if (size == 8)
            {
                u64 = data.getField<boost::uint64_t>(d, pointIndex);
                output << d.applyScaling<boost::uint64_t>(u64);
            }
            break;

        case dimension::Pointer:    // stored as 64 bits, even on a 32-bit box
        case dimension::Undefined:
            break;
    }

    return output.str();
}

boost::uint32_t Writer::writeBuffer(const PointBuffer& data)
{

    if (!m_wrote_header)
    {
        WriteHeader(data.getSchema());
        m_wrote_header = true;
    }

    std::string newline = getOptions().getValueOrDefault<std::string>("newline", "\n");
    std::string delimiter = getOptions().getValueOrDefault<std::string>("delimiter",",");
    if (delimiter.size() == 0)
        delimiter = " ";

    boost::uint32_t pointIndex(0);

    pdal::Schema const& schema = data.getSchema();
    schema::index_by_index const& dims = schema.getDimensions().get<schema::index>();

    while (pointIndex != data.getNumPoints())
    {

        schema::index_by_index::const_iterator iter = dims.begin();
        while (iter != dims.end())
        {
            if (iter->isIgnored())
            {
                iter++;
                continue;
            }

            *m_stream << getStringRepresentation(data, *iter, pointIndex);

            iter++;
            if (iter != dims.end())
                *m_stream << delimiter;
        }
        *m_stream << newline;

        pointIndex++;

    }

    return data.getNumPoints();
}

boost::property_tree::ptree Writer::toPTree() const
{
    boost::property_tree::ptree tree = pdal::Writer::toPTree();

    // add stuff here specific to this stage type

    return tree;
}

}
}
} // namespaces
<commit_msg>more log noise, denote that we've written the log in the case where we don't care to write it<commit_after>/******************************************************************************
* Copyright (c) 2011, Howard Butler, hobu.inc@gmail.com
*
* 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 Hobu, Inc. or Flaxen Geo Consulting 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 <pdal/drivers/text/Writer.hpp>
#include <pdal/PointBuffer.hpp>

#include <iostream>
#include <algorithm>

#include <boost/algorithm/string.hpp>

#ifdef USE_PDAL_PLUGIN_TEXT
PDAL_C_START

PDAL_DLL void PDALRegister_writer_text(void* factory)
{
    pdal::StageFactory& f = *(pdal::StageFactory*) factory;
    f.registerWriter(pdal::drivers::text::Writer::s_getName(), createTextWriter);
}

PDAL_C_END

pdal::Writer* createTextWriter(pdal::Stage& prevStage, const pdal::Options& options)
{
    return new pdal::drivers::text::Writer(prevStage, options);
}
#endif

namespace pdal
{
namespace drivers
{
namespace text
{

struct FileStreamDeleter
{

    template <typename T>
    void operator()(T* ptr)
    {
        ptr->flush();
        FileUtils::closeFile(ptr);
    }
};

Writer::Writer(Stage& prevStage, const Options& options)
    : pdal::Writer(prevStage, options)
    , m_wrote_header(false)

{

    return;
}

Writer::~Writer()
{
    return;
}

void Writer::initialize()
{
    pdal::Writer::initialize();

    std::string filename = getOptions().getValueOrThrow<std::string>("filename");

    // This is so the stream gets closed down if we throw any sort of
    // exception
    m_stream = FileStreamPtr(FileUtils::createFile(filename, true), FileStreamDeleter());

    return;
}

const Options Writer::getDefaultOptions() const
{
    Options options;

    Option delimiter("delimiter", ",", "Delimiter to use for writing text");
    Option newline("newline", "\n", "Newline character to use for additional lines");
    Option quote_header("quote_header", true, "Write dimension names in quotes");
    Option filename("filename", "", "Filename to write CSV file to");

    options.add(filename);
    options.add(delimiter);
    options.add(newline);
    options.add(quote_header);

    return options;
}

void Writer::writeBegin(boost::uint64_t /*targetNumPointsToWrite*/)
{
    return;
}

void Writer::writeEnd(boost::uint64_t /*actualNumPointsWritten*/)
{
    m_stream.reset();
    m_stream = FileStreamPtr();
    m_wrote_header = false;
    return;
}

void Writer::WriteHeader(pdal::Schema const& schema)
{

    schema::index_by_index const& dims = schema.getDimensions().get<schema::index>();

    bool isQuoted = getOptions().getValueOrDefault<bool>("quote_header", true);
    bool bWriteHeader = getOptions().getValueOrDefault<bool>("write_header", true);
    std::string newline = getOptions().getValueOrDefault<std::string>("newline", "\n");
    std::string delimiter = getOptions().getValueOrDefault<std::string>("delimiter",",");

    log()->get(logDEBUG) << "Writing to filename: " << getOptions().getValueOrThrow<std::string>("filename") << std::endl;

    if (!bWriteHeader)
    {
        log()->get(logDEBUG) << "Not writing header" << std::endl;
        m_wrote_header = true;
        return;

    }
    log()->get(logDEBUG) << "Writing header" << std::endl;

    if (delimiter.size() == 0)
        delimiter = " ";

    schema::index_by_index::const_iterator iter = dims.begin();
    while (iter != dims.end())
    {
        if (iter->isIgnored())
        {
            iter++;
            continue;
        }
        if (isQuoted)
            *m_stream << "\"";
        *m_stream << iter->getName();
        if (isQuoted)
            *m_stream<< "\"";
        iter++;
        if (iter != dims.end())
            *m_stream << delimiter;
    }
    *m_stream << newline;

    return;
}

std::string Writer::getStringRepresentation(PointBuffer const& data,
        Dimension const& d,
        std::size_t pointIndex) const
{
    std::ostringstream output;

    float flt(0.0);
    boost::int8_t i8(0);
    boost::uint8_t u8(0);
    boost::int16_t i16(0);
    boost::uint16_t u16(0);
    boost::int32_t i32(0);
    boost::uint32_t u32(0);
    boost::int64_t i64(0);
    boost::uint64_t u64(0);

    boost::uint32_t size = d.getByteSize();

    bool bHaveScaling = !Utils::compare_distance(d.getNumericScale(), 0.0);

    // FIXME: Allow selective scaling of requested dimensions
    if (bHaveScaling)
    {
        output.setf(std::ios::fixed, std::ios::floatfield);
        output.precision(Utils::getStreamPrecision(d.getNumericScale()));
    }
    switch (d.getInterpretation())
    {
        case dimension::Float:
            if (size == 4)
            {
                flt = data.getField<float>(d, pointIndex);
                output << static_cast<double>(flt);
            }
            if (size == 8)
            {
                output << data.getField<double>(d, pointIndex);
            }
            break;

        case dimension::SignedInteger:
        case dimension::SignedByte:
            if (size == 1)
            {
                i8 = data.getField<boost::int8_t>(d, pointIndex);
                output << d.applyScaling<boost::int8_t>(i8);
            }
            if (size == 2)
            {
                i16 = data.getField<boost::int16_t>(d, pointIndex);
                output << d.applyScaling<boost::int16_t>(i16);
            }
            if (size == 4)
            {
                i32 = data.getField<boost::int32_t>(d, pointIndex);
                output << d.applyScaling<boost::int32_t>(i32);
            }
            if (size == 8)
            {
                i64 = data.getField<boost::int64_t>(d, pointIndex);
                output << d.applyScaling<boost::int64_t>(i64);
            }
            break;

        case dimension::UnsignedInteger:
        case dimension::UnsignedByte:
            if (size == 1)
            {
                u8 = data.getField<boost::uint8_t>(d, pointIndex);
                output << d.applyScaling<boost::uint8_t>(u8);
            }
            if (size == 2)
            {
                u16 = data.getField<boost::uint16_t>(d, pointIndex);
                output << d.applyScaling<boost::uint16_t>(u16);
            }
            if (size == 4)
            {
                u32 = data.getField<boost::uint32_t>(d, pointIndex);
                output << d.applyScaling<boost::uint32_t>(u32);
            }
            if (size == 8)
            {
                u64 = data.getField<boost::uint64_t>(d, pointIndex);
                output << d.applyScaling<boost::uint64_t>(u64);
            }
            break;

        case dimension::Pointer:    // stored as 64 bits, even on a 32-bit box
        case dimension::Undefined:
            break;
    }

    return output.str();
}

boost::uint32_t Writer::writeBuffer(const PointBuffer& data)
{

    if (!m_wrote_header)
    {
        WriteHeader(data.getSchema());
        m_wrote_header = true;
    }

    std::string newline = getOptions().getValueOrDefault<std::string>("newline", "\n");
    std::string delimiter = getOptions().getValueOrDefault<std::string>("delimiter",",");
    if (delimiter.size() == 0)
        delimiter = " ";

    boost::uint32_t pointIndex(0);

    pdal::Schema const& schema = data.getSchema();
    schema::index_by_index const& dims = schema.getDimensions().get<schema::index>();

    while (pointIndex != data.getNumPoints())
    {

        schema::index_by_index::const_iterator iter = dims.begin();
        while (iter != dims.end())
        {
            if (iter->isIgnored())
            {
                iter++;
                continue;
            }

            *m_stream << getStringRepresentation(data, *iter, pointIndex);

            iter++;
            if (iter != dims.end())
                *m_stream << delimiter;
        }
        *m_stream << newline;

        pointIndex++;

    }

    return data.getNumPoints();
}

boost::property_tree::ptree Writer::toPTree() const
{
    boost::property_tree::ptree tree = pdal::Writer::toPTree();

    // add stuff here specific to this stage type

    return tree;
}

}
}
} // namespaces
<|endoftext|>