13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements C++ Base Library
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -----------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Array buffer
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deArrayBuffer.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_VALGRIND_BUILD) && defined(HAVE_VALGRIND_MEMCHECK_H)
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	include <valgrind/memcheck.h>
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace de
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace detail
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid* ArrayBuffer_AlignedMalloc (size_t numBytes, size_t alignment)
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	sizeAsInt	= (int)numBytes;
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void*		ptr;
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// int overflow
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (sizeAsInt < 0 || numBytes != (size_t)sizeAsInt)
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw std::bad_alloc();
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// alloc
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ptr = deAlignedMalloc(sizeAsInt, (int)alignment);
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!ptr)
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw std::bad_alloc();
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// mark area as undefined for valgrind
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if defined(DE_VALGRIND_BUILD) && defined(HAVE_VALGRIND_MEMCHECK_H)
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (RUNNING_ON_VALGRIND)
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VALGRIND_MAKE_MEM_UNDEFINED(ptr, numBytes);
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ptr;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ArrayBuffer_AlignedFree (void* ptr)
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deAlignedFree(ptr);
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // detail
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ArrayBuffer_selfTest (void)
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// default constructor
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> buf;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(buf.size() == 0);
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(buf.getPtr() == DE_NULL);
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// sized constructor
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> buf(4);
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(buf.size() == 4);
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(buf.getPtr() != DE_NULL);
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// copy constructor
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> originalBuf(4);
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*originalBuf.getElementPtr(0) = 1;
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*originalBuf.getElementPtr(1) = 2;
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*originalBuf.getElementPtr(2) = 3;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*originalBuf.getElementPtr(3) = 4;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> targetBuf(originalBuf);
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*originalBuf.getElementPtr(0) == 1);
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*originalBuf.getElementPtr(1) == 2);
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*originalBuf.getElementPtr(2) == 3);
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*originalBuf.getElementPtr(3) == 4);
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*targetBuf.getElementPtr(0) == 1);
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*targetBuf.getElementPtr(1) == 2);
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*targetBuf.getElementPtr(2) == 3);
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*targetBuf.getElementPtr(3) == 4);
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// assignment
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> originalBuf(4);
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*originalBuf.getElementPtr(0) = 1;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*originalBuf.getElementPtr(1) = 2;
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*originalBuf.getElementPtr(2) = 3;
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*originalBuf.getElementPtr(3) = 4;
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> targetBuf(1);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		targetBuf = originalBuf;
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*originalBuf.getElementPtr(0) == 1);
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*originalBuf.getElementPtr(1) == 2);
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*originalBuf.getElementPtr(2) == 3);
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*originalBuf.getElementPtr(3) == 4);
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*targetBuf.getElementPtr(0) == 1);
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*targetBuf.getElementPtr(1) == 2);
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*targetBuf.getElementPtr(2) == 3);
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*targetBuf.getElementPtr(3) == 4);
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// clear
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> buf(4);
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf.clear();
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(buf.size() == 0);
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(buf.getPtr() == DE_NULL);
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// setStorage
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> buf(4);
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf.setStorage(12);
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(buf.size() == 12);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(buf.getPtr() != DE_NULL);
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// setStorage, too large
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> buf(4);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*buf.getElementPtr(0) = 1;
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*buf.getElementPtr(1) = 2;
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*buf.getElementPtr(2) = 3;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*buf.getElementPtr(3) = 4;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		try
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buf.setStorage((size_t)-1);
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// setStorage succeeded, all ok
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		catch (std::bad_alloc&)
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// alloc failed, check storage not changed
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_TEST_ASSERT(buf.size() == 4);
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_TEST_ASSERT(*buf.getElementPtr(0) == 1);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_TEST_ASSERT(*buf.getElementPtr(1) == 2);
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_TEST_ASSERT(*buf.getElementPtr(2) == 3);
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_TEST_ASSERT(*buf.getElementPtr(3) == 4);
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// swap
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> buf;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> source(4);
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*source.getElementPtr(0) = 1;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*source.getElementPtr(1) = 2;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*source.getElementPtr(2) = 3;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*source.getElementPtr(3) = 4;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buf.swap(source);
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(source.size() == 0);
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(buf.size() == 4);
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*buf.getElementPtr(0) == 1);
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*buf.getElementPtr(1) == 2);
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*buf.getElementPtr(2) == 3);
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(*buf.getElementPtr(3) == 4);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// default
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int> source(4);
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int dst;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*source.getElementPtr(1) = 2;
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(&dst, (int*)source.getPtr() + 1, sizeof(int));
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(dst == 2);
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Aligned
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int, 64, sizeof(int)> source(4);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int dst;
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*source.getElementPtr(1) = 2;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(&dst, (int*)source.getPtr() + 1, sizeof(int));
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(dst == 2);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Strided
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int, 4, 64> source(4);
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int dst;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*source.getElementPtr(1) = 2;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(&dst, (deUint8*)source.getPtr() + 64, sizeof(int));
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(dst == 2);
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Aligned, Strided
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		de::ArrayBuffer<int, 32, 64> source(4);
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int dst;
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*source.getElementPtr(1) = 2;
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(&dst, (deUint8*)source.getPtr() + 64, sizeof(int));
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_TEST_ASSERT(dst == 2);
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // de
234