<commit_before>namespace factor
{

struct must_start_gc_again {};

template<typename TargetGeneration, typename Policy> struct gc_workhorse : no_fixup {
	static const bool translated_code_block_map = false;

	factor_vm *parent;
	TargetGeneration *target;
	Policy policy;
	code_heap *code;

	explicit gc_workhorse(factor_vm *parent_, TargetGeneration *target_, Policy policy_) :
		parent(parent_),
		target(target_),
		policy(policy_),
		code(parent->code) {}

	object *resolve_forwarding(object *untagged)
	{
		parent->check_data_pointer(untagged);

		/* is there another forwarding pointer? */
		while(untagged->forwarding_pointer_p())
			untagged = untagged->forwarding_pointer();

		/* we've found the destination */
		return untagged;
	}

	object *promote_object(object *untagged)
	{
		cell size = untagged->size();
		object *newpointer = target->allot(size);
		if(!newpointer) throw must_start_gc_again();

		memcpy(newpointer,untagged,size);
		untagged->forward_to(newpointer);

		policy.promoted_object(newpointer);

		return newpointer;
	}

	object *fixup_data(object *obj)
	{
		parent->check_data_pointer(obj);

		if(!policy.should_copy_p(obj))
		{
			policy.visited_object(obj);
			return obj;
		}

		object *forwarding = resolve_forwarding(obj);

		if(forwarding == obj)
			return promote_object(obj);
		else if(policy.should_copy_p(forwarding))
			return promote_object(forwarding);
		else
		{
			policy.visited_object(forwarding);
			return forwarding;
		}
	}

	code_block *fixup_code(code_block *compiled)
	{
		if(!code->marked_p(compiled))
		{
			code->set_marked_p(compiled);
			parent->mark_stack.push_back((cell)compiled + 1);
		}

		return compiled;
	}
};

struct dummy_unmarker {
	void operator()(card *ptr) {}
};

struct simple_unmarker {
	card unmask;
	explicit simple_unmarker(card unmask_) : unmask(unmask_) {}
	void operator()(card *ptr) { *ptr &= ~unmask; }
};

struct full_unmarker {
	explicit full_unmarker() {}
	void operator()(card *ptr) { *ptr = 0; }
};

template<typename TargetGeneration, typename Policy>
struct collector {
	factor_vm *parent;
	data_heap *data;
	code_heap *code;
	TargetGeneration *target;
	gc_workhorse<TargetGeneration,Policy> workhorse;
	slot_visitor<gc_workhorse<TargetGeneration,Policy> > data_visitor;
	cell cards_scanned;
	cell decks_scanned;
	cell code_blocks_scanned;

	explicit collector(factor_vm *parent_, TargetGeneration *target_, Policy policy_) :
		parent(parent_),
		data(parent_->data),
		code(parent_->code),
		target(target_),
		workhorse(parent,target,policy_),
		data_visitor(parent,workhorse),
		cards_scanned(0),
		decks_scanned(0),
		code_blocks_scanned(0) {}

	void trace_handle(cell *handle)
	{
		data_visitor.visit_handle(handle);
	}

	void trace_object(object *ptr)
	{
		data_visitor.visit_slots(ptr);
		if(ptr->type() == ALIEN_TYPE)
			((alien *)ptr)->update_address();
	}

	void trace_roots()
	{
		data_visitor.visit_roots();
	}

	void trace_contexts()
	{
		data_visitor.visit_contexts();
	}

	void trace_code_block_objects(code_block *compiled)
	{
		data_visitor.visit_code_block_objects(compiled);
	}

	void trace_embedded_literals(code_block *compiled)
	{
		data_visitor.visit_embedded_literals(compiled);
	}

	void trace_code_heap_roots(std::set<code_block *> *remembered_set)
	{
		std::set<code_block *>::const_iterator iter = remembered_set->begin();
		std::set<code_block *>::const_iterator end = remembered_set->end();

		for(; iter != end; iter++)
		{
			code_block *compiled = *iter;
			trace_code_block_objects(compiled);
			trace_embedded_literals(compiled);
			compiled->flush_icache();
			code_blocks_scanned++;
		}
	}

	inline cell first_card_in_deck(cell deck)
	{
		return deck << (deck_bits - card_bits);
	}

	inline cell last_card_in_deck(cell deck)
	{
		return first_card_in_deck(deck + 1);
	}

	inline cell card_deck_for_address(cell a)
	{
		return addr_to_deck(a - data->start);
	}

	inline cell card_start_address(cell card)
	{
		return (card << card_bits) + data->start;
	}

	inline cell card_end_address(cell card)
	{
		return ((card + 1) << card_bits) + data->start;
	}

	void trace_partial_objects(cell start, cell end, cell card_start, cell card_end)
	{
		if(card_start < end)
		{
			start += sizeof(cell);

			if(start < card_start) start = card_start;
			if(end > card_end) end = card_end;

			cell *slot_ptr = (cell *)start;
			cell *end_ptr = (cell *)end;

			for(; slot_ptr < end_ptr; slot_ptr++)
				data_visitor.visit_handle(slot_ptr);
		}
	}

	template<typename SourceGeneration, typename Unmarker>
	void trace_cards(SourceGeneration *gen, card mask, Unmarker unmarker)
	{
		card_deck *decks = data->decks;
		card_deck *cards = data->cards;

		cell gen_start_card = addr_to_card(gen->start - data->start);

		cell first_deck = card_deck_for_address(gen->start);
		cell last_deck = card_deck_for_address(gen->end);

		cell start = 0, binary_start = 0, end = 0;

		for(cell deck_index = first_deck; deck_index < last_deck; deck_index++)
		{
			if(decks[deck_index] & mask)
			{
				decks_scanned++;

				cell first_card = first_card_in_deck(deck_index);
				cell last_card = last_card_in_deck(deck_index);

				for(cell card_index = first_card; card_index < last_card; card_index++)
				{
					if(cards[card_index] & mask)
					{
						cards_scanned++;

						if(end < card_start_address(card_index))
						{
							start = gen->starts.find_object_containing_card(card_index - gen_start_card);
							binary_start = start + ((object *)start)->binary_payload_start();
							end = start + ((object *)start)->size();
						}

scan_next_object:				if(start < card_end_address(card_index))
						{
							trace_partial_objects(
								start,
								binary_start,
								card_start_address(card_index),
								card_end_address(card_index));
							if(end < card_end_address(card_index))
							{
								start = gen->next_object_after(start);
								if(start)
								{
									binary_start = start + ((object *)start)->binary_payload_start();
									end = start + ((object *)start)->size();
									goto scan_next_object;
								}
							}
						}

						unmarker(&cards[card_index]);

						if(!start) return;
					}
				}

				unmarker(&decks[deck_index]);
			}
		}
	}
};

}
<commit_msg>VM: Refactor collector.hpp to Factor style<commit_after>namespace factor {

struct must_start_gc_again {
};

template <typename TargetGeneration, typename Policy>
struct gc_workhorse : no_fixup {
  static const bool translated_code_block_map = false;

  factor_vm* parent;
  TargetGeneration* target;
  Policy policy;
  code_heap* code;

  explicit gc_workhorse(factor_vm* parent_, TargetGeneration* target_,
                        Policy policy_)
      : parent(parent_), target(target_), policy(policy_), code(parent->code) {}

  object* resolve_forwarding(object* untagged) {
    parent->check_data_pointer(untagged);

    /* is there another forwarding pointer? */
    while (untagged->forwarding_pointer_p())
      untagged = untagged->forwarding_pointer();

    /* we've found the destination */
    return untagged;
  }

  object* promote_object(object* untagged) {
    cell size = untagged->size();
    object* newpointer = target->allot(size);
    if (!newpointer)
      throw must_start_gc_again();

    memcpy(newpointer, untagged, size);
    untagged->forward_to(newpointer);

    policy.promoted_object(newpointer);

    return newpointer;
  }

  object* fixup_data(object* obj) {
    parent->check_data_pointer(obj);

    if (!policy.should_copy_p(obj)) {
      policy.visited_object(obj);
      return obj;
    }

    object* forwarding = resolve_forwarding(obj);

    if (forwarding == obj)
      return promote_object(obj);
    else if (policy.should_copy_p(forwarding))
      return promote_object(forwarding);
    else {
      policy.visited_object(forwarding);
      return forwarding;
    }
  }

  code_block* fixup_code(code_block* compiled) {
    if (!code->marked_p(compiled)) {
      code->set_marked_p(compiled);
      parent->mark_stack.push_back((cell) compiled + 1);
    }

    return compiled;
  }
};

struct dummy_unmarker {
  void operator()(card* ptr) {}
};

struct simple_unmarker {
  card unmask;
  explicit simple_unmarker(card unmask_) : unmask(unmask_) {}
  void operator()(card* ptr) { *ptr &= ~unmask; }
};

struct full_unmarker {
  explicit full_unmarker() {}
  void operator()(card* ptr) { *ptr = 0; }
};

template <typename TargetGeneration, typename Policy> struct collector {
  factor_vm* parent;
  data_heap* data;
  code_heap* code;
  TargetGeneration* target;
  gc_workhorse<TargetGeneration, Policy> workhorse;
  slot_visitor<gc_workhorse<TargetGeneration, Policy> > data_visitor;
  cell cards_scanned;
  cell decks_scanned;
  cell code_blocks_scanned;

  explicit collector(factor_vm* parent_, TargetGeneration* target_,
                     Policy policy_)
      : parent(parent_),
        data(parent_->data),
        code(parent_->code),
        target(target_),
        workhorse(parent, target, policy_),
        data_visitor(parent, workhorse),
        cards_scanned(0),
        decks_scanned(0),
        code_blocks_scanned(0) {}

  void trace_handle(cell* handle) { data_visitor.visit_handle(handle); }

  void trace_object(object* ptr) {
    data_visitor.visit_slots(ptr);
    if (ptr->type() == ALIEN_TYPE)
      ((alien*)ptr)->update_address();
  }

  void trace_roots() { data_visitor.visit_roots(); }

  void trace_contexts() { data_visitor.visit_contexts(); }

  void trace_code_block_objects(code_block* compiled) {
    data_visitor.visit_code_block_objects(compiled);
  }

  void trace_embedded_literals(code_block* compiled) {
    data_visitor.visit_embedded_literals(compiled);
  }

  void trace_code_heap_roots(std::set<code_block*>* remembered_set) {
    std::set<code_block*>::const_iterator iter = remembered_set->begin();
    std::set<code_block*>::const_iterator end = remembered_set->end();

    for (; iter != end; iter++) {
      code_block* compiled = *iter;
      trace_code_block_objects(compiled);
      trace_embedded_literals(compiled);
      compiled->flush_icache();
      code_blocks_scanned++;
    }
  }

  inline cell first_card_in_deck(cell deck) {
    return deck << (deck_bits - card_bits);
  }

  inline cell last_card_in_deck(cell deck) {
    return first_card_in_deck(deck + 1);
  }

  inline cell card_deck_for_address(cell a) {
    return addr_to_deck(a - data->start);
  }

  inline cell card_start_address(cell card) {
    return (card << card_bits) + data->start;
  }

  inline cell card_end_address(cell card) {
    return ((card + 1) << card_bits) + data->start;
  }

  void trace_partial_objects(cell start, cell end, cell card_start,
                             cell card_end) {
    if (card_start < end) {
      start += sizeof(cell);

      if (start < card_start)
        start = card_start;
      if (end > card_end)
        end = card_end;

      cell* slot_ptr = (cell*)start;
      cell* end_ptr = (cell*)end;

      for (; slot_ptr < end_ptr; slot_ptr++)
        data_visitor.visit_handle(slot_ptr);
    }
  }

  template <typename SourceGeneration, typename Unmarker>
  void trace_cards(SourceGeneration* gen, card mask, Unmarker unmarker) {
    card_deck* decks = data->decks;
    card_deck* cards = data->cards;

    cell gen_start_card = addr_to_card(gen->start - data->start);

    cell first_deck = card_deck_for_address(gen->start);
    cell last_deck = card_deck_for_address(gen->end);

    cell start = 0, binary_start = 0, end = 0;

    for (cell deck_index = first_deck; deck_index < last_deck; deck_index++) {
      if (decks[deck_index] & mask) {
        decks_scanned++;

        cell first_card = first_card_in_deck(deck_index);
        cell last_card = last_card_in_deck(deck_index);

        for (cell card_index = first_card; card_index < last_card;
             card_index++) {
          if (cards[card_index] & mask) {
            cards_scanned++;

            if (end < card_start_address(card_index)) {
              start = gen->starts
                  .find_object_containing_card(card_index - gen_start_card);
              binary_start = start + ((object*)start)->binary_payload_start();
              end = start + ((object*)start)->size();
            }

          scan_next_object:
            if (start < card_end_address(card_index)) {
              trace_partial_objects(start, binary_start,
                                    card_start_address(card_index),
                                    card_end_address(card_index));
              if (end < card_end_address(card_index)) {
                start = gen->next_object_after(start);
                if (start) {
                  binary_start =
                      start + ((object*)start)->binary_payload_start();
                  end = start + ((object*)start)->size();
                  goto scan_next_object;
                }
              }
            }

            unmarker(&cards[card_index]);

            if (!start)
              return;
          }
        }

        unmarker(&decks[deck_index]);
      }
    }
  }
};

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: oinputstreamcontainer.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-10-13 11:27:22 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _OINPUTSTREAMCONTAINER_HXX_
#define _OINPUTSTREAMCONTAINER_HXX_

#ifndef _COM_SUN_STAR_IO_XINPUTSTREAM_HPP_
#include <com/sun/star/io/XInputStream.hpp>
#endif

#ifndef _COM_SUN_STAR_EMBED_XEXTENDEDSTORAGESTREAM_HPP_
#include <com/sun/star/embed/XExtendedStorageStream.hpp>
#endif

#ifndef _COM_SUN_STAR_IO_XSEEKABLE_HPP_
#include <com/sun/star/io/XSeekable.hpp>
#endif

#ifndef _CPPUHELPER_IMPLBASE2_HXX_
#include <cppuhelper/implbase2.hxx>
#endif
#ifndef _CPPUHELPER_INTERFACECONTAINER_H_
#include <cppuhelper/interfacecontainer.h>
#endif

#include <osl/mutex.hxx>

class OFSInputStreamContainer : public cppu::WeakImplHelper2 < ::com::sun::star::io::XInputStream
                                                            ,::com::sun::star::embed::XExtendedStorageStream >
                            , public ::com::sun::star::io::XSeekable
{
protected:
    ::osl::Mutex m_aMutex;

    ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > m_xInputStream;
    ::com::sun::star::uno::Reference < ::com::sun::star::io::XSeekable > m_xSeekable;

    sal_Bool m_bSeekable;

    sal_Bool m_bDisposed;

    ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners

public:
    OFSInputStreamContainer( const ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream >& xStream );

    virtual ~OFSInputStreamContainer();

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType ) throw( ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL acquire() throw();
    virtual void SAL_CALL release() throw();

    // XInputStream
    virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL available(  )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL closeInput(  )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    //XStream
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream(  ) throw (::com::sun::star::uno::RuntimeException);

    //XSeekable
    virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int64 SAL_CALL getPosition() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int64 SAL_CALL getLength() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    //XComponent
    virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);

};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.4.432); FILE MERGED 2008/04/01 15:45:08 thb 1.4.432.3: #i85898# Stripping all external header guards 2008/04/01 12:43:34 thb 1.4.432.2: #i85898# Stripping all external header guards 2008/03/31 13:02:03 rt 1.4.432.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: oinputstreamcontainer.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _OINPUTSTREAMCONTAINER_HXX_
#define _OINPUTSTREAMCONTAINER_HXX_

