text:
using storage::DatabaseUtil;
using blink::WebIDBKey;

namespace content {

IndexedDBDispatcherHost::IndexedDBDispatcherHost(
    int ipc_process_id,
    net::URLRequestContextGetter* request_context_getter,
    IndexedDBContextImpl* indexed_db_context,
    ChromeBlobStorageContext* blob_storage_context)
    : BrowserMessageFilter(IndexedDBMsgStart),
      request_context_getter_(request_context_getter),
      request_context_(NULL),
      indexed_db_context_(indexed_db_context),
      blob_storage_context_(blob_storage_context),
      database_dispatcher_host_(new DatabaseDispatcherHost(this)),
      cursor_dispatcher_host_(new CursorDispatcherHost(this)),
      ipc_process_id_(ipc_process_id) {
  DCHECK(indexed_db_context_.get());
}

IndexedDBDispatcherHost::IndexedDBDispatcherHost(
    int ipc_process_id,
    net::URLRequestContext* request_context,
    IndexedDBContextImpl* indexed_db_context,
    ChromeBlobStorageContext* blob_storage_context)
    : BrowserMessageFilter(IndexedDBMsgStart),
      request_context_(request_context),
      indexed_db_context_(indexed_db_context),
      blob_storage_context_(blob_storage_context),
      database_dispatcher_host_(new DatabaseDispatcherHost(this)),
      cursor_dispatcher_host_(new CursorDispatcherHost(this)),
      ipc_process_id_(ipc_process_id) {
  DCHECK(indexed_db_context_.get());
}

IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {
  for (auto& iter : blob_data_handle_map_)
    delete iter.second.first;
}

void IndexedDBDispatcherHost::OnChannelConnected(int32_t peer_pid) {
  BrowserMessageFilter::OnChannelConnected(peer_pid);

  if (request_context_getter_.get()) {
    DCHECK(!request_context_);
    request_context_ = request_context_getter_->GetURLRequestContext();
    request_context_getter_ = NULL;
    DCHECK(request_context_);
  }
}

void IndexedDBDispatcherHost::OnChannelClosing() {
  bool success = indexed_db_context_->TaskRunner()->PostTask(
      FROM_HERE,
      base::Bind(&IndexedDBDispatcherHost::ResetDispatcherHosts, this));

  if (!success)
    ResetDispatcherHosts();
}

void IndexedDBDispatcherHost::OnDestruct() const {
  // The last reference to the dispatcher may be a posted task, which would
  // be destructed on the IndexedDB thread. Without this override, that would
  // take the dispatcher with it. Since the dispatcher may be keeping the
  // IndexedDBContext alive, it might be destructed to on its own thread,
  // which is not supported. Ensure destruction runs on the IO thread instead.
  BrowserThread::DeleteOnIOThread::Destruct(this);
}

void IndexedDBDispatcherHost::ResetDispatcherHosts() {
  // It is important that the various *_dispatcher_host_ members are reset
  // on the IndexedDB thread, since there might be incoming messages on that
  // thread, and we must not reset the dispatcher hosts until after those
  // messages are processed.
  DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());

  // Note that we explicitly separate CloseAll() from destruction of the
  // DatabaseDispatcherHost, since CloseAll() can invoke callbacks which need to
  // be dispatched through database_dispatcher_host_.
  database_dispatcher_host_->CloseAll();
  database_dispatcher_host_.reset();
  cursor_dispatcher_host_.reset();
}

base::TaskRunner* IndexedDBDispatcherHost::OverrideTaskRunnerForMessage(
    const IPC::Message& message) {
  if (IPC_MESSAGE_CLASS(message) != IndexedDBMsgStart)
    return NULL;

  switch (message.type()) {
    case IndexedDBHostMsg_DatabasePut::ID:
    case IndexedDBHostMsg_AckReceivedBlobs::ID:
      return NULL;
    default:
      return indexed_db_context_->TaskRunner();
  }
}

bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message) {
  if (IPC_MESSAGE_CLASS(message) != IndexedDBMsgStart)
    return false;

  DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread() ||
         (message.type() == IndexedDBHostMsg_DatabasePut::ID ||
          message.type() == IndexedDBHostMsg_AckReceivedBlobs::ID));

  bool handled = database_dispatcher_host_->OnMessageReceived(message) ||
                 cursor_dispatcher_host_->OnMessageReceived(message);

  if (!handled) {
    handled = true;
    IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcherHost, message)
      IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryGetDatabaseNames,
                          OnIDBFactoryGetDatabaseNames)
      IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryOpen, OnIDBFactoryOpen)
      IPC_MESSAGE_HANDLER(IndexedDBHostMsg_FactoryDeleteDatabase,
                          OnIDBFactoryDeleteDatabase)
      IPC_MESSAGE_HANDLER(IndexedDBHostMsg_AckReceivedBlobs, OnAckReceivedBlobs)
      IPC_MESSAGE_UNHANDLED(handled = false)
    IPC_END_MESSAGE_MAP()
  }
  return handled;
}

int32_t IndexedDBDispatcherHost::Add(IndexedDBCursor* cursor) {
  if (!cursor_dispatcher_host_) {
    return 0;
  }
  return cursor_dispatcher_host_->map_.Add(cursor);
}

int32_t IndexedDBDispatcherHost::Add(IndexedDBConnection* connection,
                                     int32_t ipc_thread_id,
                                     const GURL& origin_url) {
  if (!database_dispatcher_host_) {
    connection->Close();
    delete connection;
    return -1;
  }
  int32_t ipc_database_id = database_dispatcher_host_->map_.Add(connection);
  Context()->ConnectionOpened(origin_url, connection);
  database_dispatcher_host_->database_url_map_[ipc_database_id] = origin_url;
  return ipc_database_id;
}

void IndexedDBDispatcherHost::RegisterTransactionId(int64_t host_transaction_id,
                                                    const GURL& url) {
  if (!database_dispatcher_host_)
    return;
  database_dispatcher_host_->transaction_url_map_[host_transaction_id] = url;
}

int64_t IndexedDBDispatcherHost::HostTransactionId(int64_t transaction_id) {
  // Inject the renderer process id into the transaction id, to
  // uniquely identify this transaction, and effectively bind it to
  // the renderer that initiated it. The lower 32 bits of
  // transaction_id are guaranteed to be unique within that renderer.
  base::ProcessId pid = peer_pid();
  DCHECK(!(transaction_id >> 32)) << "Transaction ids can only be 32 bits";
  static_assert(sizeof(base::ProcessId) <= sizeof(int32_t),
                "Process ID must fit in 32 bits");

  return transaction_id | (static_cast<uint64_t>(pid) << 32);
}

int64_t IndexedDBDispatcherHost::RendererTransactionId(
    int64_t host_transaction_id) {
  DCHECK(host_transaction_id >> 32 == peer_pid())
      << "Invalid renderer target for transaction id";
  return host_transaction_id & 0xffffffff;
}

// static
uint32_t IndexedDBDispatcherHost::TransactionIdToRendererTransactionId(
    int64_t host_transaction_id) {
  return host_transaction_id & 0xffffffff;
}

// static
uint32_t IndexedDBDispatcherHost::TransactionIdToProcessId(
    int64_t host_transaction_id) {
  return (host_transaction_id >> 32) & 0xffffffff;
}

std::string IndexedDBDispatcherHost::HoldBlobData(
    const IndexedDBBlobInfo& blob_info) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  std::string uuid = blob_info.uuid();
  storage::BlobStorageContext* context = blob_storage_context_->context();
  scoped_ptr<storage::BlobDataHandle> blob_data_handle;
  if (uuid.empty()) {
    uuid = base::GenerateGUID();
    storage::BlobDataBuilder blob_data_builder(uuid);
    blob_data_builder.set_content_type(base::UTF16ToUTF8(blob_info.type()));
    blob_data_builder.AppendFile(blob_info.file_path(), 0, blob_info.size(),
                                 blob_info.last_modified());
    blob_data_handle = context->AddFinishedBlob(&blob_data_builder);
  } else {
    auto iter = blob_data_handle_map_.find(uuid);
    if (iter != blob_data_handle_map_.end()) {
      iter->second.second += 1;
      return uuid;
    }
    blob_data_handle = context->GetBlobDataFromUUID(uuid);
  }

  DCHECK(!ContainsKey(blob_data_handle_map_, uuid));
  blob_data_handle_map_[uuid] = std::make_pair(blob_data_handle.release(), 1);
  return uuid;
}

void IndexedDBDispatcherHost::DropBlobData(const std::string& uuid) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  BlobDataHandleMap::iterator iter = blob_data_handle_map_.find(uuid);
  if (iter != blob_data_handle_map_.end()) {
    DCHECK_GE(iter->second.second, 1);
    if (iter->second.second == 1) {
      delete iter->second.first;
      blob_data_handle_map_.erase(iter);
    } else {
      iter->second.second -= 1;
    }
  } else {
    DLOG(FATAL) << "Failed to find blob UUID in map:" << uuid;
  }
}

IndexedDBCursor* IndexedDBDispatcherHost::GetCursorFromId(
    int32_t ipc_cursor_id) {
  DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  return cursor_dispatcher_host_->map_.Lookup(ipc_cursor_id);
}

::IndexedDBDatabaseMetadata IndexedDBDispatcherHost::ConvertMetadata(
    const content::IndexedDBDatabaseMetadata& web_metadata) {
  ::IndexedDBDatabaseMetadata metadata;
  metadata.id = web_metadata.id;
  metadata.name = web_metadata.name;
  metadata.version = web_metadata.version;
  metadata.int_version = web_metadata.int_version;
  metadata.max_object_store_id = web_metadata.max_object_store_id;

  for (const auto& iter : web_metadata.object_stores) {
    const content::IndexedDBObjectStoreMetadata& web_store_metadata =
        iter.second;
    ::IndexedDBObjectStoreMetadata idb_store_metadata;
    idb_store_metadata.id = web_store_metadata.id;
    idb_store_metadata.name = web_store_metadata.name;
    idb_store_metadata.key_path = web_store_metadata.key_path;
    idb_store_metadata.auto_increment = web_store_metadata.auto_increment;
    idb_store_metadata.max_index_id = web_store_metadata.max_index_id;

    for (const auto& index_iter : web_store_metadata.indexes) {
      const content::IndexedDBIndexMetadata& web_index_metadata =
          index_iter.second;
      ::IndexedDBIndexMetadata idb_index_metadata;
      idb_index_metadata.id = web_index_metadata.id;
      idb_index_metadata.name = web_index_metadata.name;
      idb_index_metadata.key_path = web_index_metadata.key_path;
      idb_index_metadata.unique = web_index_metadata.unique;
      idb_index_metadata.multi_entry = web_index_metadata.multi_entry;
      idb_store_metadata.indexes.push_back(idb_index_metadata);
    }
    metadata.object_stores.push_back(idb_store_metadata);
  }
  return metadata;
}

void IndexedDBDispatcherHost::OnIDBFactoryGetDatabaseNames(
    const IndexedDBHostMsg_FactoryGetDatabaseNames_Params& params) {
  DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  base::FilePath indexed_db_path = indexed_db_context_->data_path();

  GURL origin_url =
      storage::GetOriginFromIdentifier(params.database_identifier);

  Context()->GetIDBFactory()->GetDatabaseNames(
      new IndexedDBCallbacks(
          this, params.ipc_thread_id, params.ipc_callbacks_id),
      origin_url,
      indexed_db_path,
      request_context_);
}

