eapol/eapol_framework/eapol_common/include/eap_array.h
changeset 0 c8830336c852
child 2 1c7bc153c08e
equal deleted inserted replaced
-1:000000000000 0:c8830336c852
       
     1 /*
       
     2 * Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  EAP and WLAN authentication protocols.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #if !defined(_EAP_ARRAY_H_)
       
    22 #define _EAP_ARRAY_H_
       
    23 
       
    24 #include "eap_am_memory.h"
       
    25 #include "eap_tools.h"
       
    26 #include "eap_am_tools.h"
       
    27 #include "eap_am_export.h"
       
    28 
       
    29 #if defined(_WIN32) && !defined(__GNUC__)
       
    30 	#pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients
       
    31 #endif
       
    32 
       
    33 #define EAP_ARRAY_SANITY_CHECK(this) \
       
    34 	{ \
       
    35 		EAP_ASSERT(((this)->m_head == 0 && (this)->m_tail == 0 && (this)->m_object_count == 0) \
       
    36 				   || ((this)->m_head != 0 && (this)->m_tail != 0 && (this)->m_object_count != 0)); \
       
    37 		\
       
    38 		EAP_ASSERT(((this)->m_object_count == 0 && (this)->m_head == 0) \
       
    39 				   || ((this)->m_object_count == 1 && (this)->m_head != 0 \
       
    40 					   && (this)->m_head == (this)->m_tail && (this)->m_head->get_next_atom() == 0) \
       
    41 				   || ((this)->m_object_count > 1 && (this)->m_head != 0 \
       
    42 					   && (this)->m_head != (this)->m_tail && (this)->m_head->get_next_atom() != 0)); \
       
    43 		\
       
    44 		EAP_ASSERT(((this)->m_object_count == 0 && (this)->m_tail == 0) \
       
    45 				   || ((this)->m_object_count != 0 && (this)->m_tail != 0 && (this)->m_tail->get_next_atom() == 0)); \
       
    46 	}
       
    47 
       
    48 //----------------------------------------------------------------------------------------
       
    49 
       
    50 /**
       
    51  * The eap_array_atom_c is a template class for single object stored to eap_array_c array.
       
    52  * The array objects are stored as a linked list.
       
    53  * @param Type template parameter is the actual type which is stored.
       
    54  */
       
    55 template <class Type>
       
    56 class EAP_EXPORT eap_array_atom_c
       
    57 {
       
    58 private:
       
    59 
       
    60 	/// This is pointer to the tools class. 
       
    61 	abs_eap_am_tools_c * m_am_tools;
       
    62 
       
    63 	/// This is the pointer to the actual object
       
    64 	Type *m_data;
       
    65 
       
    66 	/// Linked list pointer to the next atom
       
    67 	eap_array_atom_c<Type> *m_next_atom;
       
    68 
       
    69 	/// This flag indicates whether eap_array deletes the stored object when it is destroyed.
       
    70 	bool m_free_atom;
       
    71 
       
    72 public:
       
    73 	
       
    74 	/**
       
    75 	 * The destructor deletes the object in this atom if necessary.	 
       
    76 	 */	
       
    77 	virtual ~eap_array_atom_c()
       
    78 	{
       
    79 		m_am_tools = 0;
       
    80 
       
    81 		if (m_data != 0 
       
    82 			&& m_free_atom == true)
       
    83 		{
       
    84 			delete m_data;
       
    85 			m_data = 0;
       
    86 		}
       
    87 	}
       
    88 	
       
    89 	/**
       
    90 	 * The constructor sets the values for the member variables
       
    91 	 */	
       
    92 	eap_array_atom_c(
       
    93 		abs_eap_am_tools_c * const tools,
       
    94 		Type * const p_data,
       
    95 		const bool free_atom)
       
    96 		: m_am_tools(tools)
       
    97 		, m_data(p_data)	
       
    98 		, m_next_atom(0)
       
    99 		, m_free_atom(free_atom)
       
   100 	{
       
   101 	}
       
   102 
       
   103 	//
       
   104 	Type * const get_data()
       
   105 	{
       
   106 		return m_data;
       
   107 	}
       
   108 
       
   109 	//
       
   110 	void set_data(Type * const p_data)
       
   111 	{
       
   112 		m_data = p_data;
       
   113 	}
       
   114 
       
   115 	eap_array_atom_c * const get_next_atom() const
       
   116 	{
       
   117 		return m_next_atom;
       
   118 	}
       
   119 	
       
   120 	void set_next_atom(eap_array_atom_c<Type> * const next)
       
   121 	{
       
   122 		m_next_atom = next;
       
   123 	}
       
   124 };
       
   125 
       
   126 //----------------------------------------------------------------------------------------
       
   127 
       
   128 /**
       
   129   * The eap_array_c template class includes an array for type of Type objects.
       
   130   * The objects can be added, retrieved and their count can be queried.
       
   131   * @param Type template parameter is the actual type which is stored.
       
   132   */
       
   133 template <class Type>
       
   134 class EAP_EXPORT eap_array_c
       
   135 {
       
   136 private:
       
   137 	//--------------------------------------------------
       
   138 
       
   139 	/// This is pointer to the tools class. 
       
   140 	abs_eap_am_tools_c * m_am_tools;
       
   141 
       
   142 	/// Head pointer for the object atom linked list. 
       
   143 	eap_array_atom_c<Type> *m_head;
       
   144 
       
   145 	/// Tail pointer for the object atom linked list. 
       
   146 	eap_array_atom_c<Type> *m_tail;
       
   147 
       
   148 	/// This is the number of objects
       
   149 	u32_t m_object_count;
       
   150 
       
   151 	//--------------------------------------------------
       
   152 protected:
       
   153 	//--------------------------------------------------
       
   154 
       
   155 	//--------------------------------------------------
       
   156 public:
       
   157 	//--------------------------------------------------
       
   158 
       
   159 	/**
       
   160 	 * The constructor initializes attributes using the passed parameter.
       
   161 	 * @param tools is pointer to the tools class. @see abs_eap_am_tools_c.
       
   162 	 */
       
   163 	eap_array_c(
       
   164 		abs_eap_am_tools_c * const tools)
       
   165 		: m_am_tools(tools)
       
   166 		, m_head(0)
       
   167 		, m_tail(0)
       
   168 		, m_object_count(0)
       
   169 	{		
       
   170 	}
       
   171 
       
   172 	/**
       
   173 	 * Destructor deletes all atoms.
       
   174 	 */		
       
   175 	virtual ~eap_array_c()
       
   176 	{
       
   177 		(void) reset();
       
   178 		m_am_tools = 0;
       
   179 	}
       
   180 
       
   181 	// NOTE: This operator is NOT supported. This is unplemented prototype to cause linker error if assigment operator is used.
       
   182 	eap_array_c<Type> &operator = (const eap_array_c<Type> &right_type_value);
       
   183 
       
   184 
       
   185 	/**
       
   186 	 * reset() deletes all atoms.
       
   187 	 */		
       
   188 	eap_status_e reset()
       
   189 	{
       
   190 		EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   191 
       
   192 		EAP_ARRAY_SANITY_CHECK(this);
       
   193 
       
   194 		if (m_head == 0)
       
   195 		{
       
   196 			// The array is empty
       
   197 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   198 			return eap_status_ok;
       
   199 		}
       
   200 
       
   201 		eap_array_atom_c<Type> *current;
       
   202 		eap_array_atom_c<Type> *last;
       
   203 
       
   204 		// Go through the linked list and delete all
       
   205 		current = m_head;
       
   206 
       
   207 		while (current != 0)
       
   208 		{
       
   209 			last = current;
       
   210 			current = last->get_next_atom();
       
   211 			delete last;
       
   212 		}
       
   213 
       
   214 		m_object_count = 0UL;
       
   215 		m_head = 0;
       
   216 		m_tail = 0;
       
   217 
       
   218 		EAP_ARRAY_SANITY_CHECK(this);
       
   219 
       
   220 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   221 		return eap_status_ok;
       
   222 	}
       
   223 
       
   224 	/**
       
   225 	 * The function add_object_to_begin() adds one new object to the begin of the array.
       
   226 	 * @param object is pointer to the added object
       
   227 	 * @param m_free_object is flag that indicates whether the object should be deleted by eap_array_c
       
   228 	 */		
       
   229 	eap_status_e add_object_to_begin(
       
   230 		Type * const object,
       
   231 		const bool m_free_object)
       
   232 	{
       
   233 		EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   234 
       
   235 		eap_array_atom_c<Type> *atom;
       
   236 
       
   237 		if (object == 0)
       
   238 		{
       
   239 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   240 		}
       
   241 
       
   242 		EAP_ARRAY_SANITY_CHECK(this);
       
   243 
       
   244 		atom = new eap_array_atom_c<Type>(m_am_tools, object, m_free_object);
       
   245 		if (atom == 0
       
   246 			|| object == 0)
       
   247 		{
       
   248 			if (m_free_object == true)
       
   249 			{
       
   250 				delete object;
       
   251 			}
       
   252 
       
   253 			EAP_ARRAY_SANITY_CHECK(this);
       
   254 
       
   255 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   256 		}
       
   257 
       
   258 		// Check if this is the first item
       
   259 		if (m_head == 0)
       
   260 		{
       
   261 			// Yes
       
   262 			m_head = atom;
       
   263 			m_tail = atom;
       
   264 		}
       
   265 		else 
       
   266 		{
       
   267 			// No. Add it to the begin.
       
   268 			atom->set_next_atom(m_head);
       
   269 			m_head = atom;
       
   270 		}
       
   271 
       
   272 		m_object_count++;
       
   273 
       
   274 		EAP_ARRAY_SANITY_CHECK(this);
       
   275 
       
   276 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   277 		return eap_status_ok;
       
   278 	}
       
   279 
       
   280 	/**
       
   281 	 * The function add_object() adds one new object to the array.
       
   282 	 * @param object is pointer to the added object
       
   283 	 * @param m_free_object is flag that indicates whether the object should be deleted by eap_array_c
       
   284 	 */		
       
   285 	eap_status_e add_object(
       
   286 		Type * const object,
       
   287 		const bool m_free_object)
       
   288 	{
       
   289 		EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   290 
       
   291 		eap_array_atom_c<Type> *atom;
       
   292 
       
   293 		if (object == 0)
       
   294 		{
       
   295 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   296 		}
       
   297 
       
   298 		EAP_ARRAY_SANITY_CHECK(this);
       
   299 
       
   300 		atom = new eap_array_atom_c<Type>(m_am_tools, object, m_free_object);
       
   301 		if (atom == 0)
       
   302 		{
       
   303 			if (m_free_object == true)
       
   304 			{
       
   305 				delete object;
       
   306 			}
       
   307 
       
   308 			EAP_ARRAY_SANITY_CHECK(this);
       
   309 
       
   310 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   311 		}
       
   312 
       
   313 		// Check if this is the first item
       
   314 		if (m_head == 0)
       
   315 		{
       
   316 			// Yes
       
   317 			m_head = atom;
       
   318 			m_tail = atom;
       
   319 		}
       
   320 		else 
       
   321 		{
       
   322 			// No. Add it to the end.
       
   323 			m_tail->set_next_atom(atom);
       
   324 			m_tail = atom;
       
   325 		}
       
   326 
       
   327 		m_object_count++;
       
   328 
       
   329 		EAP_ARRAY_SANITY_CHECK(this);
       
   330 
       
   331 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   332 		return eap_status_ok;
       
   333 	}
       
   334 
       
   335 	/**
       
   336 	 * The get_object() function returns object based on the index given.
       
   337 	 * @param index Indicates which object pointer is returned
       
   338 	 * @return Object pointer
       
   339 	 */			
       
   340 	Type * const get_object(const u32_t index) const
       
   341 	{
       
   342 		EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   343 		EAP_ASSERT_ALWAYS(index < get_object_count());
       
   344 
       
   345 		EAP_ARRAY_SANITY_CHECK(this);
       
   346 
       
   347 		eap_array_atom_c<Type> *atom;
       
   348 		Type *object = 0;
       
   349 		atom = m_head;
       
   350 		u32_t i = 0;
       
   351 
       
   352 		// find the object needed by stepping through the array.
       
   353 		while (atom != 0)
       
   354 		{	
       
   355 			// Is this the correct one?
       
   356 			if (index == i)
       
   357 			{
       
   358 				// Yes.
       
   359 				object = atom->get_data();
       
   360 				break;
       
   361 			}
       
   362 
       
   363 			// Nope. Get the next one
       
   364 			i++;
       
   365 			atom = atom->get_next_atom();
       
   366 		}
       
   367 
       
   368 		EAP_ARRAY_SANITY_CHECK(this);
       
   369 
       
   370 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   371 		return object;
       
   372 	}
       
   373 
       
   374 	/**
       
   375 	 * The remove_object() function removes object based on the index given.
       
   376 	 * @param index Indicates which object pointer is returned
       
   377 	 * @return Object pointer
       
   378 	 */			
       
   379 	eap_status_e remove_object(const u32_t index)
       
   380 	{
       
   381 		EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   382 		EAP_ASSERT_ALWAYS(index < get_object_count());
       
   383 
       
   384 		EAP_ARRAY_SANITY_CHECK(this);
       
   385 
       
   386 		eap_array_atom_c<Type> *atom;
       
   387 		eap_array_atom_c<Type> *prev_atom = 0;
       
   388 		atom = m_head;
       
   389 		u32_t i = 0;
       
   390 		eap_status_e status = eap_status_illegal_index;
       
   391 
       
   392 		// find the object needed by stepping through the array.
       
   393 		while (atom != 0)
       
   394 		{	
       
   395 			// Is this the correct one?
       
   396 			if (index == i)
       
   397 			{
       
   398 				// Yes.
       
   399 				if (index == 0
       
   400 					&& prev_atom == 0)
       
   401 				{
       
   402 					// this is the first on the array.
       
   403 					m_head = atom->get_next_atom();
       
   404 					if (m_head == 0)
       
   405 					{
       
   406 						m_tail = 0;
       
   407 					}
       
   408 				}
       
   409 				else
       
   410 				{
       
   411 					prev_atom->set_next_atom(atom->get_next_atom());
       
   412 				}
       
   413 
       
   414 				if (m_tail == atom)
       
   415 				{
       
   416 					// This is the last on the array.
       
   417 					m_tail = prev_atom;
       
   418 				}
       
   419 
       
   420 				delete atom;
       
   421 				--m_object_count;
       
   422 
       
   423 				EAP_ARRAY_SANITY_CHECK(this);
       
   424 
       
   425 				status = eap_status_ok;
       
   426 				break;
       
   427 			}
       
   428 
       
   429 			// Nope. Get the next one
       
   430 			i++;
       
   431 			prev_atom = atom;
       
   432 			atom = atom->get_next_atom();
       
   433 
       
   434 		} // while()
       
   435 
       
   436 		EAP_ARRAY_SANITY_CHECK(this);
       
   437 
       
   438 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   439 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   440 	}
       
   441 
       
   442 	/**
       
   443 	 * The get_object_count() function returns the number of objects in the array.
       
   444 	 * @return number of objects
       
   445 	 */			
       
   446 	const u32_t get_object_count() const
       
   447 	{
       
   448 		EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   449 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   450 		return m_object_count;
       
   451 	}
       
   452 
       
   453 	/**
       
   454 	 * Gets last object.
       
   455 	 * @return Object pointer or null if array is empty.
       
   456 	 */			
       
   457 	Type * const get_last_object() const
       
   458 	{
       
   459 		EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   460 
       
   461 		EAP_ARRAY_SANITY_CHECK(this);
       
   462 
       
   463 		// find the object needed by stepping through the array.
       
   464 		if (get_object_count() > 0UL
       
   465 			&& m_tail != 0)
       
   466 		{	
       
   467 			// Yes.
       
   468 			Type * const object = m_tail->get_data();
       
   469 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   470 			return object;
       
   471 		}
       
   472 		else
       
   473 		{
       
   474 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   475 			return 0;
       
   476 		}
       
   477 	}
       
   478 
       
   479 	//--------------------------------------------------
       
   480 }; // class eap_array_c
       
   481 
       
   482 //----------------------------------------------------------------------------------------
       
   483 
       
   484 #endif //#if !defined(_EAP_ARRAY_H_)
       
   485 
       
   486 
       
   487 
       
   488 
       
   489 // End.