#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/embed/XExtendedStorageStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>

#include <cppuhelper/implbase2.hxx>
#include <cppuhelper/interfacecontainer.h>

#include <osl/mutex.hxx>

class OFSInputStreamContainer : public cppu::WeakImplHelper2 < ::com::sun::star::io::XInputStream
                                                            ,::com::sun::star::embed::XExtendedStorageStream >
                            , public ::com::sun::star::io::XSeekable
{
protected:
    ::osl::Mutex m_aMutex;

    ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream > m_xInputStream;
    ::com::sun::star::uno::Reference < ::com::sun::star::io::XSeekable > m_xSeekable;

    sal_Bool m_bSeekable;

    sal_Bool m_bDisposed;

    ::cppu::OInterfaceContainerHelper* m_pListenersContainer; // list of listeners

public:
    OFSInputStreamContainer( const ::com::sun::star::uno::Reference < ::com::sun::star::io::XInputStream >& xStream );

    virtual ~OFSInputStreamContainer();

    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& rType ) throw( ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL acquire() throw();
    virtual void SAL_CALL release() throw();

    // XInputStream
    virtual sal_Int32 SAL_CALL readBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nBytesToRead )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL readSomeBytes( ::com::sun::star::uno::Sequence< sal_Int8 >& aData, sal_Int32 nMaxBytesToRead )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int32 SAL_CALL available(  )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL closeInput(  )
        throw(::com::sun::star::io::NotConnectedException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    //XStream
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > SAL_CALL getInputStream(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > SAL_CALL getOutputStream(  ) throw (::com::sun::star::uno::RuntimeException);

    //XSeekable
    virtual void SAL_CALL seek( sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int64 SAL_CALL getPosition() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual sal_Int64 SAL_CALL getLength() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

    //XComponent
    virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException);

};

#endif

<|endoftext|>


<commit_before>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file     g_dfs_server_main.h
* @version
* @brief
* @author   duye
* @date     2014-09-28
* @note
*
*  1. 2014-09-28 duye Created this file
*
*/

#include <g_logger.h>
#include <g_system.h>
#include <g_dfs_server.h>

static const GInt8* LOG_PREFIX = "dfs.server.main";
static gsys::Condition exit_condition;
static const GUint32 exit_timeout = 10; // second

/**
 * @brief dfs server process monitor class
 */
class DfsServerProcessMonitorObserver : public gsys::ProcessMoniterInterface
{
public:
    DfsServerProcessMonitorObserver() {}
    ~DfsServerProcessMonitorObserver() {}

    /**
     * @brief handle system signal, when segmentation fault
     * @param [in] sig : signal
     * @note inherit from base class ProcessMoniterInterface
     */
    void onSegmentationFault(const GInt32 sig)
    {
        G_LOG_ERROR(LOG_PREFIX, "DFS server segmentation fault happened");
        G_LOG_INFO(LOG_PREFIX, "DFS server will stopped, waitting for exit");
        DfsServer::getInstance()->setState(SERVER_FAILED);
        if (!exit_condition.wait(exit_timeout))
        {
            G_LOG_ERROR(LOG_PREFIX, "DFS server can't normal exit, will force exit");
            G_LOG_WARN(LOG_PREFIX, "==============DFS server force exit===========");
        }
    }

    /**
     * @brief handle system signal, when ctrl+c
     * @param [in] sig : signal
     * @note inherit from base class ProcessMoniterInterface
     */
    void onCtrlC(const GInt32 sig)
    {
        G_LOG_INFO(LOG_PREFIX, "DFS server stop by ctrl + c");
        G_LOG_INFO(LOG_PREFIX, "DFS server will stopped, waitting for exit");
        DfsServer::getInstance()->setState(SERVER_STOP);
        if (!exit_condition.wait(exit_timeout))
        {
            G_LOG_ERROR(LOG_PREFIX, "DFS server can't normal exit, will force exit");
            G_LOG_WARN(LOG_PREFIX, "==============DFS server force exit==============");
        }
    }
}

int main()
{
    G_LOG_INIT();

    G_LOG_INFO(LOG_PREFIX, "==============DFS server startup===========");

    // process monitor
    DfsServerProcessMonitorObserver dfs_server_process_monitor_observer;
    gsys::ProcessMonitor process_monitor(&dfs_server_process_monitor_observer);

    if (IS_NO(DFSServer::getInstance()->start()))
    {
        G_LOG_ERROR(LOG_PREFIX, "DFS server startup fault");
        return -1;
    }

    while (DfsServer::getInstance()->getState() == SERVER_RUNNING)
    {
        gsys::gsystem::sleep(2);
    }

    DfsServer::getInstance()->stop();
    exit_condition.broadcast();

    G_LOG_INFO(LOG_PREFIX, "==============DFS server stopped===========");

    G_LOG_UNINIT();

    return 0;
}
<commit_msg>Update g_dfs_server_main.cpp<commit_after>/************************************************************************************
**
* @copyright (c) 2013-2100, ChengDu Duyer Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file     g_dfs_server_main.h
* @version
* @brief
* @author   duye
* @date     2014-09-28
* @note
*
*  1. 2014-09-28 duye Created this file
*
*/

#include <g_logger.h>
#include <g_system.h>
#include <g_dfs_server.h>

static const GInt8* LOG_PREFIX = "dfs.server.main";
static gsys::Condition exit_condition;
static const GUint32 exit_timeout = 10; // second

/**
 * @brief dfs server process monitor class
 */
class DfsServerProcessMonitorObserver : public gsys::ProcessMoniterInterface
{
public:
    DfsServerProcessMonitorObserver() {}
    ~DfsServerProcessMonitorObserver() {}

    /**
     * @brief handle system signal, when segmentation fault
     * @param [in] sig : signal
     * @note inherit from base class ProcessMoniterInterface
     */
    void onSegmentationFault(const GInt32 sig)
    {
        G_LOG_ERROR(LOG_PREFIX, "DFS server segmentation fault happened");
        G_LOG_INFO(LOG_PREFIX, "DFS server will stopped, waitting for exit");
        DfsServer::getInstance()->setState(SERVER_FAILED);
        if (!exit_condition.wait(exit_timeout))
        {
            G_LOG_ERROR(LOG_PREFIX, "DFS server can't normal exit, will force exit");
            G_LOG_WARN(LOG_PREFIX, "==============DFS server force exit===========");
        }
    }

    /**
     * @brief handle system signal, when ctrl+c
     * @param [in] sig : signal
     * @note inherit from base class ProcessMoniterInterface
     */
    void onCtrlC(const GInt32 sig)
    {
        G_LOG_INFO(LOG_PREFIX, "DFS server stop by ctrl + c");
        G_LOG_INFO(LOG_PREFIX, "DFS server will stopped, waitting for exit");
        DfsServer::getInstance()->setState(SERVER_STOP);
        if (!exit_condition.wait(exit_timeout))
        {
            G_LOG_ERROR(LOG_PREFIX, "DFS server can't normal exit, will force exit");
            G_LOG_WARN(LOG_PREFIX, "==============DFS server force exit==============");
        }
    }
}

int main(int argc, char** argv)
{
    G_LOG_INIT();

    G_LOG_INFO(LOG_PREFIX, "==============DFS server startup===========");

    // process monitor
    DfsServerProcessMonitorObserver dfs_server_process_monitor_observer;
    gsys::ProcessMonitor process_monitor(&dfs_server_process_monitor_observer);

    if (IS_NO(DFSServer::getInstance()->start()))
    {
        G_LOG_ERROR(LOG_PREFIX, "DFS server startup fault");
        return -1;
    }

    while (DfsServer::getInstance()->getState() == SERVER_RUNNING)
    {
        gsys::gsystem::sleep(2);
    }

    DfsServer::getInstance()->stop();
    exit_condition.broadcast();

    G_LOG_INFO(LOG_PREFIX, "==============DFS server stopped===========");

    G_LOG_UNINIT();

    return 0;
}
<|endoftext|>


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

#include "chrome/browser/chromeos/login/network_screen.h"

#include "app/l10n_util.h"
#include "base/utf_string_conversions.h"
#include "base/logging.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/login/network_selection_view.h"
#include "chrome/browser/chromeos/login/screen_observer.h"
#include "chrome/browser/chromeos/options/network_config_view.h"
#include "grit/generated_resources.h"
#include "views/widget/widget.h"
#include "views/window/window.h"

namespace chromeos {

///////////////////////////////////////////////////////////////////////////////
// NetworkScreen, public:

NetworkScreen::NetworkScreen(WizardScreenDelegate* delegate, bool is_out_of_box)
    : ViewScreen<NetworkSelectionView>(delegate),
      is_network_subscribed_(false),
      is_out_of_box_(is_out_of_box),
      ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
}

NetworkScreen::~NetworkScreen() {
  UnsubscribeNetworkNotification();
}

////////////////////////////////////////////////////////////////////////////////
// ComboboxModel implementation:

int NetworkScreen::GetItemCount() {
  // Item with index = 0 is either "no networks are available" or
  // "no selection".
  return static_cast<int>(networks_.GetNetworkCount()) + 1;
}

std::wstring NetworkScreen::GetItemAt(int index) {
  if (index == 0) {
    return networks_.IsEmpty() ?
        l10n_util::GetString(IDS_STATUSBAR_NO_NETWORKS_MESSAGE) :
        l10n_util::GetString(IDS_NETWORK_SELECTION_NONE);
  }
  NetworkList::NetworkItem* network =
      networks_.GetNetworkAt(index - 1);
  return network ? UTF16ToWide(network->label) : std::wstring();
}

////////////////////////////////////////////////////////////////////////////////
// views::Combobox::Listener implementation:

void NetworkScreen::ItemChanged(views::Combobox* sender,
                                int prev_index,
                                int new_index) {
  if (new_index == prev_index || new_index < 0 || prev_index < 0)
    return;

  if (networks_.IsEmpty())
    return;

  const NetworkList::NetworkItem* network =
      networks_.GetNetworkAt(new_index - 1);
  MessageLoop::current()->PostTask(FROM_HERE, task_factory_.NewRunnableMethod(
      &NetworkScreen::ConnectToNetwork, network->network_type, network->label));
}

///////////////////////////////////////////////////////////////////////////////
// views::ButtonListener implementation:

void NetworkScreen::ButtonPressed(views::Button* sender,
                                  const views::Event& event) {
  MessageLoop::current()->PostTask(FROM_HERE,
      task_factory_.NewRunnableMethod(&NetworkScreen::NotifyOnOffline));
}

////////////////////////////////////////////////////////////////////////////////
// NetworkLibrary::Observer implementation:

void NetworkScreen::NetworkChanged(NetworkLibrary* network_lib) {
  // Save network selection in case it would be available after refresh.
  NetworkList::NetworkType network_type = NetworkList::NETWORK_EMPTY;
  string16 network_id;
  const NetworkList::NetworkItem* selected_network = GetSelectedNetwork();
  if (selected_network) {
    network_type = selected_network->network_type;
    network_id = selected_network->label;
  }
  networks_.NetworkChanged(network_lib);
  // TODO(nkostylev): Check for connection error.
  // For initial out of box experience make sure that network was selected.
  if (networks_.ConnectedNetwork() &&
      (selected_network || !is_out_of_box_)) {
    MessageLoop::current()->PostTask(FROM_HERE,
        task_factory_.NewRunnableMethod(&NetworkScreen::NotifyOnConnection));
    return;
  }
  const NetworkList::NetworkItem* network = networks_.ConnectingNetwork();
  if (network &&
      (selected_network || !is_out_of_box_)) {
    view()->ShowConnectingStatus(true, network->label);
  }
  view()->NetworkModelChanged();
  SelectNetwork(network_type, network_id);
}

void NetworkScreen::NetworkTraffic(NetworkLibrary* cros,
                                   int traffic_type) {
}

///////////////////////////////////////////////////////////////////////////////
// NetworkScreen, ViewScreen implementation:

void NetworkScreen::CreateView() {
  language_switch_model_.InitLanguageMenu();
  ViewScreen<NetworkSelectionView>::CreateView();
}

NetworkSelectionView* NetworkScreen::AllocateView() {
  return new NetworkSelectionView(this);
}

////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, public:

void NetworkScreen::Refresh() {
  SubscribeNetworkNotification();
  NetworkChanged(chromeos::CrosLibrary::Get()->GetNetworkLibrary());
}

////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, private:

void NetworkScreen::ConnectToNetwork(NetworkList::NetworkType type,
                                     const string16& id) {
  const NetworkList::NetworkItem* network =
      networks_.GetNetworkById(type, id);
  if (network && !IsSameNetwork(network, networks_.ConnectedNetwork())) {
    if (NetworkList::NETWORK_WIFI == network->network_type) {
      if (network->wifi_network.encrypted()) {
        OpenPasswordDialog(network->wifi_network);
        return;
      } else {
        chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
            ConnectToWifiNetwork(network->wifi_network,
                                 string16(), string16(), string16());
      }
    } else if (NetworkList::NETWORK_CELLULAR == network->network_type) {
      chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
          ConnectToCellularNetwork(network->cellular_network);
    }
  }
  // Check if there's already connected network and update screen state.
  MessageLoop::current()->PostTask(FROM_HERE, task_factory_.NewRunnableMethod(
      &NetworkScreen::NetworkChanged,
      chromeos::CrosLibrary::Get()->GetNetworkLibrary()));
}

void NetworkScreen::SubscribeNetworkNotification() {
  if (!is_network_subscribed_) {
    is_network_subscribed_ = true;
    chromeos::CrosLibrary::Get()->GetNetworkLibrary()->AddObserver(this);
  }
}

void NetworkScreen::UnsubscribeNetworkNotification() {
  if (is_network_subscribed_) {
    is_network_subscribed_ = false;
    chromeos::CrosLibrary::Get()->GetNetworkLibrary()->RemoveObserver(this);
  }
}

NetworkList::NetworkItem* NetworkScreen::GetSelectedNetwork() {
  return networks_.GetNetworkAt(view()->GetSelectedNetworkItem() - 1);
}

bool NetworkScreen::IsSameNetwork(const NetworkList::NetworkItem* network1,
                                  const NetworkList::NetworkItem* network2) {
  return (network1 && network2 &&
          network1->network_type == network2->network_type &&
          network1->label == network2->label);
}

void NetworkScreen::NotifyOnConnection() {
  UnsubscribeNetworkNotification();
  delegate()->GetObserver(this)->OnExit(ScreenObserver::NETWORK_CONNECTED);
}

void NetworkScreen::NotifyOnOffline() {
  UnsubscribeNetworkNotification();
  delegate()->GetObserver(this)->OnExit(ScreenObserver::NETWORK_OFFLINE);
}

void NetworkScreen::OpenPasswordDialog(WifiNetwork network) {
  NetworkConfigView* dialog = new NetworkConfigView(network, true);
  dialog->set_browser_mode(false);
  views::Window* window = views::Window::CreateChromeWindow(
      view()->GetNativeWindow(), gfx::Rect(), dialog);
  window->SetIsAlwaysOnTop(true);
  window->Show();
  dialog->SetLoginTextfieldFocus();
}

void NetworkScreen::SelectNetwork(NetworkList::NetworkType type,
                                  const string16& id) {
  int index = networks_.GetNetworkIndexById(type, id);
  if (index >= 0) {
    view()->SetSelectedNetworkItem(index + 1);
  } else {
    view()->SetSelectedNetworkItem(0);
  }
}

}  // namespace chromeos
<commit_msg>Do nothing when "No selection" entry is selected. That entry is at index=0.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/login/network_screen.h"