void IndexedDBDispatcherHost::OnIDBFactoryOpen(
    const IndexedDBHostMsg_FactoryOpen_Params& params) {
  DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  base::TimeTicks begin_time = base::TimeTicks::Now();
  base::FilePath indexed_db_path = indexed_db_context_->data_path();

  GURL origin_url =
      storage::GetOriginFromIdentifier(params.database_identifier);

  int64_t host_transaction_id = HostTransactionId(params.transaction_id);

  // TODO(dgrogan): Don't let a non-existing database be opened (and therefore
  // created) if this origin is already over quota.
  scoped_refptr<IndexedDBCallbacks> callbacks =
      new IndexedDBCallbacks(this,
                             params.ipc_thread_id,
                             params.ipc_callbacks_id,
                             params.ipc_database_callbacks_id,
                             host_transaction_id,
                             origin_url);
  callbacks->SetConnectionOpenStartTime(begin_time);
  scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks =
      new IndexedDBDatabaseCallbacks(
          this, params.ipc_thread_id, params.ipc_database_callbacks_id);
  IndexedDBPendingConnection connection(callbacks,
                                        database_callbacks,
                                        ipc_process_id_,
                                        host_transaction_id,
                                        params.version);
  DCHECK(request_context_);
  Context()->GetIDBFactory()->Open(
      params.name, connection, request_context_, origin_url, indexed_db_path);
}

void IndexedDBDispatcherHost::OnIDBFactoryDeleteDatabase(
    const IndexedDBHostMsg_FactoryDeleteDatabase_Params& params) {
  DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  GURL origin_url =
      storage::GetOriginFromIdentifier(params.database_identifier);
  base::FilePath indexed_db_path = indexed_db_context_->data_path();
  DCHECK(request_context_);
  Context()->GetIDBFactory()->DeleteDatabase(
      params.name,
      request_context_,
      new IndexedDBCallbacks(
          this, params.ipc_thread_id, params.ipc_callbacks_id),
      origin_url,
      indexed_db_path);
}

// OnPutHelper exists only to allow us to hop threads while holding a reference
// to the IndexedDBDispatcherHost.
void IndexedDBDispatcherHost::OnPutHelper(
    const IndexedDBHostMsg_DatabasePut_Params& params,
    std::vector<storage::BlobDataHandle*> handles) {
  database_dispatcher_host_->OnPut(params, handles);
}

void IndexedDBDispatcherHost::OnAckReceivedBlobs(
    const std::vector<std::string>& uuids) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  for (const auto& uuid : uuids)
    DropBlobData(uuid);
}

void IndexedDBDispatcherHost::FinishTransaction(int64_t host_transaction_id,
                                                bool committed) {
  DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  if (!database_dispatcher_host_)
    return;
  TransactionIDToURLMap& transaction_url_map =
      database_dispatcher_host_->transaction_url_map_;
  TransactionIDToSizeMap& transaction_size_map =
      database_dispatcher_host_->transaction_size_map_;
  TransactionIDToDatabaseIDMap& transaction_database_map =
      database_dispatcher_host_->transaction_database_map_;
  if (committed)
    Context()->TransactionComplete(transaction_url_map[host_transaction_id]);
  transaction_url_map.erase(host_transaction_id);
  transaction_size_map.erase(host_transaction_id);
  transaction_database_map.erase(host_transaction_id);
}

//////////////////////////////////////////////////////////////////////
// Helper templates.
//

template <typename ObjectType>
ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(
    IDMap<ObjectType, IDMapOwnPointer>* map,
    int32_t ipc_return_object_id) {
  DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  ObjectType* return_object = map->Lookup(ipc_return_object_id);
  if (!return_object) {
    NOTREACHED() << "Uh oh, couldn't find object with id "
                 << ipc_return_object_id;
    bad_message::ReceivedBadMessage(this, bad_message::IDBDH_GET_OR_TERMINATE);
  }
  return return_object;
}

template <typename ObjectType>
ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(
    RefIDMap<ObjectType>* map,
    int32_t ipc_return_object_id) {
  DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  ObjectType* return_object = map->Lookup(ipc_return_object_id);
  if (!return_object) {
    NOTREACHED() << "Uh oh, couldn't find object with id "
                 << ipc_return_object_id;
    bad_message::ReceivedBadMessage(this, bad_message::IDBDH_GET_OR_TERMINATE);
  }
  return return_object;
}

template <typename MapType>
void IndexedDBDispatcherHost::DestroyObject(MapType* map,
                                            int32_t ipc_object_id) {
  GetOrTerminateProcess(map, ipc_object_id);
  map->Remove(ipc_object_id);
}

//////////////////////////////////////////////////////////////////////
// IndexedDBDispatcherHost::DatabaseDispatcherHost
//

IndexedDBDispatcherHost::DatabaseDispatcherHost::DatabaseDispatcherHost(
    IndexedDBDispatcherHost* parent)
    : parent_(parent) {
  map_.set_check_on_null_data(true);
}

IndexedDBDispatcherHost::DatabaseDispatcherHost::~DatabaseDispatcherHost() {
  // TODO(alecflett): uncomment these when we find the source of these leaks.
  // DCHECK(transaction_size_map_.empty());
  // DCHECK(transaction_url_map_.empty());
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::CloseAll() {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  // Abort outstanding transactions started by connections in the associated
  // front-end to unblock later transactions. This should only occur on unclean
  // (crash) or abrupt (process-kill) shutdowns.
  for (TransactionIDToDatabaseIDMap::iterator iter =
           transaction_database_map_.begin();
       iter != transaction_database_map_.end();) {
    int64_t transaction_id = iter->first;
    int32_t ipc_database_id = iter->second;
    ++iter;
    IndexedDBConnection* connection = map_.Lookup(ipc_database_id);
    if (connection && connection->IsConnected()) {
      connection->database()->Abort(
          transaction_id,
          IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError));
    }
  }
  DCHECK(transaction_database_map_.empty());

  for (const auto& iter : database_url_map_) {
    IndexedDBConnection* connection = map_.Lookup(iter.first);
    if (connection && connection->IsConnected()) {
      connection->Close();
      parent_->Context()->ConnectionClosed(iter.second, connection);
    }
  }
}