#include "app/l10n_util.h"
#include "base/utf_string_conversions.h"
#include "base/logging.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/login/network_selection_view.h"
#include "chrome/browser/chromeos/login/screen_observer.h"
#include "chrome/browser/chromeos/options/network_config_view.h"
#include "grit/generated_resources.h"
#include "views/widget/widget.h"
#include "views/window/window.h"

namespace chromeos {

///////////////////////////////////////////////////////////////////////////////
// NetworkScreen, public:

NetworkScreen::NetworkScreen(WizardScreenDelegate* delegate, bool is_out_of_box)
    : ViewScreen<NetworkSelectionView>(delegate),
      is_network_subscribed_(false),
      is_out_of_box_(is_out_of_box),
      ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
}

NetworkScreen::~NetworkScreen() {
  UnsubscribeNetworkNotification();
}

////////////////////////////////////////////////////////////////////////////////
// ComboboxModel implementation:

int NetworkScreen::GetItemCount() {
  // Item with index = 0 is either "no networks are available" or
  // "no selection".
  return static_cast<int>(networks_.GetNetworkCount()) + 1;
}

std::wstring NetworkScreen::GetItemAt(int index) {
  if (index == 0) {
    return networks_.IsEmpty() ?
        l10n_util::GetString(IDS_STATUSBAR_NO_NETWORKS_MESSAGE) :
        l10n_util::GetString(IDS_NETWORK_SELECTION_NONE);
  }
  NetworkList::NetworkItem* network =
      networks_.GetNetworkAt(index - 1);
  return network ? UTF16ToWide(network->label) : std::wstring();
}

////////////////////////////////////////////////////////////////////////////////
// views::Combobox::Listener implementation:

void NetworkScreen::ItemChanged(views::Combobox* sender,
                                int prev_index,
                                int new_index) {
  // Corner case: item with index 0 is "No selection". Just select it.
  if (new_index == prev_index || new_index <= 0 || prev_index < 0)
    return;

  if (networks_.IsEmpty())
    return;

  const NetworkList::NetworkItem* network =
      networks_.GetNetworkAt(new_index - 1);
  MessageLoop::current()->PostTask(FROM_HERE, task_factory_.NewRunnableMethod(
      &NetworkScreen::ConnectToNetwork, network->network_type, network->label));
}

///////////////////////////////////////////////////////////////////////////////
// views::ButtonListener implementation:

void NetworkScreen::ButtonPressed(views::Button* sender,
                                  const views::Event& event) {
  MessageLoop::current()->PostTask(FROM_HERE,
      task_factory_.NewRunnableMethod(&NetworkScreen::NotifyOnOffline));
}

////////////////////////////////////////////////////////////////////////////////
// NetworkLibrary::Observer implementation:

void NetworkScreen::NetworkChanged(NetworkLibrary* network_lib) {
  // Save network selection in case it would be available after refresh.
  NetworkList::NetworkType network_type = NetworkList::NETWORK_EMPTY;
  string16 network_id;
  const NetworkList::NetworkItem* selected_network = GetSelectedNetwork();
  if (selected_network) {
    network_type = selected_network->network_type;
    network_id = selected_network->label;
  }
  networks_.NetworkChanged(network_lib);
  // TODO(nkostylev): Check for connection error.
  // For initial out of box experience make sure that network was selected.
  if (networks_.ConnectedNetwork() &&
      (selected_network || !is_out_of_box_)) {
    MessageLoop::current()->PostTask(FROM_HERE,
        task_factory_.NewRunnableMethod(&NetworkScreen::NotifyOnConnection));
    return;
  }
  const NetworkList::NetworkItem* network = networks_.ConnectingNetwork();
  if (network &&
      (selected_network || !is_out_of_box_)) {
    view()->ShowConnectingStatus(true, network->label);
  }
  view()->NetworkModelChanged();
  SelectNetwork(network_type, network_id);
}

void NetworkScreen::NetworkTraffic(NetworkLibrary* cros,
                                   int traffic_type) {
}

///////////////////////////////////////////////////////////////////////////////
// NetworkScreen, ViewScreen implementation:

void NetworkScreen::CreateView() {
  language_switch_model_.InitLanguageMenu();
  ViewScreen<NetworkSelectionView>::CreateView();
}

NetworkSelectionView* NetworkScreen::AllocateView() {
  return new NetworkSelectionView(this);
}

////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, public:

void NetworkScreen::Refresh() {
  SubscribeNetworkNotification();
  NetworkChanged(chromeos::CrosLibrary::Get()->GetNetworkLibrary());
}

////////////////////////////////////////////////////////////////////////////////
// NetworkScreen, private:

void NetworkScreen::ConnectToNetwork(NetworkList::NetworkType type,
                                     const string16& id) {
  const NetworkList::NetworkItem* network =
      networks_.GetNetworkById(type, id);
  if (network && !IsSameNetwork(network, networks_.ConnectedNetwork())) {
    if (NetworkList::NETWORK_WIFI == network->network_type) {
      if (network->wifi_network.encrypted()) {
        OpenPasswordDialog(network->wifi_network);
        return;
      } else {
        chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
            ConnectToWifiNetwork(network->wifi_network,
                                 string16(), string16(), string16());
      }
    } else if (NetworkList::NETWORK_CELLULAR == network->network_type) {
      chromeos::CrosLibrary::Get()->GetNetworkLibrary()->
          ConnectToCellularNetwork(network->cellular_network);
    }
  }
  // Check if there's already connected network and update screen state.
  MessageLoop::current()->PostTask(FROM_HERE, task_factory_.NewRunnableMethod(
      &NetworkScreen::NetworkChanged,
      chromeos::CrosLibrary::Get()->GetNetworkLibrary()));
}

void NetworkScreen::SubscribeNetworkNotification() {
  if (!is_network_subscribed_) {
    is_network_subscribed_ = true;
    chromeos::CrosLibrary::Get()->GetNetworkLibrary()->AddObserver(this);
  }
}

void NetworkScreen::UnsubscribeNetworkNotification() {
  if (is_network_subscribed_) {
    is_network_subscribed_ = false;
    chromeos::CrosLibrary::Get()->GetNetworkLibrary()->RemoveObserver(this);
  }
}

NetworkList::NetworkItem* NetworkScreen::GetSelectedNetwork() {
  return networks_.GetNetworkAt(view()->GetSelectedNetworkItem() - 1);
}

bool NetworkScreen::IsSameNetwork(const NetworkList::NetworkItem* network1,
                                  const NetworkList::NetworkItem* network2) {
  return (network1 && network2 &&
          network1->network_type == network2->network_type &&
          network1->label == network2->label);
}

void NetworkScreen::NotifyOnConnection() {
  UnsubscribeNetworkNotification();
  delegate()->GetObserver(this)->OnExit(ScreenObserver::NETWORK_CONNECTED);
}

void NetworkScreen::NotifyOnOffline() {
  UnsubscribeNetworkNotification();
  delegate()->GetObserver(this)->OnExit(ScreenObserver::NETWORK_OFFLINE);
}

void NetworkScreen::OpenPasswordDialog(WifiNetwork network) {
  NetworkConfigView* dialog = new NetworkConfigView(network, true);
  dialog->set_browser_mode(false);
  views::Window* window = views::Window::CreateChromeWindow(
      view()->GetNativeWindow(), gfx::Rect(), dialog);
  window->SetIsAlwaysOnTop(true);
  window->Show();
  dialog->SetLoginTextfieldFocus();
}

void NetworkScreen::SelectNetwork(NetworkList::NetworkType type,
                                  const string16& id) {
  int index = networks_.GetNetworkIndexById(type, id);
  if (index >= 0) {
    view()->SetSelectedNetworkItem(index + 1);
  } else {
    view()->SetSelectedNetworkItem(0);
  }
}

}  // namespace chromeos
<|endoftext|>


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

#include "chrome/browser/chromeos/native_dialog_window.h"

#include <gtk/gtk.h>