bool IndexedDBDispatcherHost::DatabaseDispatcherHost::OnMessageReceived(
    const IPC::Message& message) {
  DCHECK(
      (message.type() == IndexedDBHostMsg_DatabasePut::ID ||
       message.type() == IndexedDBHostMsg_AckReceivedBlobs::ID) ||
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());

  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(
      IndexedDBDispatcherHost::DatabaseDispatcherHost, message)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCreateObjectStore,
                        OnCreateObjectStore)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDeleteObjectStore,
                        OnDeleteObjectStore)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCreateTransaction,
                        OnCreateTransaction)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseClose, OnClose)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseVersionChangeIgnored,
                        OnVersionChangeIgnored)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDestroyed, OnDestroyed)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseGet, OnGet)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseGetAll, OnGetAll)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabasePut, OnPutWrapper)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseSetIndexKeys, OnSetIndexKeys)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseSetIndexesReady,
                        OnSetIndexesReady)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseOpenCursor, OnOpenCursor)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCount, OnCount)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDeleteRange, OnDeleteRange)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseClear, OnClear)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCreateIndex, OnCreateIndex)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseDeleteIndex, OnDeleteIndex)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseAbort, OnAbort)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_DatabaseCommit, OnCommit)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  return handled;
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateObjectStore(
    const IndexedDBHostMsg_DatabaseCreateObjectStore_Params& params) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  int64_t host_transaction_id =
      parent_->HostTransactionId(params.transaction_id);
  connection->database()->CreateObjectStore(host_transaction_id,
                                            params.object_store_id,
                                            params.name,
                                            params.key_path,
                                            params.auto_increment);
  if (parent_->Context()->IsOverQuota(
          database_url_map_[params.ipc_database_id])) {
    connection->database()->Abort(
        host_transaction_id,
        IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError));
  }
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteObjectStore(
    int32_t ipc_database_id,
    int64_t transaction_id,
    int64_t object_store_id) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  connection->database()->DeleteObjectStore(
      parent_->HostTransactionId(transaction_id), object_store_id);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateTransaction(
    const IndexedDBHostMsg_DatabaseCreateTransaction_Params& params) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  int64_t host_transaction_id =
      parent_->HostTransactionId(params.transaction_id);

  if (transaction_database_map_.find(host_transaction_id) !=
      transaction_database_map_.end()) {
    DLOG(ERROR) << "Duplicate host_transaction_id.";
    return;
  }

  connection->database()->CreateTransaction(
      host_transaction_id, connection, params.object_store_ids, params.mode);
  transaction_database_map_[host_transaction_id] = params.ipc_database_id;
  parent_->RegisterTransactionId(host_transaction_id,
                                 database_url_map_[params.ipc_database_id]);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClose(
    int32_t ipc_database_id) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;
  connection->Close();
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnVersionChangeIgnored(
    int32_t ipc_database_id) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;
  connection->VersionChangeIgnored();
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDestroyed(
    int32_t ipc_object_id) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, ipc_object_id);
  if (!connection)
    return;
  if (connection->IsConnected())
    connection->Close();
  parent_->Context()
      ->ConnectionClosed(database_url_map_[ipc_object_id], connection);
  database_url_map_.erase(ipc_object_id);
  parent_->DestroyObject(&map_, ipc_object_id);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnGet(
    const IndexedDBHostMsg_DatabaseGet_Params& params) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
      parent_, params.ipc_thread_id, params.ipc_callbacks_id));
  connection->database()->Get(
      parent_->HostTransactionId(params.transaction_id),
      params.object_store_id,
      params.index_id,
      make_scoped_ptr(new IndexedDBKeyRange(params.key_range)),
      params.key_only,
      callbacks);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnGetAll(
    const IndexedDBHostMsg_DatabaseGetAll_Params& params) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
      parent_, params.ipc_thread_id, params.ipc_callbacks_id));
  connection->database()->GetAll(
      parent_->HostTransactionId(params.transaction_id), params.object_store_id,
      params.index_id, make_scoped_ptr(new IndexedDBKeyRange(params.key_range)),
      params.key_only, params.max_count, callbacks);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPutWrapper(
    const IndexedDBHostMsg_DatabasePut_Params& params) {
  std::vector<storage::BlobDataHandle*> handles;
  for (size_t i = 0; i < params.value.blob_or_file_info.size(); ++i) {
    const IndexedDBMsg_BlobOrFileInfo& info = params.value.blob_or_file_info[i];
    handles.push_back(parent_->blob_storage_context_->context()
                          ->GetBlobDataFromUUID(info.uuid)
                          .release());
  }
  parent_->indexed_db_context_->TaskRunner()->PostTask(
      FROM_HERE,
      base::Bind(
          &IndexedDBDispatcherHost::OnPutHelper, parent_, params, handles));
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPut(
    const IndexedDBHostMsg_DatabasePut_Params& params,
    std::vector<storage::BlobDataHandle*> handles) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());

  ScopedVector<storage::BlobDataHandle> scoped_handles;
  scoped_handles.swap(handles);

  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;
  scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
      parent_, params.ipc_thread_id, params.ipc_callbacks_id));

  int64_t host_transaction_id =
      parent_->HostTransactionId(params.transaction_id);

  std::vector<IndexedDBBlobInfo> blob_info(
      params.value.blob_or_file_info.size());

  ChildProcessSecurityPolicyImpl* policy =
      ChildProcessSecurityPolicyImpl::GetInstance();

  for (size_t i = 0; i < params.value.blob_or_file_info.size(); ++i) {
    const IndexedDBMsg_BlobOrFileInfo& info = params.value.blob_or_file_info[i];
    if (info.is_file) {
      base::FilePath path;
      if (!info.file_path.empty()) {
        path = base::FilePath::FromUTF16Unsafe(info.file_path);
        if (!policy->CanReadFile(parent_->ipc_process_id_, path)) {
          bad_message::ReceivedBadMessage(parent_,
                                          bad_message::IDBDH_CAN_READ_FILE);
          return;
        }
      }
      blob_info[i] =
          IndexedDBBlobInfo(info.uuid, path, info.file_name, info.mime_type);
      if (info.size != static_cast<uint64_t>(-1)) {
        blob_info[i].set_last_modified(
            base::Time::FromDoubleT(info.last_modified));
        blob_info[i].set_size(info.size);
      }
    } else {
      blob_info[i] = IndexedDBBlobInfo(info.uuid, info.mime_type, info.size);
    }
  }

  // TODO(alecflett): Avoid a copy here.
  IndexedDBValue value;
  value.bits = params.value.bits;
  value.blob_info.swap(blob_info);
  connection->database()->Put(host_transaction_id,
                              params.object_store_id,
                              &value,
                              &scoped_handles,
                              make_scoped_ptr(new IndexedDBKey(params.key)),
                              params.put_mode,
                              callbacks,
                              params.index_keys);
  TransactionIDToSizeMap* map =
      &parent_->database_dispatcher_host_->transaction_size_map_;
  // Size can't be big enough to overflow because it represents the
  // actual bytes passed through IPC.
  (*map)[host_transaction_id] += params.value.bits.size();
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnSetIndexKeys(
    const IndexedDBHostMsg_DatabaseSetIndexKeys_Params& params) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  int64_t host_transaction_id =
      parent_->HostTransactionId(params.transaction_id);
  connection->database()->SetIndexKeys(
      host_transaction_id,
      params.object_store_id,
      make_scoped_ptr(new IndexedDBKey(params.primary_key)),
      params.index_keys);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnSetIndexesReady(
    int32_t ipc_database_id,
    int64_t transaction_id,
    int64_t object_store_id,
    const std::vector<int64_t>& index_ids) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  connection->database()->SetIndexesReady(
      parent_->HostTransactionId(transaction_id), object_store_id, index_ids);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnOpenCursor(
    const IndexedDBHostMsg_DatabaseOpenCursor_Params& params) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
      parent_, params.ipc_thread_id, params.ipc_callbacks_id, -1));
  connection->database()->OpenCursor(
      parent_->HostTransactionId(params.transaction_id),
      params.object_store_id,
      params.index_id,
      make_scoped_ptr(new IndexedDBKeyRange(params.key_range)),
      params.direction,
      params.key_only,
      params.task_type,
      callbacks);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCount(
    const IndexedDBHostMsg_DatabaseCount_Params& params) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
      parent_, params.ipc_thread_id, params.ipc_callbacks_id));
  connection->database()->Count(
      parent_->HostTransactionId(params.transaction_id),
      params.object_store_id,
      params.index_id,
      make_scoped_ptr(new IndexedDBKeyRange(params.key_range)),
      callbacks);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteRange(
    const IndexedDBHostMsg_DatabaseDeleteRange_Params& params) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks(
      parent_, params.ipc_thread_id, params.ipc_callbacks_id));
  connection->database()->DeleteRange(
      parent_->HostTransactionId(params.transaction_id),
      params.object_store_id,
      make_scoped_ptr(new IndexedDBKeyRange(params.key_range)),
      callbacks);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnClear(
    int32_t ipc_thread_id,
    int32_t ipc_callbacks_id,
    int32_t ipc_database_id,
    int64_t transaction_id,
    int64_t object_store_id) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  scoped_refptr<IndexedDBCallbacks> callbacks(
      new IndexedDBCallbacks(parent_, ipc_thread_id, ipc_callbacks_id));

  connection->database()->Clear(
      parent_->HostTransactionId(transaction_id), object_store_id, callbacks);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnAbort(
    int32_t ipc_database_id,
    int64_t transaction_id) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  connection->database()->Abort(parent_->HostTransactionId(transaction_id));
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCommit(
    int32_t ipc_database_id,
    int64_t transaction_id) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  int64_t host_transaction_id = parent_->HostTransactionId(transaction_id);
  int64_t transaction_size = transaction_size_map_[host_transaction_id];
  if (transaction_size &&
      parent_->Context()->WouldBeOverQuota(
          transaction_url_map_[host_transaction_id], transaction_size)) {
    connection->database()->Abort(
        host_transaction_id,
        IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError));
    return;
  }

  connection->database()->Commit(host_transaction_id);
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnCreateIndex(
    const IndexedDBHostMsg_DatabaseCreateIndex_Params& params) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, params.ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  int64_t host_transaction_id =
      parent_->HostTransactionId(params.transaction_id);
  connection->database()->CreateIndex(host_transaction_id,
                                      params.object_store_id,
                                      params.index_id,
                                      params.name,
                                      params.key_path,
                                      params.unique,
                                      params.multi_entry);
  if (parent_->Context()->IsOverQuota(
          database_url_map_[params.ipc_database_id])) {
    connection->database()->Abort(
        host_transaction_id,
        IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError));
  }
}

void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnDeleteIndex(
    int32_t ipc_database_id,
    int64_t transaction_id,
    int64_t object_store_id,
    int64_t index_id) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBConnection* connection =
      parent_->GetOrTerminateProcess(&map_, ipc_database_id);
  if (!connection || !connection->IsConnected())
    return;

  connection->database()->DeleteIndex(
      parent_->HostTransactionId(transaction_id), object_store_id, index_id);
}

//////////////////////////////////////////////////////////////////////
// IndexedDBDispatcherHost::CursorDispatcherHost
//

IndexedDBDispatcherHost::CursorDispatcherHost::CursorDispatcherHost(
    IndexedDBDispatcherHost* parent)
    : parent_(parent) {
  map_.set_check_on_null_data(true);
}

IndexedDBDispatcherHost::CursorDispatcherHost::~CursorDispatcherHost() {}

bool IndexedDBDispatcherHost::CursorDispatcherHost::OnMessageReceived(
    const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(
      IndexedDBDispatcherHost::CursorDispatcherHost, message)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorAdvance, OnAdvance)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorContinue, OnContinue)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorPrefetch, OnPrefetch)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorPrefetchReset, OnPrefetchReset)
    IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDestroyed, OnDestroyed)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()

  DCHECK(
      !handled ||
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());

  return handled;
}

void IndexedDBDispatcherHost::CursorDispatcherHost::OnAdvance(
    int32_t ipc_cursor_id,
    int32_t ipc_thread_id,
    int32_t ipc_callbacks_id,
    uint32_t count) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBCursor* idb_cursor =
      parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
  if (!idb_cursor)
    return;

  idb_cursor->Advance(
      count,
      new IndexedDBCallbacks(
          parent_, ipc_thread_id, ipc_callbacks_id, ipc_cursor_id));
}

void IndexedDBDispatcherHost::CursorDispatcherHost::OnContinue(
    int32_t ipc_cursor_id,
    int32_t ipc_thread_id,
    int32_t ipc_callbacks_id,
    const IndexedDBKey& key,
    const IndexedDBKey& primary_key) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBCursor* idb_cursor =
      parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
  if (!idb_cursor)
    return;

  idb_cursor->Continue(
      key.IsValid() ? make_scoped_ptr(new IndexedDBKey(key))
                    : scoped_ptr<IndexedDBKey>(),
      primary_key.IsValid() ? make_scoped_ptr(new IndexedDBKey(primary_key))
                            : scoped_ptr<IndexedDBKey>(),
      new IndexedDBCallbacks(
          parent_, ipc_thread_id, ipc_callbacks_id, ipc_cursor_id));
}

void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetch(
    int32_t ipc_cursor_id,
    int32_t ipc_thread_id,
    int32_t ipc_callbacks_id,
    int n) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBCursor* idb_cursor =
      parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
  if (!idb_cursor)
    return;

  idb_cursor->PrefetchContinue(
      n,
      new IndexedDBCallbacks(
          parent_, ipc_thread_id, ipc_callbacks_id, ipc_cursor_id));
}

void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetchReset(
    int32_t ipc_cursor_id,
    int used_prefetches,
    int unused_prefetches) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  IndexedDBCursor* idb_cursor =
      parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
  if (!idb_cursor)
    return;

  leveldb::Status s =
      idb_cursor->PrefetchReset(used_prefetches, unused_prefetches);
  // TODO(cmumford): Handle this error (crbug.com/363397)
  if (!s.ok())
    DLOG(ERROR) << "Unable to reset prefetch";
}

void IndexedDBDispatcherHost::CursorDispatcherHost::OnDestroyed(
    int32_t ipc_object_id) {
  DCHECK(
      parent_->indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
  parent_->DestroyObject(&map_, ipc_object_id);
}

}  // namespace content


text:
<!DOCTYPE HTML>

<title>IssuerLocaleChangedCallback (ACF (Core) 0.5.1-SNAPSHOT API)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="declaration: package: co.aikar.commands, interface: IssuerLocaleChangedCallback">
<meta name="generator" content="javadoc/ClassWriterImpl">
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../script-dir/jquery-ui.min.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../jquery-ui.overrides.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

SEARCH:
<input type="text" id="search-input" value="search" disabled="disabled">
<input type="reset" id="reset-button" value="reset" disabled="disabled">

Package co.aikar.commands

Interface IssuerLocaleChangedCallback<I extends CommandIssuer>

public interface IssuerLocaleChangedCallback<I extends CommandIssuer>

Method Summary

<button id="method-summary-table-tab0" role="tab" aria-selected="true" aria-controls="method-summary-table.tabpanel" tabindex="0" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table', 3)" class="active-table-tab">All Methods</button><button id="method-summary-table-tab2" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table-tab2', 3)" class="table-tab">Instance Methods</button><button id="method-summary-table-tab3" role="tab" aria-selected="false" aria-controls="method-summary-table.tabpanel" tabindex="-1" onkeydown="switchTab(event)" onclick="show('method-summary-table', 'method-summary-table-tab3', 3)" class="table-tab">Abstract Methods</button>

Modifier and Type

Method

Description

void

onIssuerLocaleChange<wbr>(I issuer,
 Locale oldLocale,
 Locale newLocale)

Method Details

onIssuerLocaleChange

void onIssuerLocaleChange<wbr>(I issuer,
 Locale oldLocale,
 Locale newLocale)

Copyright © 2021. All rights reserved.

redpajama_set_name: RedPajamaGithub


text:
#include "stdafx.h"
#include "log.h"
#include "logfile.h"
#include <io.h>

#include <chrono>

#include "../math/math.h"
#include "../files/files.h"