#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/frame/bubble_window.h"
#include "chrome/browser/ui/views/window.h"
#include "ui/base/gtk/gtk_signal.h"
#include "views/controls/native/native_view_host.h"
#include "views/widget/widget.h"
#include "views/window/dialog_delegate.h"
#include "views/window/non_client_view.h"

namespace {

const int kDialogPadding = 3;

const char kNativeDialogHost[] = "_chromeos_native_dialog_host_";

// TODO(xiyuan): Use gtk_window_get_default_widget with GTK 2.14+.
// Gets the default widget of given dialog.
GtkWidget* GetDialogDefaultWidget(GtkDialog* dialog) {
  GtkWidget* default_widget = NULL;

  GList* children = gtk_container_get_children(
      GTK_CONTAINER(dialog->action_area));

  GList* current = children;
  while (current) {
    GtkWidget* widget = reinterpret_cast<GtkWidget*>(current->data);
    if (gtk_widget_has_default(widget)) {
      default_widget = widget;
      break;
    }

    current = g_list_next(current);
  }

  g_list_free(children);

  return default_widget;
}

}  // namespace

namespace chromeos {

class NativeDialogHost : public views::DialogDelegateView {
 public:
  NativeDialogHost(gfx::NativeView native_dialog,
                   int flags,
                   const gfx::Size& size,
                   const gfx::Size& min_size);
  ~NativeDialogHost();

  // views::DialogDelegate implementation:
  virtual bool CanResize() const { return flags_ & DIALOG_FLAG_RESIZEABLE; }
  virtual int GetDialogButtons() const { return 0; }
  virtual std::wstring GetWindowTitle() const { return title_; }
  virtual views::View* GetContentsView() { return this; }
  virtual bool IsModal() const { return flags_ & DIALOG_FLAG_MODAL; }
  virtual void WindowClosing();

 protected:
  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnCheckResize);
  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnDialogDestroy);

  // views::View implementation:
  virtual gfx::Size GetPreferredSize();
  virtual void Layout();
  virtual void ViewHierarchyChanged(bool is_add,
                                    views::View* parent,
                                    views::View* child);
 private:
  // Init and attach to native dialog.
  void Init();

  // Check and apply minimum size restriction.
  void CheckSize();

  // The GtkDialog whose vbox will be displayed in this view.
  gfx::NativeView dialog_;

  // NativeViewHost for the dialog's contents.
  views::NativeViewHost* contents_view_;

  std::wstring title_;
  int flags_;
  gfx::Size size_;
  gfx::Size preferred_size_;
  gfx::Size min_size_;

  int destroy_signal_id_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(NativeDialogHost);
};

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, public:

NativeDialogHost::NativeDialogHost(gfx::NativeView native_dialog,
                                   int flags,
                                   const gfx::Size& size,
                                   const gfx::Size& min_size)
    : dialog_(native_dialog),
      contents_view_(NULL),
      flags_(flags),
      size_(size),
      preferred_size_(size),
      min_size_(min_size),
      destroy_signal_id_(0) {
  const char* title = gtk_window_get_title(GTK_WINDOW(dialog_));
  if (title)
    UTF8ToWide(title, strlen(title), &title_);

  destroy_signal_id_ = g_signal_connect(dialog_, "destroy",
      G_CALLBACK(&OnDialogDestroyThunk), this);
}

NativeDialogHost::~NativeDialogHost() {
}

void NativeDialogHost::OnCheckResize(GtkWidget* widget) {
  // Do auto height resize only when we are asked to do so.
  if (size_.height() == 0) {
    gfx::NativeView contents = contents_view_->native_view();

    // Check whether preferred height has changed. We keep the current width
    // unchanged and pass "-1" as height to let gtk calculate a proper height.
    gtk_widget_set_size_request(contents, width(), -1);
    GtkRequisition requsition = { 0 };
    gtk_widget_size_request(contents, &requsition);

    if (preferred_size_.height() != requsition.height) {
      preferred_size_.set_width(requsition.width);
      preferred_size_.set_height(requsition.height);
      CheckSize();
      SizeToPreferredSize();

      gfx::Size window_size =
          GetWidget()->non_client_view()->GetPreferredSize();
      gfx::Rect window_bounds = GetWidget()->GetWindowScreenBounds();
      window_bounds.set_width(window_size.width());
      window_bounds.set_height(window_size.height());
      GetWidget()->SetBoundsConstrained(window_bounds, NULL);
    }
  }
}

void NativeDialogHost::OnDialogDestroy(GtkWidget* widget) {
  dialog_ = NULL;
  destroy_signal_id_ = 0;
  GetWidget()->Close();
}

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, views::DialogDelegate implementation:
void NativeDialogHost::WindowClosing() {
  if (dialog_) {
    // Disconnect the "destroy" signal because we are about to destroy
    // the dialog ourselves and no longer interested in it.
    g_signal_handler_disconnect(G_OBJECT(dialog_), destroy_signal_id_);
    gtk_dialog_response(GTK_DIALOG(dialog_), GTK_RESPONSE_DELETE_EVENT);
  }
}

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, views::View implementation:

gfx::Size NativeDialogHost::GetPreferredSize() {
  return preferred_size_;
}

void NativeDialogHost::Layout() {
  contents_view_->SetBounds(0, 0, width(), height());
}

void NativeDialogHost::ViewHierarchyChanged(bool is_add,
                                            views::View* parent,
                                            views::View* child) {
  if (is_add && child == this)
    Init();
}

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, private:
void NativeDialogHost::Init() {
  if (contents_view_)
    return;

  // Get default widget of the dialog.
  GtkWidget* default_widget = GetDialogDefaultWidget(GTK_DIALOG(dialog_));

  // Get focus widget of the dialog.
  GtkWidget* focus_widget = gtk_window_get_focus(GTK_WINDOW(dialog_));

  // Create a GtkAlignment as dialog contents container.
  GtkWidget* contents = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(contents),
      kDialogPadding, kDialogPadding,
      kDialogPadding, kDialogPadding);

  // Move dialog contents into our container.
  GtkWidget* dialog_contents = GTK_DIALOG(dialog_)->vbox;
  g_object_ref(dialog_contents);
  gtk_container_remove(GTK_CONTAINER(dialog_), dialog_contents);
  gtk_container_add(GTK_CONTAINER(contents), dialog_contents);
  g_object_unref(dialog_contents);
  gtk_widget_hide(dialog_);

  g_object_set_data(G_OBJECT(dialog_), kNativeDialogHost,
      reinterpret_cast<gpointer>(this));

  gtk_widget_show_all(contents);

  contents_view_ = new views::NativeViewHost();
  // TODO(xiyuan): Find a better way to get proper background.
  contents_view_->set_background(views::Background::CreateSolidBackground(
      kBubbleWindowBackgroundColor));
  AddChildView(contents_view_);
  contents_view_->Attach(contents);

  g_signal_connect(GetWidget()->GetNativeWindow(), "check-resize",
      G_CALLBACK(&OnCheckResizeThunk), this);

  const int padding = 2 * kDialogPadding;
  // Use gtk's default size if size is not specified.
  if (size_.IsEmpty()) {
    // Use given width or height if given.
    if (size_.width() || size_.height()) {
      int width = size_.width() == 0 ? -1 : size_.width() + padding;
      int height = size_.height() == 0 ? -1 : size_.height() + padding;
      gtk_widget_set_size_request(contents, width, height);
    }

    GtkRequisition requsition = { 0 };
    gtk_widget_size_request(contents, &requsition);
    preferred_size_.set_width(requsition.width);
    preferred_size_.set_height(requsition.height);
  } else {
    preferred_size_.set_width(size_.width() + padding);
    preferred_size_.set_height(size_.height() + padding);
  }

  CheckSize();

  if (default_widget)
    gtk_widget_grab_default(default_widget);

  if (focus_widget)
    gtk_widget_grab_focus(focus_widget);
}

void NativeDialogHost::CheckSize() {
  // Apply the minimum size.
  if (preferred_size_.width() < min_size_.width())
    preferred_size_.set_width(min_size_.width());
  if (preferred_size_.height() < min_size_.height())
    preferred_size_.set_height(min_size_.height());
}

void ShowNativeDialog(gfx::NativeWindow parent,
                      gfx::NativeView native_dialog,
                      int flags,
                      const gfx::Size& size,
                      const gfx::Size& min_size) {
  NativeDialogHost* native_dialog_host =
      new NativeDialogHost(native_dialog, flags, size, min_size);
  browser::CreateViewsWindow(parent, native_dialog_host);
  native_dialog_host->GetWidget()->Show();
}

gfx::NativeWindow GetNativeDialogWindow(gfx::NativeView native_dialog) {
  NativeDialogHost* host = reinterpret_cast<NativeDialogHost*>(
      g_object_get_data(G_OBJECT(native_dialog), kNativeDialogHost));
  return host ? host->GetWidget()->GetNativeWindow() : NULL;
}

gfx::Rect GetNativeDialogContentsBounds(gfx::NativeView native_dialog) {
  NativeDialogHost* host = reinterpret_cast<NativeDialogHost*>(
      g_object_get_data(G_OBJECT(native_dialog), kNativeDialogHost));
  return host ? host->bounds() : gfx::Rect();
}

}  // namespace chromeos
<commit_msg>Make Tab key to work on new bookmark dialog.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/native_dialog_window.h"

#include <gtk/gtk.h>

#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/chromeos/frame/bubble_window.h"
#include "chrome/browser/ui/views/window.h"
#include "ui/base/gtk/gtk_signal.h"
#include "views/controls/native/native_view_host.h"
#include "views/widget/widget.h"
#include "views/window/dialog_delegate.h"
#include "views/window/non_client_view.h"