// the maxfile size we want to use.
static size_t MAX_FILE_SIZE_IN_MEGABYTES = 5;

static const MYODD_CHAR* LogFile_default_Prefix = _T("myodd");
static const MYODD_CHAR* LogFile_default_Extention = _T("log");

namespace myodd{ namespace log{
  LogFile::LogFile() :
    m_fp( NULL ),
    m_uCurrentSize( 0 ),
    m_bInOpenCall( false ),
    _maxFileSizeInMegabytes(MAX_FILE_SIZE_IN_MEGABYTES)
  {
  }

  LogFile::~LogFile()
  {
    //  close the log file.
    Close();
  }

  /**
   * Check if the log file is open or not.
   * @param none
   * @return bool if the log file is open or not.
   */
  bool LogFile::IsOpen() const
  {
    return ( m_fp != NULL && !m_bInOpenCall );
  }

  struct tm LogFile::GetCurrentTimeStruct() const
  {
    // the current time.
    auto timeNow = std::chrono::system_clock::now();

    // to a time_t struct
    auto tTime = std::chrono::system_clock::to_time_t(timeNow);

    // to a tm structure.
    return *localtime(&tTime);
  }

  /**
   * Updated the started time of the log file.
   * this will set the _tStarted structure.
   */
  void LogFile::UpdateStartedTime()
  {
    // update the started time with the current structure.
    _tStarted = GetCurrentTimeStruct();
  }

  /**
   * Create the log file given the prefix and extension
   * We will check that the file size if within limit
   * And the date/time is up to date.
   */
  bool LogFile::Create()
  {
    //  is the file open already.
    if (IsOpen())
    {
      return true;
    }

    // lock the current
    if( m_bInOpenCall )
    {
      return false;
    }

    //  we are in open call
    // that way we can log things ourselves.
    m_bInOpenCall = true;

    bool bResult = false;
    try
    {
      // get the time now.
      UpdateStartedTime();

      // look for a file that matches
      for ( unsigned int i = 0;; ++i )
      {
        //  get the log file.
        MYODD_CHAR szDateLogStarted[40] = {};
        _tcsftime(szDateLogStarted, _countof(szDateLogStarted), _T("%Y-%m-%d"), &_tStarted );

        // add a number if the file number is > 0
        // so we will create more than one file for today if need be.
        MYODD_CHAR szFileCount[10] = {};
        if (i > 0)
        {
          swprintf(szFileCount, _T("-%u"), i);
        }

        //  we have already added a back slash at the end of the directory.
        // the file could exist already.
        std::wstring proposedCurrentFile = m_sDirectory + m_sPrefix + szDateLogStarted + szFileCount + _T(".") + m_sExtention;

        double fileSizeInMegabytes = myodd::math::BytesToMegabytes(myodd::files::GetFileSizeInBytes(proposedCurrentFile));
        if (fileSizeInMegabytes < GetMaxFileSizeInMegabytes())
        {
          m_sCurrentFile = proposedCurrentFile;
          break;
        }
      }

      // try and open the new file.
      m_fp = _tfsopen(m_sCurrentFile.c_str(), _T("a+b"), _SH_DENYWR);

      // did the file open?
      if( NULL == m_fp )
      {
        myodd::log::LogError( _T("Could not open log file : \"%s\"."), m_sCurrentFile.c_str() );
        bResult = false;
      }
      else
      {
        myodd::log::LogSuccess( _T("Log file, \"%s\", opened."), m_sCurrentFile.c_str() );

        //  get the size of the file.
        m_uCurrentSize = _filelengthi64(_fileno(m_fp));

        // is it a brand new file?
        if( m_uCurrentSize == 0 )
        {
          // add the unicode byte order format.
          fputwc(0xFEFF, m_fp);
        }
#ifdef _DEBUG
        // just make sure that we have the right format.
        // if the file was changed by the user, then something will go wrong at some stage.
        // but we cannot go around and police user misbehaving
        //
        // so the debug version will make sure that the app is not misbehaving.
        else if (m_uCurrentSize >= sizeof(WORD))
        {
          WORD wBOM;
          if (fread(&wBOM, sizeof(wBOM), 1, m_fp) == 1)
          {
            assert( wBOM == 0xFEFF );
          }
        }
#endif // Check for the UNICODE param

        // go to the end of the file.
        (void)fseek(m_fp, 0, SEEK_END);
      }

      //  if we made it here, then it worked.
      bResult = true;
    }
    catch ( ... )
    {
      bResult = false;
    }

    //  we are no longer in open call.
    m_bInOpenCall = false;

    // return if this worked.
    return bResult;
  }

  /**
   * Ensure that the file is not too big and not out of date.
   */
  void LogFile::ValidateDateAndSize()
  {
    if (!IsOpen())
    {
      return;
    }

    // recreate?
    bool bRecreate = false;

    // check the size.
    double fileSizeInMegabytes = myodd::math::BytesToMegabytes(myodd::files::GetFileSizeInBytes( GetCurrentLogFile()));
    if (fileSizeInMegabytes > GetMaxFileSizeInMegabytes())
    {
      bRecreate = true;
    }
    else
    {
      // get the current time and check if the file is out of date.
      auto tStarted = GetCurrentTimeStruct();

      //  compare it to the started time.
      auto tm = GetStartedDate();
      if (tm.tm_yday != tStarted.tm_yday)
      {
        //  close the old one and force a re-open
        // this will force a check to be done.
        bRecreate = true;
      }
    }

    if (bRecreate)
    {
      // close the old file
      Close();

      // create a new one.
      Create();
    }
  }

  /**
   * Open the file for login.
   * @param none
   * @return none
   */
  bool LogFile::Open()
  {
    //  is the file open already.
    if (IsOpen())
    {
      return true;
    }

    // lock the current
    if( m_bInOpenCall )
    {
      return false;
    }

    //  we are in open call
    // that way we can log things ourselves.
    m_bInOpenCall = true;

    //  assume an error.
    bool bResult = false;
    try
    {
      // do we already know the name of the file?
      if( m_sCurrentFile.empty() )
      {
        if( !Create() )
        {
          //  there was a problem.
          m_bInOpenCall = true;
          return false;
        }
      }

      // try and open the new file.
      m_fp = _tfsopen(m_sCurrentFile.c_str(), _T("a+b"), _SH_DENYWR);

      //  get the size of the file.
      m_uCurrentSize = _filelengthi64(_fileno(m_fp));

      // go to the end of the file.
      (void)fseek(m_fp, 0, SEEK_END);

      //  if we made it here, then it worked.
      bResult = true;
    }
    catch ( ... )
    {
      bResult = false;
    }

    //  we are no longer in open call.
    m_bInOpenCall = false;

    return bResult;
  }

  /**
   * Close a log file.
   * @param none
   * @return bool if the file was closed or not.
   */
  bool LogFile::Close()
  {
    // is it open?
    if (!IsOpen())
    {
      return true;
    }

    // close it.
    bool bResult = (fclose(m_fp) == 0);
    m_fp = NULL;
    m_uCurrentSize = 0;
    return bResult;
  }

  /**
   * Log an entry to the file.
   * @param unsigned int uiType the log type
   * @param const MYODD_CHAR* the line we are adding.
   * @return bool success or not.
   */
  bool LogFile::LogToFile( unsigned int uiType, const MYODD_CHAR* pszLine )
  {
    //  are we logging?
    if (m_sCurrentFile.empty())
    {
      return false;
    }

    if (!Open())
    {
      return false;
    }

    // check the size and date
    ValidateDateAndSize();

    bool bResult = false;
    try
    {
      // get the current date so we can add it to the log.
      auto tStarted = GetCurrentTimeStruct();

      MYODD_CHAR szDateLogStarted[40];
      _tcsftime(szDateLogStarted, _countof(szDateLogStarted), _T("%Y/%m/%d %H:%M:%S"), &tStarted );

      //  build the return message.
      MYODD_STRING stdMsg = szDateLogStarted;
      stdMsg += _T(" ") + myodd::strings::ToString( uiType, _T("%04d") );
      stdMsg += _T(" ");
      stdMsg += (pszLine ? pszLine : _T(""));
      stdMsg += _T("\r\n");

      const MYODD_CHAR* pszMsg = stdMsg.c_str();

      // get the total size of what we are about to write..
      size_t uToWrite = _tcslen(pszMsg) * sizeof(MYODD_CHAR);

      //  then we can write to the file.
      size_t uWritten = fwrite(pszMsg, 1, uToWrite, m_fp);

      //  did it work?
      bResult = !ferror(m_fp);

      //  get the file size.
      m_uCurrentSize += uWritten;
    }
    catch( ... )
    {
    }
    Close();
    return bResult;
  }

  /**
  * Set the log path directory.
  * If we pass a NULL argument then we want to stop/disable the logging.
  * @param const std::wstring& wPath the log path we will be using.
  * @param const std::wstring& wPrefix the prefix of the filename we will create, (default is blank).
  * @param const std::wstring& wExtention the file extension.
  * @param size_t maxFileSize the max file size in megabytes.
  * @return bool success or not
  */
  bool LogFile::Initialise(const std::wstring& wPath, const std::wstring& wPrefix, const std::wstring& wExtention, size_t maxFileSize)
  {
    //  close the file
    Close();

    // is the new, given path valid?
    // or is the user telling us that they want to close it?
    if( wPath.length() == 0 )
    {
      m_sPrefix = m_sExtention = m_sDirectory = _T("");
      return true;
    }

    //  set the prefix and extension.
    // if the user is giving us some silly values then there is nothing we can do about really.
    m_sPrefix     = wPrefix.length() > 0    ? wPrefix    : LogFile_default_Prefix;
    m_sExtention  = wExtention.length() > 0 ? wExtention : LogFile_default_Extention;

    // It seems to be valid, so we can set the path here.
    m_sDirectory = wPath;

    //  expand the file name
    if (!myodd::files::ExpandEnvironment(m_sDirectory, m_sDirectory))
    {
      return false;
    }

    //  add a trailing backslash
    myodd::files::AddTrailingBackSlash( m_sDirectory );

    //  expand the path, in case the user changes their path or something.
    if( !myodd::files::GetAbsolutePath( m_sDirectory, m_sDirectory, _T(".") ))
    {
      return false;
    }

    // expand the path, in case the user changes their path or something.
    if( !myodd::files::CreateFullDirectory( m_sDirectory.c_str(), false ) )
    {
      return false;
    }

    // simply open the next file
    // if there is a problem then nothing will log.
    return Create();
  }
} //  log
} //  myodd


text:
@interface TBBaseCollectionViewController : TBBaseViewController

@property (weak, nonatomic) IBOutlet UICollectionView *clvData;

@property (strong, nonatomic) NSMutableArray *arrData;

#pragma mark - UITableView
#pragma marl + Datasource
- (void)cellForRow:(UICollectionViewCell *)_cell;

#pragma mark + Delegate
- (void)didSelectWithObject:(id)_object;
- (void)didSelectWithObject:(id)_object withCell:(UICollectionViewCell *)_cell;

#pragma mark + SVPullToRefresh
- (void)addPullToRefresh;
- (void)processForRefresh;

- (void)addPullToLoadMore;
- (void)processForLoadMore;

#pragma mark - Data
- (void)reloadData;