namespace {

const int kDialogPadding = 3;

const char kNativeDialogHost[] = "_chromeos_native_dialog_host_";

// TODO(xiyuan): Use gtk_window_get_default_widget with GTK 2.14+.
// Gets the default widget of given dialog.
GtkWidget* GetDialogDefaultWidget(GtkDialog* dialog) {
  GtkWidget* default_widget = NULL;

  GList* children = gtk_container_get_children(
      GTK_CONTAINER(dialog->action_area));

  GList* current = children;
  while (current) {
    GtkWidget* widget = reinterpret_cast<GtkWidget*>(current->data);
    if (gtk_widget_has_default(widget)) {
      default_widget = widget;
      break;
    }

    current = g_list_next(current);
  }

  g_list_free(children);

  return default_widget;
}

}  // namespace

namespace chromeos {

class NativeDialogHost : public views::DialogDelegateView {
 public:
  NativeDialogHost(gfx::NativeView native_dialog,
                   int flags,
                   const gfx::Size& size,
                   const gfx::Size& min_size);
  ~NativeDialogHost();

  // views::DialogDelegate implementation:
  virtual bool CanResize() const { return flags_ & DIALOG_FLAG_RESIZEABLE; }
  virtual int GetDialogButtons() const { return 0; }
  virtual std::wstring GetWindowTitle() const { return title_; }
  virtual views::View* GetContentsView() { return this; }
  virtual bool IsModal() const { return flags_ & DIALOG_FLAG_MODAL; }
  virtual void WindowClosing();

 protected:
  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnCheckResize);
  CHROMEGTK_CALLBACK_0(NativeDialogHost, void, OnDialogDestroy);
  CHROMEGTK_CALLBACK_1(NativeDialogHost, gboolean, OnGtkKeyPressed, GdkEvent*);

  // views::View implementation:
  virtual gfx::Size GetPreferredSize();
  virtual void Layout();
  virtual void ViewHierarchyChanged(bool is_add,
                                    views::View* parent,
                                    views::View* child);
 private:
  // Init and attach to native dialog.
  void Init();

  // Enable moving focuses over native widgets by the Tab key.
  void InitNativeFocusMove(GtkWidget* contents);

  // Check and apply minimum size restriction.
  void CheckSize();

  // The GtkDialog whose vbox will be displayed in this view.
  gfx::NativeView dialog_;

  // NativeViewHost for the dialog's contents.
  views::NativeViewHost* contents_view_;

  std::wstring title_;
  int flags_;
  gfx::Size size_;
  gfx::Size preferred_size_;
  gfx::Size min_size_;

  int destroy_signal_id_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(NativeDialogHost);
};

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, public:

NativeDialogHost::NativeDialogHost(gfx::NativeView native_dialog,
                                   int flags,
                                   const gfx::Size& size,
                                   const gfx::Size& min_size)
    : dialog_(native_dialog),
      contents_view_(NULL),
      flags_(flags),
      size_(size),
      preferred_size_(size),
      min_size_(min_size),
      destroy_signal_id_(0) {
  const char* title = gtk_window_get_title(GTK_WINDOW(dialog_));
  if (title)
    UTF8ToWide(title, strlen(title), &title_);

  destroy_signal_id_ = g_signal_connect(dialog_, "destroy",
      G_CALLBACK(&OnDialogDestroyThunk), this);
}

NativeDialogHost::~NativeDialogHost() {
}

void NativeDialogHost::OnCheckResize(GtkWidget* widget) {
  // Do auto height resize only when we are asked to do so.
  if (size_.height() == 0) {
    gfx::NativeView contents = contents_view_->native_view();

    // Check whether preferred height has changed. We keep the current width
    // unchanged and pass "-1" as height to let gtk calculate a proper height.
    gtk_widget_set_size_request(contents, width(), -1);
    GtkRequisition requsition = { 0 };
    gtk_widget_size_request(contents, &requsition);

    if (preferred_size_.height() != requsition.height) {
      preferred_size_.set_width(requsition.width);
      preferred_size_.set_height(requsition.height);
      CheckSize();
      SizeToPreferredSize();

      gfx::Size window_size =
          GetWidget()->non_client_view()->GetPreferredSize();
      gfx::Rect window_bounds = GetWidget()->GetWindowScreenBounds();
      window_bounds.set_width(window_size.width());
      window_bounds.set_height(window_size.height());
      GetWidget()->SetBoundsConstrained(window_bounds, NULL);
    }
  }
}

void NativeDialogHost::OnDialogDestroy(GtkWidget* widget) {
  dialog_ = NULL;
  destroy_signal_id_ = 0;
  GetWidget()->Close();
}

gboolean NativeDialogHost::OnGtkKeyPressed(GtkWidget* widget, GdkEvent* event) {
  // Manually handle focus movement by Tab key.
  // See the comments in NativeDialogHost::InitNativeFocusMove for more detail.
  views::KeyEvent key_event(event);
  if (views::FocusManager::IsTabTraversalKeyEvent(key_event)) {
    GtkWindow* window = GetWidget()->GetNativeWindow();
    GtkDirectionType dir =
        key_event.IsShiftDown() ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD;
    static_cast<GtkWindowClass*>(
        g_type_class_peek(GTK_TYPE_WINDOW))->move_focus(window, dir);
    return true;
  }
  return false;
}

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, views::DialogDelegate implementation:
void NativeDialogHost::WindowClosing() {
  if (dialog_) {
    // Disconnect the "destroy" signal because we are about to destroy
    // the dialog ourselves and no longer interested in it.
    g_signal_handler_disconnect(G_OBJECT(dialog_), destroy_signal_id_);
    gtk_dialog_response(GTK_DIALOG(dialog_), GTK_RESPONSE_DELETE_EVENT);
  }
}

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, views::View implementation:

gfx::Size NativeDialogHost::GetPreferredSize() {
  return preferred_size_;
}

void NativeDialogHost::Layout() {
  contents_view_->SetBounds(0, 0, width(), height());
}

void NativeDialogHost::ViewHierarchyChanged(bool is_add,
                                            views::View* parent,
                                            views::View* child) {
  if (is_add && child == this)
    Init();
}

///////////////////////////////////////////////////////////////////////////////
// NativeDialogHost, private:
void NativeDialogHost::Init() {
  if (contents_view_)
    return;

  // Get default widget of the dialog.
  GtkWidget* default_widget = GetDialogDefaultWidget(GTK_DIALOG(dialog_));

  // Get focus widget of the dialog.
  GtkWidget* focus_widget = gtk_window_get_focus(GTK_WINDOW(dialog_));

  // Create a GtkAlignment as dialog contents container.
  GtkWidget* contents = gtk_alignment_new(0.5, 0.5, 1.0, 1.0);
  gtk_alignment_set_padding(GTK_ALIGNMENT(contents),
      kDialogPadding, kDialogPadding,
      kDialogPadding, kDialogPadding);

  // Move dialog contents into our container.
  GtkWidget* dialog_contents = GTK_DIALOG(dialog_)->vbox;
  g_object_ref(dialog_contents);
  gtk_container_remove(GTK_CONTAINER(dialog_), dialog_contents);
  gtk_container_add(GTK_CONTAINER(contents), dialog_contents);
  g_object_unref(dialog_contents);
  gtk_widget_hide(dialog_);

  g_object_set_data(G_OBJECT(dialog_), kNativeDialogHost,
      reinterpret_cast<gpointer>(this));

  gtk_widget_show_all(contents);

  contents_view_ = new views::NativeViewHost();
  // TODO(xiyuan): Find a better way to get proper background.
  contents_view_->set_background(views::Background::CreateSolidBackground(
      kBubbleWindowBackgroundColor));
  AddChildView(contents_view_);
  contents_view_->Attach(contents);

  InitNativeFocusMove(contents);

  g_signal_connect(GetWidget()->GetNativeWindow(), "check-resize",
      G_CALLBACK(&OnCheckResizeThunk), this);

  const int padding = 2 * kDialogPadding;
  // Use gtk's default size if size is not specified.
  if (size_.IsEmpty()) {
    // Use given width or height if given.
    if (size_.width() || size_.height()) {
      int width = size_.width() == 0 ? -1 : size_.width() + padding;
      int height = size_.height() == 0 ? -1 : size_.height() + padding;
      gtk_widget_set_size_request(contents, width, height);
    }

    GtkRequisition requsition = { 0 };
    gtk_widget_size_request(contents, &requsition);
    preferred_size_.set_width(requsition.width);
    preferred_size_.set_height(requsition.height);
  } else {
    preferred_size_.set_width(size_.width() + padding);
    preferred_size_.set_height(size_.height() + padding);
  }

  CheckSize();

  if (default_widget)
    gtk_widget_grab_default(default_widget);

  if (focus_widget)
    gtk_widget_grab_focus(focus_widget);
}

void NativeDialogHost::InitNativeFocusMove(GtkWidget* contents) {
  // Fix for http://crosbug.com/7725.
  //
  // When a native GTK dialog is hosted on views+GTK, the views framework
  // prevents Tab key events to be passed to the GTK's handler in three places:
  //   1. views::FocusManager::OnKeyEvent
  //     It intercepts key events _after_ the usual event handlers through the
  //     native widget hierarchy and _before_ the native key binding handlers.
  //     Since moving focus by Tab is implemented as a key binding, it cannot
  //     be reached. As a workaround for NativeDialogHost, we install an usual
  //     key event handler for capturing Tab key, before FocusManager.
  //   2. ::gtk_views_window_move_focus
  //     The default "move_focus" method of GtkWindow is overridden by views
  //     to invoke views::FocusManager. This is avoided by calling the default
  //     GtkWindow->move_focus explicitly in the OnGtkKeyPressed handler.
  //   3. ::gtk_views_fixed_init
  //     Several GTK widgets of type GtkViewsFixed are inserted between the
  //     dialog window and the dialog controls, so that views framework can
  //     observe native events. The problem is that these widgets have CAN_FOCUS
  //     flags, which means they don't propagate focuses to the child controls.
  //     Here we turn the flag off to make descendant dialog controls focusable.
  // Note that, these "stealing" behaviors of views are required ones in the
  // usual situation where native widgets are used just as a hidden background
  // implementation of views. Only when a native widget hierarchy is hosted and
  // directly exposed to the users, the following workaround is necessary.

  g_signal_connect(contents, "key_press_event",
                   G_CALLBACK(&OnGtkKeyPressedThunk), this);

  GtkWidget* window = GTK_WIDGET(GetWidget()->GetNativeWindow());
  GtkWidget* anscestor = gtk_widget_get_parent(GTK_WIDGET(contents));
  while (anscestor && anscestor != window) {
    GTK_WIDGET_UNSET_FLAGS(anscestor, GTK_CAN_FOCUS);
    anscestor = gtk_widget_get_parent(anscestor);
  }
}