- (void)prepareData;
- (void)loadDataWithOffSet:(NSInteger)offSet;
- (void)displayError:(NSError *)error;

@end


text:
import { Router, Route, IndexRoute, Redirect, Link, browserHistory } from 'react-router'
import React from 'react'
import ContentEditable from 'react-contenteditable'
import update from 'react/lib/update';
import Card from './board/Card';
import Modal from '../ui/Modal';

class BoardTemplate extends React.Component {
  constructor(...args) {
    super(...args);

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(evt) {
    this.props.data.html = evt.target.value;
    this.props.handleChange();
  }

  render() {
    return (
      <ContentEditable
        onChange={this.handleChange}
        html={this.props.data.html}
        disabled={true}/>
    )
  }
}

export default class Board extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      tpl: this.props.tpl,
      activeTpl: {},
      activeTplLink: '',
      modal: false,
      shouldUpdate: true
    };

    this.moveCard = this.moveCard.bind(this);
    this._state = Object.assign({}, this.state);
    this.handleTitleChange = this.handleTitleChange.bind(this);
    this.handledDescriptionChange = this.handledDescriptionChange.bind(this);
    this.handleRemove = this.handleRemove.bind(this);
    this.handleLink = this.handleLink.bind(this);
    this.hideModal = this.hideModal.bind(this);
    this.handleOk = this.handleOk.bind(this);
    this.handleLinkChange = this.handleLinkChange.bind(this);
  }

  componentWillUpdate(nextProps, nextState) {
    this.props.saveState();
  }

  handleTitleChange(e) {
    this.setState(update(this.state, {
      tpl: {
        title: {
          $set: e.target.value
        }
      }
    }));
  }

  handledDescriptionChange(e) {
    this.setState(update(this.state, {
      tpl: {
        description: {
          $set: e.target.value
        }
      }
    }));
  }

  moveCard(dragIndex, hoverIndex) {
    const { items } = this.state.tpl;
    const dragCard = items[dragIndex];

    this.setState(update(this.state, {
      tpl: {
        items: {
          $splice: [
            [dragIndex, 1],
            [hoverIndex, 0, dragCard]
          ]
        }
      }
    }));
  }

  handleRemove(index) {
    return () => {
      var state = update(this.state, {
        tpl: {
          items: {
            $splice: [[index, 1]]
          }
        }
      })

      this.props.tpl.items = state.tpl.items;

      this.setState(state);
    }
  }

  handleLink(item) {
    return () => {
      this.setState(update(this.state, {
        $merge: {
          activeTpl: item,
          activeTplLink: item.link,
          modal: true
        }
      }));
    }
  }

  handleLinkChange(e) {
    this.setState(update(this.state, {
      activeTplLink: {
        $set: e.target.value
      }
    }));
  }

  hideModal() {
    this.setState(update(this.state, {
      modal: {
        $set: false
      }
    }));
  }

  handleOk() {
    if (this.state.activeTpl) {
      var itemIndex = -1;
      this.state.tpl.items.forEach((item, index) => {
        if (item.id == this.state.activeTpl.id) {
          item.link = this.state.activeTplLink;
          return false;
        }
      });
      this.state.modal = false;
      this.setState(this.state);
    }
  }

  render() {
    var style = {
      display: this.state.tpl.items.length ? 'none' : 'block',
      textAlign: 'center'
    }

    var createTemplate = (item) => {
      if (item.type === 'image') {
        return (

        )
      } else if (item.type == 'text') {
        return (
          <BoardTemplate data={item} handleChange={this.props.saveState} />
        )
      } else {
        return (

        )
      }
    }

    return (

        <Modal
          data={{title: '超链接'}}
          show={this.state.modal}
          onHide={this.hideModal}
          onOk={this.handleOk} >
          <input
            className="form-control"
            type="text"
            value={this.state.activeTplLink}
            onChange={this.handleLinkChange}
            placeholder="请填写链接" />
        </Modal>

            <input
              className="form-control title"
              type="text"
              placeholder="标题"
              value={this.state.tpl.title}
              onChange={this.handleTitleChange} />
            <textarea
              className="form-control description"
              type="text"
              placeholder="微信分享描述"
              value={this.state.tpl.description}
              onChange={this.handledDescriptionChange} />

☜请在左边添加模版

          {this.state.tpl.items.map((item, i) => {
            return (
              <Card
                key={item.id}
                index={i}
                moveCard={this.moveCard}
                handleRemove={this.handleRemove(i)}
                handleLink={this.handleLink(item)}
                config={item.config} >
                {createTemplate(item)}
              </Card>
            );
          })}

    )
  }
}


text:
package org.jitsi.impl.protocol.xmpp;

import net.java.sip.communicator.service.protocol.*;

import org.osgi.framework.*;

import java.util.*;

/**
 * Protocol provider factory implementation ofr {@link XmppProtocolProvider}.
 *
 * @author Pawel Domas
 */