void NativeDialogHost::CheckSize() {
  // Apply the minimum size.
  if (preferred_size_.width() < min_size_.width())
    preferred_size_.set_width(min_size_.width());
  if (preferred_size_.height() < min_size_.height())
    preferred_size_.set_height(min_size_.height());
}

void ShowNativeDialog(gfx::NativeWindow parent,
                      gfx::NativeView native_dialog,
                      int flags,
                      const gfx::Size& size,
                      const gfx::Size& min_size) {
  NativeDialogHost* native_dialog_host =
      new NativeDialogHost(native_dialog, flags, size, min_size);
  browser::CreateViewsWindow(parent, native_dialog_host);
  native_dialog_host->GetWidget()->Show();
}

gfx::NativeWindow GetNativeDialogWindow(gfx::NativeView native_dialog) {
  NativeDialogHost* host = reinterpret_cast<NativeDialogHost*>(
      g_object_get_data(G_OBJECT(native_dialog), kNativeDialogHost));
  return host ? host->GetWidget()->GetNativeWindow() : NULL;
}

gfx::Rect GetNativeDialogContentsBounds(gfx::NativeView native_dialog) {
  NativeDialogHost* host = reinterpret_cast<NativeDialogHost*>(
      g_object_get_data(G_OBJECT(native_dialog), kNativeDialogHost));
  return host ? host->bounds() : gfx::Rect();
}

}  // namespace chromeos
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "cyber/common/file.h"

#include <dirent.h>
#include <errno.h>
#include <glob.h>
#include <stddef.h>
#include <unistd.h>
#include <fstream>
#include <string>

namespace apollo {
namespace cyber {
namespace common {

bool SetProtoToASCIIFile(const google::protobuf::Message &message,
                         int file_descriptor) {
  using google::protobuf::TextFormat;
  using google::protobuf::io::FileOutputStream;
  using google::protobuf::io::ZeroCopyOutputStream;
  if (file_descriptor < 0) {
    AERROR << "Invalid file descriptor.";
    return false;
  }
  ZeroCopyOutputStream *output = new FileOutputStream(file_descriptor);
  bool success = TextFormat::Print(message, output);
  delete output;
  close(file_descriptor);
  return success;
}

bool SetProtoToASCIIFile(const google::protobuf::Message &message,
                         const std::string &file_name) {
  int fd = open(file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
  if (fd < 0) {
    AERROR << "Unable to open file " << file_name << " to write.";
    return false;
  }
  return SetProtoToASCIIFile(message, fd);
}

bool GetProtoFromASCIIFile(const std::string &file_name,
                           google::protobuf::Message *message) {
  using google::protobuf::TextFormat;
  using google::protobuf::io::FileInputStream;
  using google::protobuf::io::ZeroCopyInputStream;
  int file_descriptor = open(file_name.c_str(), O_RDONLY);
  if (file_descriptor < 0) {
    AERROR << "Failed to open file " << file_name << " in text mode.";
    // Failed to open;
    return false;
  }

  ZeroCopyInputStream *input = new FileInputStream(file_descriptor);
  bool success = TextFormat::Parse(input, message);
  if (!success) {
    AERROR << "Failed to parse file " << file_name << " as text proto.";
  }
  delete input;
  close(file_descriptor);
  return success;
}

bool SetProtoToBinaryFile(const google::protobuf::Message &message,
                          const std::string &file_name) {
  std::fstream output(file_name,
                      std::ios::out | std::ios::trunc | std::ios::binary);
  return message.SerializeToOstream(&output);
}

bool GetProtoFromBinaryFile(const std::string &file_name,
                            google::protobuf::Message *message) {
  std::fstream input(file_name, std::ios::in | std::ios::binary);
  if (!input.good()) {
    AERROR << "Failed to open file " << file_name << " in binary mode.";
    return false;
  }
  if (!message->ParseFromIstream(&input)) {
    AERROR << "Failed to parse file " << file_name << " as binary proto.";
    return false;
  }
  return true;
}

bool GetProtoFromFile(const std::string &file_name,
                      google::protobuf::Message *message) {
  // Try the binary parser first if it's much likely a binary proto.
  static const std::string kBinExt = ".bin";
  if (std::equal(kBinExt.rbegin(), kBinExt.rend(), file_name.rbegin())) {
    return GetProtoFromBinaryFile(file_name, message) ||
           GetProtoFromASCIIFile(file_name, message);
  }

  return GetProtoFromASCIIFile(file_name, message) ||
         GetProtoFromBinaryFile(file_name, message);
}

bool GetContent(const std::string &file_name, std::string *content) {
  std::ifstream fin(file_name);
  if (!fin) {
    return false;
  }

  std::stringstream str_stream;
  str_stream << fin.rdbuf();
  *content = str_stream.str();
  return true;
}

std::string GetAbsolutePath(const std::string &prefix,
                            const std::string &relative_path) {
  if (relative_path.empty()) {
    return prefix;
  }
  // If prefix is empty or relative_path is already absolute.
  if (prefix.empty() || relative_path.front() == '/') {
    return relative_path;
  }

  if (prefix.back() == '/') {
    return prefix + relative_path;
  }
  return prefix + "/" + relative_path;
}

bool PathExists(const std::string &path) {
  struct stat info;
  return stat(path.c_str(), &info) == 0;
}

bool DirectoryExists(const std::string &directory_path) {
  struct stat info;
  if (stat(directory_path.c_str(), &info) != 0) {
    return false;
  }

  if (info.st_mode & S_IFDIR) {
    return true;
  }

  return false;
}

std::vector<std::string> Glob(const std::string &pattern) {
  glob_t globs = {};
  std::vector<std::string> results;
  if (0 == glob(pattern.c_str(), GLOB_TILDE, nullptr, &globs)) {
    for (size_t i = 0; i < globs.gl_pathc; ++i) {
      results.emplace_back(globs.gl_pathv[i]);
    }
  }
  globfree(&globs);
  return results;
}

bool CopyFile(const std::string &from, const std::string &to) {
  std::ifstream src(from, std::ios::binary);
  if (!src) {
    AERROR << "Source path doesn't exist: " << from;
    return false;
  }

  std::ofstream dst(to, std::ios::binary);
  if (!dst) {
    AERROR << "Target path is not writable: " << to;
    return false;
  }

  dst << src.rdbuf();
  return true;
}

bool CopyDir(const std::string &from, const std::string &to) {
  DIR *directory = opendir(from.c_str());
  if (directory == nullptr) {
    AERROR << "Cannot open directory " << from;
    return false;
  }

  bool ret = true;
  if (EnsureDirectory(to)) {
    struct dirent *entry;
    while ((entry = readdir(directory)) != nullptr) {
      // skip directory_path/. and directory_path/..
      if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
        continue;
      }
      const std::string sub_path_from = from + "/" + entry->d_name;
      const std::string sub_path_to = to + "/" + entry->d_name;
      if (entry->d_type == DT_DIR) {
        ret &= CopyDir(sub_path_from, sub_path_to);
      } else {
        ret &= CopyFile(sub_path_from, sub_path_to);
      }
    }
  } else {
    AERROR << "Cannot create target directory " << to;
    ret = false;
  }
  closedir(directory);
  return ret;
}

bool Copy(const std::string &from, const std::string &to) {
  return DirectoryExists(from) ? CopyDir(from, to) : CopyFile(from, to);
}

bool EnsureDirectory(const std::string &directory_path) {
  std::string path = directory_path;
  for (size_t i = 1; i < directory_path.size(); ++i) {
    if (directory_path[i] == '/') {
      // Whenever a '/' is encountered, create a temporary view from
      // the start of the path to the character right before this.
      path[i] = 0;

      if (mkdir(path.c_str(), S_IRWXU) != 0) {
        if (errno != EEXIST) {
          return false;
        }
      }

      // Revert the temporary view back to the original.
      path[i] = '/';
    }
  }

  // Make the final (full) directory.
  if (mkdir(path.c_str(), S_IRWXU) != 0) {
    if (errno != EEXIST) {
      return false;
    }
  }

  return true;
}

bool RemoveAllFiles(const std::string &directory_path) {
  DIR *directory = opendir(directory_path.c_str());
  if (directory == nullptr) {
    AERROR << "Cannot open directory " << directory_path;
    return false;
  }

  struct dirent *file;
  while ((file = readdir(directory)) != nullptr) {
    // skip directory_path/. and directory_path/..
    if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) {
      continue;
    }
    // build the path for each file in the folder
    std::string file_path = directory_path + "/" + file->d_name;
    if (unlink(file_path.c_str()) < 0) {
      AERROR << "Fail to remove file " << file_path << ": " << strerror(errno);
      closedir(directory);
      return false;
    }
  }
  closedir(directory);
  return true;
}

std::vector<std::string> ListSubPaths(const std::string &directory_path,
                                      const unsigned char d_type) {
  std::vector<std::string> result;
  DIR *directory = opendir(directory_path.c_str());
  if (directory == nullptr) {
    AERROR << "Cannot open directory " << directory_path;
    return result;
  }

  struct dirent *entry;
  while ((entry = readdir(directory)) != nullptr) {
    // Skip "." and "..".
    if (entry->d_type == d_type && strcmp(entry->d_name, ".") != 0 &&
        strcmp(entry->d_name, "..") != 0) {
      result.emplace_back(entry->d_name);
    }
  }
  closedir(directory);
  return result;
}

std::string GetFileName(const std::string &path, const bool remove_extension) {
  std::string::size_type start = path.rfind('/');
  if (start == std::string::npos) {
    start = 0;
  } else {
    // Move to the next char after '/'.
    ++start;
  }

  std::string::size_type end = std::string::npos;
  if (remove_extension) {
    end = path.rfind('.');
    // The last '.' is found before last '/', ignore.
    if (end != std::string::npos && end < start) {
      end = std::string::npos;
    }
  }
  const auto len = (end != std::string::npos) ? end - start : end;
  return path.substr(start, len);
}

std::string GetCurrentPath() {
  char tmp[PATH_MAX];
  if (getcwd(tmp, sizeof(tmp)) != nullptr) {
    return std::string(tmp);
  } else {
    return std::string("");
  }
}

}  // namespace common
}  // namespace cyber
}  // namespace apollo
<commit_msg>Revert.<commit_after>/******************************************************************************
 * Copyright 2018 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "cyber/common/file.h"

#include <dirent.h>
#include <errno.h>
#include <glob.h>
#include <stddef.h>
#include <unistd.h>
#include <fstream>
#include <string>

namespace apollo {
namespace cyber {
namespace common {

bool SetProtoToASCIIFile(const google::protobuf::Message &message,
                         int file_descriptor) {
  using google::protobuf::TextFormat;
  using google::protobuf::io::FileOutputStream;
  using google::protobuf::io::ZeroCopyOutputStream;
  if (file_descriptor < 0) {
    AERROR << "Invalid file descriptor.";
    return false;
  }
  ZeroCopyOutputStream *output = new FileOutputStream(file_descriptor);
  bool success = TextFormat::Print(message, output);
  delete output;
  close(file_descriptor);
  return success;
}

bool SetProtoToASCIIFile(const google::protobuf::Message &message,
                         const std::string &file_name) {
  int fd = open(file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
  if (fd < 0) {
    AERROR << "Unable to open file " << file_name << " to write.";
    return false;
  }
  return SetProtoToASCIIFile(message, fd);
}

bool GetProtoFromASCIIFile(const std::string &file_name,
                           google::protobuf::Message *message) {
  using google::protobuf::TextFormat;
  using google::protobuf::io::FileInputStream;
  using google::protobuf::io::ZeroCopyInputStream;
  int file_descriptor = open(file_name.c_str(), O_RDONLY);
  if (file_descriptor < 0) {
    AERROR << "Failed to open file " << file_name << " in text mode.";
    // Failed to open;
    return false;
  }

  ZeroCopyInputStream *input = new FileInputStream(file_descriptor);
  bool success = TextFormat::Parse(input, message);
  if (!success) {
    AERROR << "Failed to parse file " << file_name << " as text proto.";
  }
  delete input;
  close(file_descriptor);
  return success;
}

bool SetProtoToBinaryFile(const google::protobuf::Message &message,
                          const std::string &file_name) {
  std::fstream output(file_name,
                      std::ios::out | std::ios::trunc | std::ios::binary);
  return message.SerializeToOstream(&output);
}

bool GetProtoFromBinaryFile(const std::string &file_name,
                            google::protobuf::Message *message) {
  std::fstream input(file_name, std::ios::in | std::ios::binary);
  if (!input.good()) {
    AERROR << "Failed to open file " << file_name << " in binary mode.";
    return false;
  }
  if (!message->ParseFromIstream(&input)) {
    AERROR << "Failed to parse file " << file_name << " as binary proto.";
    return false;
  }
  return true;
}

bool GetProtoFromFile(const std::string &file_name,
                      google::protobuf::Message *message) {
  // Try the binary parser first if it's much likely a binary proto.
  static const std::string kBinExt = ".bin";
  if (std::equal(kBinExt.rbegin(), kBinExt.rend(), file_name.rbegin())) {
    return GetProtoFromBinaryFile(file_name, message) ||
           GetProtoFromASCIIFile(file_name, message);
  }

  return GetProtoFromASCIIFile(file_name, message) ||
         GetProtoFromBinaryFile(file_name, message);
}

bool GetContent(const std::string &file_name, std::string *content) {
  std::ifstream fin(file_name);
  if (!fin) {
    return false;
  }

  std::stringstream str_stream;
  str_stream << fin.rdbuf();
  *content = str_stream.str();
  return true;
}

std::string GetAbsolutePath(const std::string &prefix,
                            const std::string &relative_path) {
  if (relative_path.empty()) {
    return prefix;
  }
  // If prefix is empty or relative_path is already absolute.
  if (prefix.empty() || relative_path.front() == '/') {
    return relative_path;
  }

  if (prefix.back() == '/') {
    return prefix + relative_path;
  }
  return prefix + "/" + relative_path;
}

bool PathExists(const std::string &path) {
  struct stat info;
  return stat(path.c_str(), &info) == 0;
}

bool DirectoryExists(const std::string &directory_path) {
  struct stat info;
  if (stat(directory_path.c_str(), &info) != 0) {
    return false;
  }

  if (info.st_mode & S_IFDIR) {
    return true;
  }

  return false;
}

std::vector<std::string> Glob(const std::string &pattern) {
  glob_t globs = {};
  std::vector<std::string> results;
  if (0 == glob(pattern.c_str(), GLOB_TILDE, nullptr, &globs)) {
    for (size_t i = 0; i < globs.gl_pathc; ++i) {
      results.emplace_back(globs.gl_pathv[i]);
    }
  }
  globfree(&globs);
  return results;
}

bool CopyFile(const std::string &from, const std::string &to) {
  std::ifstream src(from, std::ios::binary);
  if (!src) {
    AERROR << "Source path doesn't exist: " << from;
    return false;
  }

  std::ofstream dst(to, std::ios::binary);
  if (!dst) {
    AERROR << "Target path is not writable: " << to;
    return false;
  }

  dst << src.rdbuf();
  return true;
}

bool CopyDir(const std::string &from, const std::string &to) {
  DIR *directory = opendir(from.c_str());
  if (directory == nullptr) {
    AERROR << "Cannot open directory " << from;
    return false;
  }

  bool ret = true;
  if (EnsureDirectory(to)) {
    struct dirent *entry;
    while ((entry = readdir(directory)) != nullptr) {
      // skip directory_path/. and directory_path/..
      if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
        continue;
      }
      const std::string sub_path_from = from + "/" + entry->d_name;
      const std::string sub_path_to = to + "/" + entry->d_name;
      if (entry->d_type == DT_DIR) {
        ret &= CopyDir(sub_path_from, sub_path_to);
      } else {
        ret &= CopyFile(sub_path_from, sub_path_to);
      }
    }
  } else {
    AERROR << "Cannot create target directory " << to;
    ret = false;
  }
  closedir(directory);
  return ret;
}

bool Copy(const std::string &from, const std::string &to) {
  return DirectoryExists(from) ? CopyDir(from, to) : CopyFile(from, to);
}

bool EnsureDirectory(const std::string &directory_path) {
  std::string path = directory_path;
  for (size_t i = 1; i < directory_path.size(); ++i) {
    if (directory_path[i] == '/') {
      // Whenever a '/' is encountered, create a temporary view from
      // the start of the path to the character right before this.
      path[i] = 0;

      if (mkdir(path.c_str(), S_IRWXU) != 0) {
        if (errno != EEXIST) {
          return false;
        }
      }

      // Revert the temporary view back to the original.
      path[i] = '/';
    }
  }

  // Make the final (full) directory.
  if (mkdir(path.c_str(), S_IRWXU) != 0) {
    if (errno != EEXIST) {
      return false;
    }
  }

  return true;
}

bool RemoveAllFiles(const std::string &directory_path) {
  DIR *directory = opendir(directory_path.c_str());
  if (directory == nullptr) {
    AERROR << "Cannot open directory " << directory_path;
    return false;
  }

  struct dirent *file;
  while ((file = readdir(directory)) != nullptr) {
    // skip directory_path/. and directory_path/..
    if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) {
      continue;
    }
    // build the path for each file in the folder
    std::string file_path = directory_path + "/" + file->d_name;
    if (unlink(file_path.c_str()) < 0) {
      AERROR << "Fail to remove file " << file_path << ": " << strerror(errno);
      closedir(directory);
      return false;
    }
  }
  closedir(directory);
  return true;
}

std::vector<std::string> ListSubPaths(const std::string &directory_path,
                                      const unsigned char d_type) {
  std::vector<std::string> result;
  DIR *directory = opendir(directory_path.c_str());
  if (directory == nullptr) {
    AERROR << "Cannot open directory " << directory_path;
    return result;
  }

  struct dirent *entry;
  while ((entry = readdir(directory)) != nullptr) {
    // Skip "." and "..".
    if (entry->d_type == d_type && strcmp(entry->d_name, ".") != 0 &&
        strcmp(entry->d_name, "..") != 0) {
      result.emplace_back(entry->d_name);
    }
  }
  closedir(directory);
  return result;
}

std::string GetFileName(const std::string &path, const bool remove_extension) {
  std::string::size_type start = path.rfind('/');
  if (start == std::string::npos) {
    start = 0;
  } else {
    // Move to the next char after '/'.
    ++start;
  }

  std::string::size_type end = std::string::npos;
  if (remove_extension) {
    end = path.rfind('.');
    // The last '.' is found before last '/', ignore.
    if (end != std::string::npos && end < start) {
      end = std::string::npos;
    }
  }
  const auto len = (end != std::string::npos) ? end - start : end;
  return path.substr(start, len);
}

std::string GetCurrentPath() {
  char tmp[PATH_MAX];
  if (getcwd(tmp, sizeof(tmp)) != NULL) {
    return std::string(tmp);
  } else {
    return std::string("");
  }
}

}  // namespace common
}  // namespace cyber
}  // namespace apollo
<|endoftext|>