public class XmppProviderFactory
    extends ProtocolProviderFactory
{
    /**
     * Creates a new <tt>ProtocolProviderFactory</tt>.
     *
     * @param bundleContext the bundle context reference of the service
     * @param protocolName  the name of the protocol
     */
    protected XmppProviderFactory(
            BundleContext bundleContext,
            String protocolName)
    {
        super(bundleContext, protocolName);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public AccountID installAccount(String s,
                                    Map<String, String> stringStringMap)
        throws IllegalArgumentException, IllegalStateException,
               NullPointerException
    {
        throw new RuntimeException("Not implemented");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void modifyAccount(ProtocolProviderService protocolProviderService,
                              Map<String, String> stringStringMap)
        throws NullPointerException
    {
        throw new RuntimeException("Not implemented");
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected AccountID createAccountID(String userId,
                                        Map<String, String> accountProperties)
    {
        return new XmppAccountID(userId, accountProperties);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected ProtocolProviderService createService(String userID,
                                                    AccountID accountID)
    {
        return new XmppProtocolProvider(accountID);
    }
}


text:
egghead-angularjs-protractor-screenshots
========================================

Code for the Better Protractor Testing with Screenshots video on egghead.io

```js
var IndexPage = require('./IndexPage'),
    capture = require('../screenshot');

describe('hello-protractor', function () {

  var page = new IndexPage();

  beforeEach(function() {
      page.get();
  });

  afterEach(function () {
    capture.takeScreenshot(jasmine.getEnv().currentSpec);
  });

  describe('index', function () {
    it('should display the correct title', function () {
      expect(page.getTitle()).toBe('hello protractor');
    });

    it('should display the message when button clicked', function () {
      page.clickButton();

      expect(page.getMessageText()).toBe('button 1 clicked');
    });
  });
});
```

```js
var fs = require('fs');

function capture (spec) {
	var name = spec.description.split(' ').join('_');

	browser.takeScreenshot().then(function (png) {
		var stream = fs.createWriteStream('screenshots/' + name + '.png');
		stream.write(new Buffer(png, 'base64'));
		stream.end();
	});
}

exports.takeScreenshot = function (spec) {
	capture(spec);
};

exports.takeScreenshotOnFailure = function (spec) {
	if (spec.results().passed()) return;

	capture(spec);
};
```


text:
namespace chromeos {

namespace {

// Used to wait for session manager to become active.
class SessionStartWaiter : public session_manager::SessionManagerObserver {
 public:
  SessionStartWaiter() = default;
  ~SessionStartWaiter() override = default;

  void Wait() {
    if (!session_manager::SessionManager::Get()->IsUserSessionBlocked())
      return;
    session_observer_.Add(session_manager::SessionManager::Get());

    base::RunLoop run_loop;
    session_active_callback_ = run_loop.QuitClosure();
    run_loop.Run();

    session_observer_.RemoveAll();
  }

  // session_manager::SessionManagerObserver:
  void OnSessionStateChanged() override {
    if (!session_manager::SessionManager::Get()->IsUserSessionBlocked() &&
        session_active_callback_) {
      std::move(session_active_callback_).Run();
    }
  }

 private:
  base::OnceClosure session_active_callback_;
  ScopedObserver<session_manager::SessionManager,
                 session_manager::SessionManagerObserver>
      session_observer_{this};

  DISALLOW_COPY_AND_ASSIGN(SessionStartWaiter);
};

}  // namespace

class PasswordChangeTest : public LoginManagerTest {
 public:
  PasswordChangeTest() : LoginManagerTest() {
    login_mixin_.AppendRegularUsers(1);
    test_account_id_ = login_mixin_.users()[0].account_id;
  }
  ~PasswordChangeTest() override = default;

  UserContext GetTestUserContext() {
    const user_manager::User* user =
        user_manager::UserManager::Get()->FindUser(test_account_id_);
    UserContext user_context(*user);
    user_context.SetKey(Key(kPassword));
    user_context.SetUserIDHash(test_account_id_.GetUserEmail());
    return user_context;
  }

  // Sets up UserSessionManager to use stub authenticator that reports a
  // password change, and attempts login.
  // Password changed OOBE dialog is expected to show up after calling this.
  void SetUpStubAuthentcatorAndAttemptLogin(const std::string& old_password) {
    UserContext user_context = GetTestUserContext();

    auto authenticator_builder =
        std::make_unique<StubAuthenticatorBuilder>(user_context);
    authenticator_builder->SetUpPasswordChange(
        old_password,
        base::BindRepeating(&PasswordChangeTest::HandleDataRecoveryStatusChange,
                            base::Unretained(this)));
    test::UserSessionManagerTestApi(UserSessionManager::GetInstance())
        .InjectAuthenticatorBuilder(std::move(authenticator_builder));

    ExistingUserController::current_controller()->SetDisplayEmail(
        test_account_id_.GetUserEmail());
    ExistingUserController::current_controller()->Login(user_context,
                                                        SigninSpecifics());
  }

  void WaitForPasswordChangeScreen() {
    OobeScreenWaiter(OobeScreen::SCREEN_PASSWORD_CHANGED).Wait();
    OobeWindowVisibilityWaiter(true).Wait();

    EXPECT_FALSE(ash::LoginScreenTestApi::IsShutdownButtonShown());
    EXPECT_FALSE(ash::LoginScreenTestApi::IsGuestButtonShown());
    EXPECT_FALSE(ash::LoginScreenTestApi::IsAddUserButtonShown());
  }

 protected:
  AccountId test_account_id_;
  StubAuthenticator::DataRecoveryStatus data_recovery_status_ =
      StubAuthenticator::DataRecoveryStatus::kNone;
  LoginManagerMixin login_mixin_{&mixin_host_};

 private:
  void HandleDataRecoveryStatusChange(
      StubAuthenticator::DataRecoveryStatus status) {
    EXPECT_EQ(StubAuthenticator::DataRecoveryStatus::kNone,
              data_recovery_status_);
    data_recovery_status_ = status;
  }
};

IN_PROC_BROWSER_TEST_F(PasswordChangeTest, MigrateOldCryptohome) {
  SetUpStubAuthentcatorAndAttemptLogin("old user password");
  WaitForPasswordChangeScreen();

  test::OobeJS()
      .CreateVisibilityWaiter(true,
                              {"gaia-password-changed", "oldPasswordCard"})
      ->Wait();

  // Fill out and submit the old password passed to the stub authenticator.
  test::OobeJS().TypeIntoPath("old user password",
                              {"gaia-password-changed", "oldPasswordInput"});
  test::OobeJS().ClickOnPath(
      {"gaia-password-changed", "oldPasswordInputForm", "button"});

  // User session should start, and whole OOBE screen is expected to be hidden,
  OobeWindowVisibilityWaiter(false).Wait();
  EXPECT_EQ(StubAuthenticator::DataRecoveryStatus::kRecovered,
            data_recovery_status_);

  SessionStartWaiter().Wait();
}

IN_PROC_BROWSER_TEST_F(PasswordChangeTest, RetryOnWrongPassword) {
  SetUpStubAuthentcatorAndAttemptLogin("old user password");
  WaitForPasswordChangeScreen();
  test::OobeJS()
      .CreateVisibilityWaiter(true,
                              {"gaia-password-changed", "oldPasswordCard"})
      ->Wait();

  // Fill out and submit the old password passed to the stub authenticator.
  test::OobeJS().TypeIntoPath("incorrect old user password",
                              {"gaia-password-changed", "oldPasswordInput"});
  test::OobeJS().ClickOnPath(
      {"gaia-password-changed", "oldPasswordInputForm", "button"});

  // Expect the UI to report failure.
  test::OobeJS()
      .CreateWaiter(test::GetOobeElementPath(
                        {"gaia-password-changed", "oldPasswordInput"}) +
                    ".invalid")
      ->Wait();
  test::OobeJS().ExpectEnabledPath(
      {"gaia-password-changed", "oldPasswordCard"});

  EXPECT_EQ(StubAuthenticator::DataRecoveryStatus::kRecoveryFailed,
            data_recovery_status_);

  data_recovery_status_ = StubAuthenticator::DataRecoveryStatus::kNone;

  // Submit the correct password.
  test::OobeJS().TypeIntoPath("old user password",
                              {"gaia-password-changed", "oldPasswordInput"});
  test::OobeJS().ClickOnPath(
      {"gaia-password-changed", "oldPasswordInputForm", "button"});

  // User session should start, and whole OOBE screen is expected to be hidden,
  OobeWindowVisibilityWaiter(false).Wait();
  EXPECT_EQ(StubAuthenticator::DataRecoveryStatus::kRecovered,
            data_recovery_status_);

  SessionStartWaiter().Wait();
}

IN_PROC_BROWSER_TEST_F(PasswordChangeTest, SkipDataRecovery) {
  SetUpStubAuthentcatorAndAttemptLogin("old user password");
  WaitForPasswordChangeScreen();
  test::OobeJS()
      .CreateVisibilityWaiter(true,
                              {"gaia-password-changed", "oldPasswordCard"})
      ->Wait();

  // Click forgot password link.
  test::OobeJS().ClickOnPath({"gaia-password-changed", "forgot-password-link"});

  test::OobeJS()
      .CreateDisplayedWaiter(false,
                             {"gaia-password-changed", "oldPasswordCard"})
      ->Wait();

  test::OobeJS().ExpectVisiblePath({"gaia-password-changed", "try-again-link"});
  test::OobeJS().ExpectVisiblePath(
      {"gaia-password-changed", "proceedAnywayBtn"});

  // Click "Proceed anyway".
  test::OobeJS().ClickOnPath({"gaia-password-changed", "proceedAnywayBtn"});

  // User session should start, and whole OOBE screen is expected to be hidden,
  OobeWindowVisibilityWaiter(false).Wait();
  EXPECT_EQ(StubAuthenticator::DataRecoveryStatus::kResynced,
            data_recovery_status_);

  SessionStartWaiter().Wait();
}

IN_PROC_BROWSER_TEST_F(PasswordChangeTest, TryAgainAfterForgetLinkClick) {
  SetUpStubAuthentcatorAndAttemptLogin("old user password");
  WaitForPasswordChangeScreen();
  test::OobeJS()
      .CreateDisplayedWaiter(true, {"gaia-password-changed", "oldPasswordCard"})
      ->Wait();

  // Click forgot password link.
  test::OobeJS().ClickOnPath({"gaia-password-changed", "forgot-password-link"});

  test::OobeJS()
      .CreateDisplayedWaiter(false,
                             {"gaia-password-changed", "oldPasswordCard"})
      ->Wait();

  test::OobeJS().ExpectVisiblePath({"gaia-password-changed", "try-again-link"});
  test::OobeJS().ExpectVisiblePath(
      {"gaia-password-changed", "proceedAnywayBtn"});

  // Go back to old password input by clicking Try Again.
  test::OobeJS().ClickOnPath({"gaia-password-changed", "try-again-link"});

  test::OobeJS()
      .CreateDisplayedWaiter(true, {"gaia-password-changed", "oldPasswordCard"})
      ->Wait();

  // Enter and submit the correct password.
  test::OobeJS().TypeIntoPath("old user password",
                              {"gaia-password-changed", "oldPasswordInput"});
  test::OobeJS().ClickOnPath(
      {"gaia-password-changed", "oldPasswordInputForm", "button"});

  // User session should start, and whole OOBE screen is expected to be hidden,
  OobeWindowVisibilityWaiter(false).Wait();
  EXPECT_EQ(StubAuthenticator::DataRecoveryStatus::kRecovered,
            data_recovery_status_);

  SessionStartWaiter().Wait();
}

IN_PROC_BROWSER_TEST_F(PasswordChangeTest, ClosePasswordChangedDialog) {
  SetUpStubAuthentcatorAndAttemptLogin("old user password");
  WaitForPasswordChangeScreen();
  test::OobeJS()
      .CreateVisibilityWaiter(true,
                              {"gaia-password-changed", "oldPasswordCard"})
      ->Wait();

  test::OobeJS().TypeIntoPath("old user password",
                              {"gaia-password-changed", "oldPasswordInput"});
  // Click the close button.
  test::OobeJS().ClickOnPath(
      {"gaia-password-changed", "navigation", "closeButton"});

  OobeWindowVisibilityWaiter(false).Wait();
  EXPECT_EQ(StubAuthenticator::DataRecoveryStatus::kNone,
            data_recovery_status_);

  ExistingUserController::current_controller()->Login(GetTestUserContext(),
                                                      SigninSpecifics());
  OobeWindowVisibilityWaiter(true).Wait();
  OobeScreenWaiter(OobeScreen::SCREEN_PASSWORD_CHANGED).Wait();
}

}  // namespace chromeos


text:
static int hourlyWage;

@implementation Settings
+(int)hourlyWage {return hourlyWage;}

+(void)setHourlyWage: (int) wage{
    hourlyWage = wage;
}

@end


text:
<?php

namespace PSX\Framework\Tests\Loader\LocationFinder;

use PHPUnit\Framework\TestCase;
use PSX\Framework\Loader\Context;
use PSX\Framework\Loader\LocationFinder\RoutingParser;
use PSX\Framework\Loader\RoutingParser\PhpFile;
use PSX\Http\Request;
use PSX\Uri\Uri;

/**
 * RoutingParserTest
 *
 * @author  Christoph Kappestein <christoph.kappestein@gmail.com>
 * @license http://www.apache.org/licenses/LICENSE-2.0
 * @link    http://phpsx.org
 */
class RoutingParserTest extends TestCase
{
    public function testNormalRoute()
    {
        $context = $this->resolve('GET', '');
        $this->assertEquals('PSX\Framework\Loader\Foo1Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());

        $context = $this->resolve('GET', '/');
        $this->assertEquals('PSX\Framework\Loader\Foo1Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());

        $context = $this->resolve('GET', '/foo/bar');
        $this->assertEquals('PSX\Framework\Loader\Foo2Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());

        $context = $this->resolve('GET', '/foo/test');
        $this->assertEquals('PSX\Framework\Loader\Foo3Controller', $context->getSource());
        $this->assertEquals(['bar' => 'test'], $context->getParameters());

        $context = $this->resolve('GET', '/foo/test/bar');
        $this->assertEquals('PSX\Framework\Loader\Foo4Controller', $context->getSource());
        $this->assertEquals(['bar' => 'test', 'foo' => 'bar'], $context->getParameters());

        $context = $this->resolve('GET', '/bar');
        $this->assertEquals('PSX\Framework\Loader\Foo5Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());

        $context = $this->resolve('GET', '/bar/foo');
        $this->assertEquals('PSX\Framework\Loader\Foo6Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());

        $context = $this->resolve('GET', '/bar/14');
        $this->assertEquals('PSX\Framework\Loader\Foo7Controller', $context->getSource());
        $this->assertEquals(['foo' => '14'], $context->getParameters());

        $context = $this->resolve('GET', '/bar/14/16');
        $this->assertEquals('PSX\Framework\Loader\Foo8Controller', $context->getSource());
        $this->assertEquals(['foo' => '14', 'bar' => '16'], $context->getParameters());

        $context = $this->resolve('POST', '/bar');
        $this->assertEquals('PSX\Framework\Loader\Foo9Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());

        $context = $this->resolve('GET', '/whitespace');
        $this->assertEquals('PSX\Framework\Loader\Foo10Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());

        $context = $this->resolve('GET', '/alias');
        $this->assertEquals('PSX\Framework\Loader\Foo2Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());

        $context = $this->resolve('GET', '/files/foo/bar/foo.htm');
        $this->assertEquals('PSX\Framework\Loader\Foo12Controller', $context->getSource());
        $this->assertEquals(['path' => 'foo/bar/foo.htm'], $context->getParameters());

        // we can not resolve controller Foo13Controller since it has a static
        // url this is only useful for the reverse router

        $context = $this->resolve('GET', '/baz');
        $this->assertEquals('PSX\Framework\Loader\Foo14Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());

        $context = $this->resolve('PATCH', '/baz');
        $this->assertEquals('PSX\Framework\Loader\Foo14Controller', $context->getSource());
        $this->assertEquals([], $context->getParameters());
    }

    public function testInvalidRoute()
    {
        $context = $this->resolve('/foo/baz', 'GET');

        $this->assertEquals(null, $context->getSource());
        $this->assertEquals([], $context->getParameters());
    }

    public function testRegexpRoute()
    {
        $context = $this->resolve('GET', '/bar/foo/16');

        $this->assertEquals(null, $context->getSource());
        $this->assertEquals([], $context->getParameters());
    }

    protected function resolve(string $method, string $path)
    {
        $context = new Context();
        $request = new Request(new Uri($path), $method);

        $locationFinder = new RoutingParser(new PhpFile(__DIR__ . '/../routes.php'));
        $locationFinder->resolve($request, $context);

        return $context;
    }
}


text:
package ru.stqa.pft.addressbook.model;

import com.google.gson.annotations.Expose;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
import org.hibernate.annotations.Type;
import ru.stqa.pft.addressbook.tests.TestBase;

import javax.persistence.*;
import java.io.File;
import java.util.HashSet;
import java.util.Set;

@XStreamAlias("contact")
@Entity
@Table (name = "addressbook")
public class ContactData {
  @Expose
  @Column(name = "firstname")
  private String firstname;
  @Expose
  @Column(name = "lastname")
  private String lastname;

  @Expose
  @Column(name = "email")
  @Type(type = "text")

  private String email;
  @Expose
  @Column(name = "home")
  @Type(type = "text")
  private String phoneHome;
  @Expose
  @Type(type = "text")
  @Column(name = "mobile")
  private String phoneMobile;
  @Expose
  @Type(type = "text")
  @Column(name = "work")
  private String phoneWork;
  @Expose
  @Transient
  private String allPhones;
  @Expose
  @Column(name = "email2")
  @Type(type = "text")
  private String email2;
  @Expose
  @Column(name = "email3")
  @Type(type = "text")
  private String email3;
  @Expose
  @Transient
  private String allEmails;
  @Transient
  @Expose
  private String allName;
  @Column(name = "photo")
  @Type(type = "text")
  private String photo;
  @Expose
  @Column(name = "address")
  @Type(type = "text")
  private String address;

  @Override
  public String toString() {
    return "ContactData{" +
            "firstname='" + firstname + '\'' +
            ", lastname='" + lastname + '\'' +
            ", id=" + id +
            '}';
  }

  @XStreamOmitField
  @ManyToMany (fetch = FetchType.EAGER)
  @JoinTable(name = "address_in_groups",
          joinColumns = @JoinColumn (name = "id"), inverseJoinColumns = @JoinColumn (name = "group_id"))
  private Set<GroupData> groups = new HashSet<GroupData>();

  @XStreamOmitField
  @Id
  @Column(name = "id")
  private int id = Integer.MAX_VALUE;

  public Groups getGroups() {
    return new Groups(groups);
  }
  public String getFirstname() {
    return firstname;
  }

  public String getLastname() {
    return lastname;
  }

  public String getEmail() {
    return email;
  }

  public String getPhoneHome() {
    return phoneHome;
  }

  public String getPhoneMobile() {
    return phoneMobile;
  }

  public String getPhoneWork() {
    return phoneWork;
  }

  public String getEmail2() {
    return email2;
  }

  public String getEmail3() {
    return email3;
  }

  public String getAllEmails() {
    return allEmails;
  }

  public String getAddress() {
    return address;
  }

  public String getAllPhone() {
    return allPhones;
  }

  public String getAllName() {
    return allName;
  }

  public int getId() {
    return id;
  }

  public File getPhoto() {
    return new File(photo);
  }

  public ContactData inGroup(GroupData group) {
    groups.add(group);
    return this;
  }

  public ContactData withId(int id) {
    this.id = id;
    return this;
  }

  public ContactData withFirstname(String firstname) {
    this.firstname = firstname;
    return this;
  }

  public ContactData withLastname(String lastname) {
    this.lastname = lastname;
    return this;
  }

  public ContactData withEmail(String email) {
    this.email = email;
    return this;
  }

  public ContactData withAllPhone(String allPhones) {
    this.allPhones = allPhones;
    return this;
  }

  public ContactData withPhoneHome(String phoneHome) {
    this.phoneHome = phoneHome;
    return this;
  }

  public ContactData withPhoneWork(String phoneWork) {
    this.phoneWork = phoneWork;
    return this;
  }

  public ContactData withPhoneMobile(String phoneMobile) {
    this.phoneMobile = phoneMobile;
    return this;
  }

  public ContactData withEmail2(String email2) {
    this.email2 = email2;
    return this;
  }

  public ContactData withEmail3(String email3) {
    this.email3 = email3;
    return this;
  }

  public ContactData withAllEmails(String allEmails) {
    this.allEmails = allEmails;
    return this;
  }

  public ContactData withAllName(String allName) {
    this.allName = allName;
    return this;
  }

  public ContactData withPhoto(File photo) {
    this.photo = photo.getPath();
    return this;
  }

  public ContactData withAddress(String address) {
    this.address = address;
    return this;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    ContactData that = (ContactData) o;

    if (id != that.id) return false;
    if (firstname != null ? !firstname.equals(that.firstname) : that.firstname != null) return false;
    if (lastname != null ? !lastname.equals(that.lastname) : that.lastname != null) return false;
    if (email != null ? !email.equals(that.email) : that.email != null) return false;
    if (phoneHome != null ? !phoneHome.equals(that.phoneHome) : that.phoneHome != null) return false;
    if (phoneMobile != null ? !phoneMobile.equals(that.phoneMobile) : that.phoneMobile != null) return false;
    if (phoneWork != null ? !phoneWork.equals(that.phoneWork) : that.phoneWork != null) return false;
    if (email2 != null ? !email2.equals(that.email2) : that.email2 != null) return false;
    if (email3 != null ? !email3.equals(that.email3) : that.email3 != null) return false;
    return address != null ? address.equals(that.address) : that.address == null;
  }

  @Override
  public int hashCode() {
    int result = firstname != null ? firstname.hashCode() : 0;
    result = 31 * result + (lastname != null ? lastname.hashCode() : 0);
    result = 31 * result + (email != null ? email.hashCode() : 0);
    result = 31 * result + (phoneHome != null ? phoneHome.hashCode() : 0);
    result = 31 * result + (phoneMobile != null ? phoneMobile.hashCode() : 0);
    result = 31 * result + (phoneWork != null ? phoneWork.hashCode() : 0);
    result = 31 * result + (email2 != null ? email2.hashCode() : 0);
    result = 31 * result + (email3 != null ? email3.hashCode() : 0);
    result = 31 * result + (address != null ? address.hashCode() : 0);
    result = 31 * result + id;
    return result;
  }

}


text:
class QPainter;
class QPainterPath;
class QPolygonF;
class QPointF;

class CQFillTexture : public QObject {
 public:
  enum class FillType {
    NONE,
    FILL,
    HATCH,
    CROSS_HATCH,
    ZIG_ZAG,
    DOTS,
    HEXAGONS,
    CROSSES,
    CAPS,
    WOVEN,
    WAVES,
    NYLON,
    SQUARES
  };

  enum class ShapeType {
    NONE     = int(FillType::NONE),
    DOTS     = int(FillType::DOTS),
    HEXAGONS = int(FillType::HEXAGONS),
    CROSSES  = int(FillType::CROSSES),
    CAPS     = int(FillType::CAPS),
    WOVEN    = int(FillType::WOVEN),
    WAVES    = int(FillType::WAVES),
    NYLON    = int(FillType::NYLON),
    SQUARES  = int(FillType::SQUARES)
  };

 public:
  CQFillTexture();

  //---

  const FillType &fillType() const { return fillData_.fillType; }
  void setFillType(const FillType &t) { fillData_.fillType = t; }

  double width() const { return fillData_.width; }
  void setWidth(double r) { fillData_.width = r; }

  double delta() const { return fillData_.delta; }
  void setDelta(double r) { fillData_.delta = r; }

  double angle() const { return fillData_.angle; }
  void setAngle(double r) { fillData_.angle = r; }

  double radius() const { return fillData_.radius; }
  void setRadius(double r) { fillData_.radius = r; }

  const QColor &bgColor() const { return fillData_.bgColor; }
  void setBgColor(const QColor &c) { fillData_.bgColor = c; }

  const QColor &fgColor() const { return fillData_.fgColor; }
  void setFgColor(const QColor &c) { fillData_.fgColor = c; }

  const QColor &altColor() const { return fillData_.altColor; }
  void setAltColor(const QColor &c) { fillData_.altColor = c; }

  bool isFilled() const { return fillData_.filled; }
  void setFilled(bool b) { fillData_.filled = b; }

  bool isStroked() const { return fillData_.stroked; }
  void setStroked(bool b) { fillData_.stroked = b; }

  bool isBgFilled() const { return fillData_.bgFilled; }
  void setBgFilled(bool b) { fillData_.bgFilled = b; }

  //---

  void fillPath(QPainter *painter, const QPainterPath &path);
  void fillRect(QPainter *painter, const QRectF &rect);
  void fillPolygon(QPainter *painter, const QPolygonF &poly);

  //---

  QString toString() const;

 private:
  struct FillData {
    FillType  fillType  { FillType::FILL };
    double    width     { 4.0 };
    double    delta     { 0.0 };
    double    angle     { 0.0 };
    double    radius    { 16 };
    bool      filled    { true };
    bool      stroked   { true };
    bool      bgFilled  { true };
    bool      connect   { false };
    ShapeType shapeType { ShapeType::NONE };
    QColor    bgColor   { Qt::white };
    QColor    fgColor   { Qt::black };
    QColor    altColor;
    int       lineNum   { 0 };
    int       cellNum   { 0 };
  };

 private:
  void hatchFillPolygon(QPainter *painter, const QPolygonF &poly, const FillData &fillData);

  void fillHexagons(QPainter *painter, const QPolygonF &poly, const FillData &fillData);

  void drawLine(QPainter *painter, const QPointF &p1, const QPointF &p2, double width);

  void fillHexagon(QPainter *painter, const QPointF &center, double r, const FillData &fillData);

  void drawWoven(QPainter *painter, const QPointF &center, double r, const FillData &fillData);
  void drawNylon(QPainter *painter, const QPointF &center, double r, const FillData &fillData);

  void moveFillShapePath(QPainter *painter, const QPainterPath &path,
                         const QPointF &center, const FillData &fillData);
  void moveDrawShapePath(QPainter *painter, const QPainterPath &path,
                         const QPointF &center, const FillData &fillData);
  void drawShapePath(QPainter *painter, const QPainterPath &path, double width);

  void circlePath(double r, QPainterPath &path) const;
  void crossPath (double r, double angle, QPainterPath &path) const;
  void capPath   (double r, double angle, QPainterPath &path) const;
  void wavePath  (double r, double angle, QPainterPath &path) const;
  void nylonPath (double r, double angle, QPainterPath &path) const;
  void wovenPath (double r, double angle, QPainterPath &path) const;
  void squarePath(double r, double angle, QPainterPath &path) const;

  QPainterPath movePath  (const QPainterPath &path, const QPointF &c) const;
  QPainterPath rotatePath(const QPainterPath &path, const QPointF &c, double angle) const;

 private:
  FillData fillData_;
};

#endif


text:
package org.elasticsearch.index.mapper;

import org.apache.lucene.index.IndexableField;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.ParseContext.Document;
import org.elasticsearch.test.ESSingleNodeTestCase;

import static org.elasticsearch.test.StreamsUtils.copyToBytesFromClasspath;
import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath;
import static org.hamcrest.Matchers.equalTo;

public class GenericStoreDynamicTemplateTests extends ESSingleNodeTestCase {
    public void testSimple() throws Exception {
        String mapping = copyToStringFromClasspath("/org/elasticsearch/index/mapper/dynamictemplate/genericstore/test-mapping.json");
        IndexService index = createIndex("test");
        client().admin().indices().preparePutMapping("test").setType("person").setSource(mapping, XContentType.JSON).get();

        MapperService mapperService = index.mapperService();

        byte[] json = copyToBytesFromClasspath("/org/elasticsearch/index/mapper/dynamictemplate/genericstore/test-data.json");
        ParsedDocument parsedDoc = mapperService.documentMapper().parse(
            SourceToParse.source("test", "person", "1", new BytesArray(json), XContentType.JSON));
        client().admin().indices().preparePutMapping("test").setType("person")
            .setSource(parsedDoc.dynamicMappingsUpdate().toString(), XContentType.JSON).get();
        Document doc = parsedDoc.rootDoc();

        IndexableField f = doc.getField("name");
        assertThat(f.name(), equalTo("name"));
        assertThat(f.stringValue(), equalTo("some name"));
        assertThat(f.fieldType().stored(), equalTo(true));

        MappedFieldType fieldType = mapperService.fullName("name");
        assertThat(fieldType.stored(), equalTo(true));

        boolean stored = false;
        for (IndexableField field : doc.getFields("age")) {
            stored |=  field.fieldType().stored();
        }
        assertTrue(stored);

        fieldType = mapperService.fullName("age");
        assertThat(fieldType.stored(), equalTo(true));
    }
}


text:
def get_context(context):
	# do your magic here
	pass


text:
package com.mateuszkoslacz.moviper.tests.rules;

import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

import io.reactivex.android.plugins.RxAndroidPlugins;
import io.reactivex.schedulers.Schedulers;

/**
 * This rule registers SchedulerHooks for RxJava and RxAndroid to ensure that subscriptions always
 * subscribeOn and observeOn Schedulers.immediate(). Warning, this rule will reset RxAndroidPlugins
 * and RxJavaPlugins before and after each test so if the application code uses RxJava plugins this
 * may affect the behaviour of the testing method.
 */
public class RxAndroidSchedulersOverrideRule implements TestRule {

    @Override
    public Statement apply(final Statement base, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                RxAndroidPlugins.setInitMainThreadSchedulerHandler(__ -> Schedulers.trampoline());
                base.evaluate();
            }
        };
    }
}


text:
 File Upload

Select files from your computer

				          <form action="" method="post" enctype="multipart/form-data" class="js-upload-form" id="js-upload-form">

						              		Browse...
							                <input type="file" name="resultFiles" id="js-upload-files">

								      <input class="typeahead combobox form-control project" name="project" type="text" placeholder="project">

								        <button class="btn btn-default emu-select" type="button"></button>

								      <input class="typeahead combobox form-control version" name="version" type="text" placeholder="version">

								        <button class="btn btn-default emu-select" type="button"></button>

								      <input class="typeahead combobox form-control build" name="build" type="text" placeholder="build">

								        <button class="btn btn-default emu-select" type="button"></button>

				              <button type="submit" class="btn btn-sm btn-primary" id="js-upload-submit">Upload files</button>
				              <button type=reset class="btn btn-sm btn-secondary" id="js-upload-reset">clear</button>

				          </form>

Selected files

				            	nothing selected

Or drag and drop files below

				            Just drag and drop files here


text:
function fileInfo = rtbResolveFilePath(fileName, rootFolder)
%% Resolve a path to the given file.
%
% fileInfo = rtbResolveFilePath(fileName, rootFolder)
%
% Searches for the given fileName, which might be a plain file name, or
% a relative or absolute path to a file.  First searches within the given
% rootFolder and its subfolders for a file that matches fileName.  If no
% match is found within rootFolder, searches for a matching file on the
% Matlab path.
%
% Returns a struct of info about the given fileName, with the following
% fields:
%   - verbatimName - fileName exactly as given
%   - rootFolder - rootFolder exactly as given
%   - isRootFolderMatch - true only if fileName was found within rootFolder
%   - resolvedPath - unambiguous path to the given fileName
%   - absolutePath - full absolute path to the given fileName, if found
%
% resolvedPath will be an unambiguous path to the first file that
% matches fileName.   If the match was found within rootFolder,
% resolvedPath is the relative path to the matched file, starting from
% rootFolder.  If the match was found on the Matlab path, but not in
% rootFolder, resolvedPath is the full absolute path to the matched
% file.  If no match was found, resolvedPath is the empty string ''.
%
% In all cases isRootFolderMatch indicates whether or not a match was
% found within rootFolder.  When isRootFolderMatch is true, resolvedPath
% should be treated as a relative path.
%
%%% RenderToolbox4 Copyright (c) 2012-2016 The RenderToolbox Team.
%%% About Us://github.com/RenderToolbox/RenderToolbox4/wiki/About-Us
%%% RenderToolbox4 is released under the MIT License.  See LICENSE file.

parser = inputParser();
parser.addRequired('fileName', @ischar);
parser.addRequired('rootFolder', @ischar);
parser.parse(fileName, rootFolder);
fileName = parser.Results.fileName;
rootFolder = parser.Results.rootFolder;

blank = {[]};
fileInfo = struct( ...
    'verbatimName', blank, ...
    'rootFolder', blank, ...
    'isRootFolderMatch', blank, ...
    'resolvedPath', blank, ...
    'absolutePath', blank);

% basic info as given
fileInfo(1).verbatimName = fileName;
fileInfo(1).rootFolder = rootFolder;

% given a path relative to workingFolder?
rootRelative = fullfile(rootFolder, fileName);
if exist(rootRelative, 'file')
    fileInfo(1).absolutePath = rootRelative;
    [fileInfo(1).isRootFolderMatch, fileInfo(1).resolvedPath] = ...
        checkRootPath(rootRelative, rootFolder);
    return;
end

% given a plain file within workingFolder?
if 7 == exist(rootFolder, 'dir')
    matches = rtbFindFiles('root', rootFolder, ...
        'filter', fileName, ...
        'exactMatch', true);
    if ~isempty(matches)
        fileInfo(1).absolutePath = matches{1};
        [fileInfo(1).isRootFolderMatch, fileInfo(1).resolvedPath] = ...
            checkRootPath(matches{1}, rootFolder);
        return;
    end
end

% given a path relative to pwd()?
pwdRelative = fullfile(pwd(), fileName);
if exist(pwdRelative, 'file')
    fileInfo(1).absolutePath = pwdRelative;
    [fileInfo(1).isRootFolderMatch, fileInfo(1).resolvedPath] = ...
        checkRootPath(pwdRelative, rootFolder);
    return;
end

% given an absolute path or a plain file on the Matlab path?
whichFile = which(fileName);
if ~isempty(whichFile)
    fileInfo(1).absolutePath = whichFile;
    [fileInfo(1).isRootFolderMatch, fileInfo(1).resolvedPath] = ...
        checkRootPath(whichFile, rootFolder);
    return;
end

% file doesn't seem to exist, but try to resolve it based on syntax alone
[matchesRoot, resolvedPath] = checkRootPath(fileName, rootFolder);
if matchesRoot
    fileInfo(1).absolutePath = fullfile(rootFolder, fileName);
    fileInfo(1).isRootFolderMatch = true;
    fileInfo(1).resolvedPath = resolvedPath;
else
    fileInfo(1).absolutePath = '';
    fileInfo(1).isRootFolderMatch = false;
    fileInfo(1).resolvedPath = '';
end

%% Get relative path from rootFolder, if any.
function [isPrefix, resolvedPath] = checkRootPath(path, rootFolder)
[isPrefix, relativePath] = rtbIsPathPrefix(rootFolder, path);
if isPrefix
    resolvedPath = relativePath;
else
    resolvedPath = path;
end


text:
module OVIRT
  class Template < BaseObject
    attr_reader :description, :status, :cluster, :creation_time, :os, :storage, :display, :profile, :memory

    def initialize(client, xml)
      super(client, xml[:id], xml[:href], (xml/'name').first.text)
      parse_xml_attributes!(xml)
      self
    end

    def self.to_xml(opts={})
      builder = Nokogiri::XML::Builder.new do
        template_ {
          name_ opts[:name] || "t-#{Time.now.to_i}"
          description opts[:description] || ''
          vm(:id => opts[:vm])
        }
      end
      Nokogiri::XML(builder.to_xml).root.to_s
    end

    def interfaces
      @interfaces ||= @client.template_interfaces(id)
    end

    def volumes
      @volumes ||= @client.send(:volumes, "/templates/%s/disks" % id)
    end

    private
    def parse_xml_attributes!(xml)
      @description = ((xml/'description').first.text rescue '')
      @status = ((xml/'status').first.text rescue 'unknown')
      @memory = (xml/'memory').first.text
      @profile = (xml/'type').first.text
      @cluster = Link::new(@client, (xml/'cluster').first[:id], (xml/'cluster').first[:href])
      @display = {
        :type => (xml/'display/type').first.text,
        :monitors => (xml/'display/monitors').first.text
      }
      @cores = ((xml/'cpu/topology').first[:cores].to_i * (xml/'cpu/topology').first[:sockets].to_i rescue nil)
      @storage = ((xml/'disks/disk/size').first.text rescue nil)
      @creation_time = (xml/'creation_time').text
      @os = {
          :type => (xml/'os').first[:type],
          :boot => (xml/'os/boot').collect {|boot| boot[:dev] }
      }
    end
  end
end


text:
package com.pushtorefresh.storio.sample.db.resolvers;

import android.database.Cursor;
import android.support.annotation.NonNull;

import com.pushtorefresh.storio.sample.db.entities.Tweet;
import com.pushtorefresh.storio.sample.db.entities.User;
import com.pushtorefresh.storio.sample.db.entities.UserWithTweets;
import com.pushtorefresh.storio.sample.db.tables.TweetsTable;
import com.pushtorefresh.storio.sqlite.StorIOSQLite;
import com.pushtorefresh.storio.sqlite.operations.get.GetResolver;
import com.pushtorefresh.storio.sqlite.queries.Query;
import com.pushtorefresh.storio.sqlite.queries.RawQuery;

import java.util.List;

public final class UserWithTweetsGetResolver extends GetResolver<UserWithTweets> {

    // We can even reuse existing get resolvers for our needs
    // But, you can always write custom code, of course.
    @NonNull
    private final GetResolver<User> userGetResolver;

    // Sorry for this hack :(
    // We will pass you an instance of StorIO
    // into the mapFromCursor() in v2.0.0.
    //
    // At the moment, you can save this instance in performGet() and then null it at the end
    @NonNull
    private final ThreadLocal<StorIOSQLite> storIOSQLiteFromPerformGet = new ThreadLocal<StorIOSQLite>();

    public UserWithTweetsGetResolver(@NonNull GetResolver<User> userGetResolver) {
        this.userGetResolver = userGetResolver;
    }

    @NonNull
    @Override
    public UserWithTweets mapFromCursor(@NonNull Cursor cursor) {
        final StorIOSQLite storIOSQLite = storIOSQLiteFromPerformGet.get();

        // Or you can manually parse cursor (it will be sliiightly faster)
        final User user = userGetResolver.mapFromCursor(cursor);

        // Yep, you can reuse StorIO here!
        // Or, you can do manual low level requests here
        // BTW, if you profiled your app and found that such queries are not very fast
        // You can always add some optimized version for particular queries to improve the performance
        final List<Tweet> tweetsOfTheUser = storIOSQLite
                .get()
                .listOfObjects(Tweet.class)
                .withQuery(Query.builder()
                        .table(TweetsTable.TABLE)
                        .where(TweetsTable.COLUMN_AUTHOR + "=?")
                        .whereArgs(user.nick())
                        .build())
                .prepare()
                .executeAsBlocking();

        return new UserWithTweets(user, tweetsOfTheUser);
    }

    @NonNull
    @Override
    public Cursor performGet(@NonNull StorIOSQLite storIOSQLite, @NonNull RawQuery rawQuery) {
        storIOSQLiteFromPerformGet.set(storIOSQLite);
        return storIOSQLite.internal().rawQuery(rawQuery);
    }

    @NonNull
    @Override
    public Cursor performGet(@NonNull StorIOSQLite storIOSQLite, @NonNull Query query) {
        storIOSQLiteFromPerformGet.set(storIOSQLite);
        return storIOSQLite.internal().query(query);
    }
}