<commit_before>/*
 * Copyright 2004-2014 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is 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.
 */

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include "stringutil.h"

#include "misc.h"

#include <inttypes.h>

static ChainHashMap<const char*, StringHashFns, const char*> chapelStringsTable;

static const char*
canonicalize_string(const char *s) {
  const char* ss = chapelStringsTable.get(s);
  if (!ss) {
    chapelStringsTable.put(s, s);
    return s;
  }
  return ss;
}

const char*
astr(const char* s1, const char* s2, const char* s3, const char* s4,
     const char* s5, const char* s6, const char* s7, const char* s8) {
  int len;
  len = strlen(s1);
  if (s2)
    len += strlen(s2);
  if (s3)
    len += strlen(s3);
  if (s4)
    len += strlen(s4);
  if (s5)
    len += strlen(s5);
  if (s6)
    len += strlen(s6);
  if (s7)
    len += strlen(s7);
  if (s8)
    len += strlen(s8);
  char* s = (char*)malloc(len+1);
  strcpy(s, s1);
  if (s2)
    strcat(s, s2);
  if (s3)
    strcat(s, s3);
  if (s4)
    strcat(s, s4);
  if (s5)
    strcat(s, s5);
  if (s6)
    strcat(s, s6);
  if (s7)
    strcat(s, s7);
  if (s8)
    strcat(s, s8);
  const char* t = canonicalize_string(s);
  if (s != t)
    free(s);
  return t;
}

const char*
istr(int i) {
  char s[64];
  if (sprintf(s, "%d", i) > 63)
    INT_FATAL("istr buffer overflow");
  return astr(s);
}

//
// returns a canonicalized substring that contains the first part of
// 's' up to 'e'
// note: e must be in s
//
const char* asubstr(const char* s, const char* e) {
  char* ss = (char*)malloc(e-s+1);
  strncpy(ss, s, e-s);
  ss[e-s] = '\0';
  const char* t = canonicalize_string(ss);
  if (ss != t)
    free(ss);
  return t;
}

void deleteStrings() {
  Vec<const char*> keys;
  chapelStringsTable.get_keys(keys);
  forv_Vec(const char, key, keys) {
    free(const_cast<char*>(key));
  }
}

#define define_str2Int(type, format)                              \
  type##_t str2##type(const char* str) {                          \
    if (!str) {                                                   \
      INT_FATAL("NULL string passed to strTo_" #type "()");       \
    }                                                             \
    int len = strlen(str);                                        \
    if (len < 1) {                                                \
      INT_FATAL("empty string passed to strTo_" #type "()");      \
    }                                                             \
    type##_t val;                                                 \
    int numitems = sscanf(str, format, &val);                     \
    if (numitems != 1) {                                          \
      INT_FATAL("Illegal string passed to strTo_" #type "()");    \
    }                                                             \
    return val;                                                   \
  }

define_str2Int(int8, "%" SCNd8)
define_str2Int(int16, "%" SCNd16)
define_str2Int(int32, "%" SCNd32)
define_str2Int(int64, "%" SCNd64)
define_str2Int(uint8, "%" SCNu8)
define_str2Int(uint16, "%" SCNu16)
define_str2Int(uint32, "%" SCNu32)
define_str2Int(uint64, "%" SCNu64)

uint64_t binStr2uint64(const char* str) {
  if (!str) {
    INT_FATAL("NULL string passed to binStrToUint64()");
  }
  int len = strlen(str);
  if (len < 3 || str[0] != '0' || (str[1] != 'b' && str[1] != 'B')) {
    INT_FATAL("Illegal string passed to binStrToUint64()");
  }
  uint64_t val = 0;
  for (int i=2; i<len; i++) {
    val <<= 1;
    switch (str[i]) {
    case '0':
      break;
    case '1':
      val += 1;
      break;
    default:
      INT_FATAL("illegal character in binary string: '%c'", str[i]);
    }
  }
  return val;
}

uint64_t octStr2uint64(const char* str) {
  if (!str) {
    INT_FATAL("NULL string passed to octStrToUint64()");
  }
  int len = strlen(str);
  if (len < 3 || str[0] != '0' || (str[1] != 'o' && str[1] != 'O')) {
    INT_FATAL("Illegal string passed to octStrToUint64()");
  }
  uint64_t val = strtoll(str+2, NULL, 8);
  // Strtol converts the string to a number with base provided, in this case 8
  return val;
}

uint64_t hexStr2uint64(const char* str) {
  if (!str) {
    INT_FATAL("NULL string passed to hexStrToUint64()");
  }
  int len = strlen(str);
  if (len < 3 || str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
    INT_FATAL("Illegal string passed to hexStrToUint64()");
  }
  uint64_t val;
  int numitems = sscanf(str+2, "%"SCNx64, &val);
  if (numitems != 1) {
    INT_FATAL("Illegal string passed to hexStrToUint64");
  }
  return val;
}
<commit_msg>Take Brad's implementation comments into account.<commit_after>/*
 * Copyright 2004-2014 Cray Inc.
 * Other additional copyright holders may be indicated within.
 *
 * The entirety of this work is 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.
 */

#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include "stringutil.h"

#include "misc.h"

#include <inttypes.h>

static ChainHashMap<const char*, StringHashFns, const char*> chapelStringsTable;

static const char*
canonicalize_string(const char *s) {
  const char* ss = chapelStringsTable.get(s);
  if (!ss) {
    chapelStringsTable.put(s, s);
    return s;
  }
  return ss;
}

const char*
astr(const char* s1, const char* s2, const char* s3, const char* s4,
     const char* s5, const char* s6, const char* s7, const char* s8) {
  int len;
  len = strlen(s1);
  if (s2)
    len += strlen(s2);
  if (s3)
    len += strlen(s3);
  if (s4)
    len += strlen(s4);
  if (s5)
    len += strlen(s5);
  if (s6)
    len += strlen(s6);
  if (s7)
    len += strlen(s7);
  if (s8)
    len += strlen(s8);
  char* s = (char*)malloc(len+1);
  strcpy(s, s1);
  if (s2)
    strcat(s, s2);
  if (s3)
    strcat(s, s3);
  if (s4)
    strcat(s, s4);
  if (s5)
    strcat(s, s5);
  if (s6)
    strcat(s, s6);
  if (s7)
    strcat(s, s7);
  if (s8)
    strcat(s, s8);
  const char* t = canonicalize_string(s);
  if (s != t)
    free(s);
  return t;
}

const char*
istr(int i) {
  char s[64];
  if (sprintf(s, "%d", i) > 63)
    INT_FATAL("istr buffer overflow");
  return astr(s);
}

//
// returns a canonicalized substring that contains the first part of
// 's' up to 'e'
// note: e must be in s
//
const char* asubstr(const char* s, const char* e) {
  char* ss = (char*)malloc(e-s+1);
  strncpy(ss, s, e-s);
  ss[e-s] = '\0';
  const char* t = canonicalize_string(ss);
  if (ss != t)
    free(ss);
  return t;
}

void deleteStrings() {
  Vec<const char*> keys;
  chapelStringsTable.get_keys(keys);
  forv_Vec(const char, key, keys) {
    free(const_cast<char*>(key));
  }
}

#define define_str2Int(type, format)                              \
  type##_t str2##type(const char* str) {                          \
    if (!str) {                                                   \
      INT_FATAL("NULL string passed to strTo_" #type "()");       \
    }                                                             \
    int len = strlen(str);                                        \
    if (len < 1) {                                                \
      INT_FATAL("empty string passed to strTo_" #type "()");      \
    }                                                             \
    type##_t val;                                                 \
    int numitems = sscanf(str, format, &val);                     \
    if (numitems != 1) {                                          \
      INT_FATAL("Illegal string passed to strTo_" #type "()");    \
    }                                                             \
    return val;                                                   \
  }

define_str2Int(int8, "%" SCNd8)
define_str2Int(int16, "%" SCNd16)
define_str2Int(int32, "%" SCNd32)
define_str2Int(int64, "%" SCNd64)
define_str2Int(uint8, "%" SCNu8)
define_str2Int(uint16, "%" SCNu16)
define_str2Int(uint32, "%" SCNu32)
define_str2Int(uint64, "%" SCNu64)

uint64_t binStr2uint64(const char* str) {
  if (!str) {
    INT_FATAL("NULL string passed to binStrToUint64()");
  }
  int len = strlen(str);
  if (len < 3 || str[0] != '0' || (str[1] != 'b' && str[1] != 'B')) {
    INT_FATAL("Illegal string passed to binStrToUint64()");
  }
  uint64_t val = 0;
  for (int i=2; i<len; i++) {
    val <<= 1;
    switch (str[i]) {
    case '0':
      break;
    case '1':
      val += 1;
      break;
    default:
      INT_FATAL("illegal character in binary string: '%c'", str[i]);
    }
  }
  return val;
}

uint64_t octStr2uint64(const char* str) {
  if (!str) {
    INT_FATAL("NULL string passed to octStrToUint64()");
  }
  int len = strlen(str);
  if (len < 3 || str[0] != '0' || (str[1] != 'o' && str[1] != 'O')) {
    INT_FATAL("Illegal string passed to octStrToUint64()");
  }
  uint64_t val = strtoul(str+2, NULL, 8);
  // strtoul() converts the string to a number with base provided, in this
  // case 8
  return val;
}

uint64_t hexStr2uint64(const char* str) {
  if (!str) {
    INT_FATAL("NULL string passed to hexStrToUint64()");
  }
  int len = strlen(str);
  if (len < 3 || str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
    INT_FATAL("Illegal string passed to hexStrToUint64()");
  }
  uint64_t val;
  int numitems = sscanf(str+2, "%"SCNx64, &val);
  if (numitems != 1) {
    INT_FATAL("Illegal string passed to hexStrToUint64");
  }
  return val;
}
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// File: TestMatrixStoragePolicies.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description:
//
///////////////////////////////////////////////////////////////////////////////

#include <UnitTests/LibUtilities/TestMatrixStoragePolicies.h>
#include <LibUtilities/LinearAlgebra/NekMatrix.hpp>

#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/unit_test.hpp>

#include <boost/test/auto_unit_test.hpp>

namespace Nektar
{
    namespace UpperTriangularUnitTests
    {
        typedef MatrixStoragePolicy<NekDouble, UpperTriangularMatrixTag> Policy;

        void Test0ParameterInitialize()
        {
            Array<OneD, NekDouble> result = Policy::Initialize();
            BOOST_CHECK_EQUAL(result.num_elements(), 0);
            BOOST_CHECK_EQUAL(result.GetOffset(), 0);
            BOOST_CHECK(result.data() != 0);
        }

        void Test2ParameterInitialize()
        {
            {
                Array<OneD, NekDouble> result = Policy::Initialize(5, 5);
                BOOST_CHECK_EQUAL(result.num_elements(), 15);
            }

            {
                BOOST_CHECK_THROW( (Policy::Initialize(5,6)), ErrorUtil::NekError);
                BOOST_CHECK_THROW( (Policy::Initialize(6,5)), ErrorUtil::NekError);
            }
        }

        void TestSingleValuePopulationInitialize()
        {
            {
                Array<OneD, NekDouble> result = Policy::Initialize(5, 5, 7.2);
                BOOST_CHECK_EQUAL(result.num_elements(), 15);
                for(Array<OneD, NekDouble>::iterator iter = result.begin(); iter != result.end(); ++iter)
                {
                    BOOST_CHECK_EQUAL(*iter, 7.2);
                }
            }

            {
                BOOST_CHECK_THROW( (Policy::Initialize(5,6,7.2)), ErrorUtil::NekError);
                BOOST_CHECK_THROW( (Policy::Initialize(6,5,7.2)), ErrorUtil::NekError);
            }
        }

        void TestCArrayInitialization()
        {
            NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0};

            {
                Array<OneD, NekDouble> result = Policy::Initialize(3, 3, buf);
                BOOST_CHECK_EQUAL(result.num_elements(), 6);

                BOOST_CHECK_EQUAL(result[0], 1.0);
                BOOST_CHECK_EQUAL(result[1], 2.0);
                BOOST_CHECK_EQUAL(result[2], 3.0);
                BOOST_CHECK_EQUAL(result[3], 5.0);
                BOOST_CHECK_EQUAL(result[4], 6.0);
                BOOST_CHECK_EQUAL(result[5], 9.0);
            }

            {

                BOOST_CHECK_THROW( (Policy::Initialize(5,6,buf)), ErrorUtil::NekError);
                BOOST_CHECK_THROW( (Policy::Initialize(6,5,buf)), ErrorUtil::NekError);
            }
        }

        void TestArrayInitialization()
        {
            NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0};
            Array<OneD, NekDouble> array_buf(6, buf);

            {
                Array<OneD, NekDouble> result = Policy::Initialize(3, 3, array_buf);
                BOOST_CHECK_EQUAL(result.num_elements(), 6);

                BOOST_CHECK_EQUAL(result[0], 1.0);
                BOOST_CHECK_EQUAL(result[1], 2.0);
                BOOST_CHECK_EQUAL(result[2], 3.0);
                BOOST_CHECK_EQUAL(result[3], 5.0);
                BOOST_CHECK_EQUAL(result[4], 6.0);
                BOOST_CHECK_EQUAL(result[5], 9.0);
            }

            {

                BOOST_CHECK_THROW( (Policy::Initialize(5,6,buf)), ErrorUtil::NekError);
                BOOST_CHECK_THROW( (Policy::Initialize(6,5,buf)), ErrorUtil::NekError);
            }

            {
                NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0, 10.0};
                Array<OneD, NekDouble> array_buf(7, buf);
                BOOST_CHECK_NO_THROW(Policy::Initialize(3, 3, array_buf));
            }

            {
                NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0, 10.0};
                Array<OneD, NekDouble> array_buf(5, buf);
                BOOST_CHECK_THROW(Policy::Initialize(3, 3, array_buf), ErrorUtil::NekError);
            }
        }

        void TestConstGetValue()
        {
            NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0};
            Array<OneD, NekDouble> array_buf(6, buf);
            Array<OneD, NekDouble> data = Policy::Initialize(3, 3, array_buf);
            BOOST_CHECK_EQUAL(data.num_elements(), 6);

            {
                BOOST_CHECK_EQUAL(1.0, Policy::GetValue(3, 3, 0, 0, data));
                BOOST_CHECK_EQUAL(2.0, Policy::GetValue(3, 3, 0, 1, data));
                BOOST_CHECK_EQUAL(3.0, Policy::GetValue(3, 3, 0, 2, data));
                BOOST_CHECK_EQUAL(0.0, Policy::GetValue(3, 3, 1, 0, data));
                BOOST_CHECK_EQUAL(5.0, Policy::GetValue(3, 3, 1, 1, data));
                BOOST_CHECK_EQUAL(6.0, Policy::GetValue(3, 3, 1, 2, data));
                BOOST_CHECK_EQUAL(0.0, Policy::GetValue(3, 3, 2, 0, data));
                BOOST_CHECK_EQUAL(0.0, Policy::GetValue(3, 3, 2, 1, data));
                BOOST_CHECK_EQUAL(9.0, Policy::GetValue(3, 3, 2, 2, data));
            }

            #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
            {
                BOOST_CHECK_THROW(Policy::GetValue(3,4,3,3,data), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::GetValue(3,3,4,3,data), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::GetValue(3,3,3,4,data), ErrorUtil::NekError);
            }
            #endif
        }

        void TestSetValue()
        {
            NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0};
            Array<OneD, NekDouble> array_buf(6, buf);
            Array<OneD, NekDouble> data = Policy::Initialize(3, 3, array_buf);
            BOOST_CHECK_EQUAL(data.num_elements(), 6);

            Policy::SetValue(3,3,0,0,data, 7.2);
            BOOST_CHECK_EQUAL(7.2, Policy::GetValue(3,3,0,0,data));
            BOOST_CHECK_EQUAL(1.0, array_buf[0]);
            BOOST_CHECK_EQUAL(7.2, data[0]);

            Policy::SetValue(3,3,0,1,data,10.0);
            BOOST_CHECK_EQUAL(10.0, Policy::GetValue(3,3,0,1,data));
            Policy::SetValue(3,3,0,2,data,20.0);
            BOOST_CHECK_EQUAL(20.0, Policy::GetValue(3,3,0,2,data));
            Policy::SetValue(3,3,1,1,data,30.0);
            BOOST_CHECK_EQUAL(30.0, Policy::GetValue(3,3,1,1,data));
            Policy::SetValue(3,3,1,2,data,40.0);
            BOOST_CHECK_EQUAL(40.0, Policy::GetValue(3,3,1,2,data));
            Policy::SetValue(3,3,2,2,data,50.0);
            BOOST_CHECK_EQUAL(50.0, Policy::GetValue(3,3,2,2,data));

            // Can't set in the lower triangle.
            BOOST_CHECK_THROW(Policy::SetValue(3,3,1,0,data,8.0), ErrorUtil::NekError);
            BOOST_CHECK_THROW(Policy::SetValue(3,3,2,0,data,8.0), ErrorUtil::NekError);
            BOOST_CHECK_THROW(Policy::SetValue(3,3,2,1,data,8.0), ErrorUtil::NekError);

            #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
            {
                BOOST_CHECK_THROW(Policy::SetValue(3,4,3,3,data,8.0), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::SetValue(3,3,4,3,data,8.0), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::SetValue(3,3,3,4,data,8.0), ErrorUtil::NekError);
            }
            #endif
        }
        void TestAdvance()
        {
            {
                NekDouble buf[] = {1.0, 2.0, 3.0,
                                        5.0, 6.0,
                                             9.0};
                Array<OneD, NekDouble> array_buf(6, buf);
                Array<OneD, NekDouble> data = Policy::Initialize(3, 3, array_buf);
                BOOST_CHECK_EQUAL(data.num_elements(), 6);

                unsigned int curRow = 0;
                unsigned int curColumn = 0;
                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(0, curRow);
                BOOST_CHECK_EQUAL(1, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(0, curRow);
                BOOST_CHECK_EQUAL(2, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(1, curRow);
                BOOST_CHECK_EQUAL(1, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(1, curRow);
                BOOST_CHECK_EQUAL(2, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(2, curRow);
                BOOST_CHECK_EQUAL(2, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curRow);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curColumn);
            }

            {
                NekDouble buf[] = {1.0};
                Array<OneD, NekDouble> array_buf(1, buf);
                Array<OneD, NekDouble> data = Policy::Initialize(1, 1, array_buf);
                BOOST_CHECK_EQUAL(data.num_elements(), 1);

                unsigned int curRow = 0;
                unsigned int curColumn = 0;
                boost::tie(curRow, curColumn) = Policy::Advance(1, 1, curRow, curColumn);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curRow);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curColumn);
            }

            {
                NekDouble buf[] = {1.0, 2.0,
                                        5.0};
                Array<OneD, NekDouble> array_buf(3, buf);
                Array<OneD, NekDouble> data = Policy::Initialize(2, 2, array_buf);
                BOOST_CHECK_EQUAL(data.num_elements(), 3);

                unsigned int curRow = 0;
                unsigned int curColumn = 0;
                boost::tie(curRow, curColumn) = Policy::Advance(2, 2, curRow, curColumn);
                BOOST_CHECK_EQUAL(0, curRow);
                BOOST_CHECK_EQUAL(1, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(2, 2, curRow, curColumn);
                BOOST_CHECK_EQUAL(1, curRow);
                BOOST_CHECK_EQUAL(1, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(2, 2, curRow, curColumn);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curRow);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curColumn);
            }
        }
    }
}

<commit_msg>*** empty log message ***<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// File: TestMatrixStoragePolicies.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description:
//
///////////////////////////////////////////////////////////////////////////////

#include <UnitTests/LibUtilities/TestMatrixStoragePolicies.h>
#include <LibUtilities/LinearAlgebra/NekMatrix.hpp>

#include <boost/test/auto_unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/unit_test.hpp>

#include <boost/test/auto_unit_test.hpp>

namespace Nektar
{
    namespace UpperTriangularUnitTests
    {
        typedef MatrixStoragePolicy<NekDouble, UpperTriangularMatrixTag> Policy;

        void Test0ParameterInitialize()
        {
            Array<OneD, NekDouble> result = Policy::Initialize();
            BOOST_CHECK_EQUAL(result.num_elements(), 0);
            BOOST_CHECK_EQUAL(result.GetOffset(), 0);
            BOOST_CHECK(result.data() != 0);
        }

        void Test2ParameterInitialize()
        {
            {
                Array<OneD, NekDouble> result = Policy::Initialize(5, 5);
                BOOST_CHECK_EQUAL(result.num_elements(), 15);
            }

            {
                BOOST_CHECK_THROW( (Policy::Initialize(5,6)), ErrorUtil::NekError);
                BOOST_CHECK_THROW( (Policy::Initialize(6,5)), ErrorUtil::NekError);
            }
        }

        void TestSingleValuePopulationInitialize()
        {
            {
                Array<OneD, NekDouble> result = Policy::Initialize(5, 5, 7.2);
                BOOST_CHECK_EQUAL(result.num_elements(), 15);
                for(Array<OneD, NekDouble>::iterator iter = result.begin(); iter != result.end(); ++iter)
                {
                    BOOST_CHECK_EQUAL(*iter, 7.2);
                }
            }

            {
                BOOST_CHECK_THROW( (Policy::Initialize(5,6,7.2)), ErrorUtil::NekError);
                BOOST_CHECK_THROW( (Policy::Initialize(6,5,7.2)), ErrorUtil::NekError);
            }
        }

        void TestCArrayInitialization()
        {
            NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0};

            {
                Array<OneD, NekDouble> result = Policy::Initialize(3, 3, buf);
                BOOST_CHECK_EQUAL(result.num_elements(), 6);

                BOOST_CHECK_EQUAL(result[0], 1.0);
                BOOST_CHECK_EQUAL(result[1], 2.0);
                BOOST_CHECK_EQUAL(result[2], 3.0);
                BOOST_CHECK_EQUAL(result[3], 5.0);
                BOOST_CHECK_EQUAL(result[4], 6.0);
                BOOST_CHECK_EQUAL(result[5], 9.0);
            }

            {

                BOOST_CHECK_THROW( (Policy::Initialize(5,6,buf)), ErrorUtil::NekError);
                BOOST_CHECK_THROW( (Policy::Initialize(6,5,buf)), ErrorUtil::NekError);
            }
        }

        void TestArrayInitialization()
        {
            NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0};
            Array<OneD, NekDouble> array_buf(6, buf);

            {
                Array<OneD, NekDouble> result = Policy::Initialize(3, 3, array_buf);
                BOOST_CHECK_EQUAL(result.num_elements(), 6);

                BOOST_CHECK_EQUAL(result[0], 1.0);
                BOOST_CHECK_EQUAL(result[1], 2.0);
                BOOST_CHECK_EQUAL(result[2], 3.0);
                BOOST_CHECK_EQUAL(result[3], 5.0);
                BOOST_CHECK_EQUAL(result[4], 6.0);
                BOOST_CHECK_EQUAL(result[5], 9.0);
            }

            {

                BOOST_CHECK_THROW( (Policy::Initialize(5,6,buf)), ErrorUtil::NekError);
                BOOST_CHECK_THROW( (Policy::Initialize(6,5,buf)), ErrorUtil::NekError);
            }

            {
                NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0, 10.0};
                Array<OneD, NekDouble> array_buf(7, buf);
                BOOST_CHECK_NO_THROW(Policy::Initialize(3, 3, array_buf));
            }

            {
                NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0, 10.0};
                Array<OneD, NekDouble> array_buf(5, buf);
                BOOST_CHECK_THROW(Policy::Initialize(3, 3, array_buf), ErrorUtil::NekError);
            }
        }

        void TestConstGetValue()
        {
            NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0};
            Array<OneD, NekDouble> array_buf(6, buf);
            Array<OneD, NekDouble> data = Policy::Initialize(3, 3, array_buf);
            BOOST_CHECK_EQUAL(data.num_elements(), 6);

            {
                BOOST_CHECK_EQUAL(1.0, Policy::GetValue(3, 3, 0, 0, data));
                BOOST_CHECK_EQUAL(2.0, Policy::GetValue(3, 3, 0, 1, data));
                BOOST_CHECK_EQUAL(3.0, Policy::GetValue(3, 3, 0, 2, data));
                BOOST_CHECK_EQUAL(0.0, Policy::GetValue(3, 3, 1, 0, data));
                BOOST_CHECK_EQUAL(5.0, Policy::GetValue(3, 3, 1, 1, data));
                BOOST_CHECK_EQUAL(6.0, Policy::GetValue(3, 3, 1, 2, data));
                BOOST_CHECK_EQUAL(0.0, Policy::GetValue(3, 3, 2, 0, data));
                BOOST_CHECK_EQUAL(0.0, Policy::GetValue(3, 3, 2, 1, data));
                BOOST_CHECK_EQUAL(9.0, Policy::GetValue(3, 3, 2, 2, data));
            }

            #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
            {
                BOOST_CHECK_THROW(Policy::GetValue(3,4,3,3,data), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::GetValue(3,3,4,3,data), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::GetValue(3,3,3,4,data), ErrorUtil::NekError);
            }
            #endif
        }

        void TestSetValue()
        {
            NekDouble buf[] = {1.0, 2.0, 3.0,
                                    5.0, 6.0,
                                         9.0};
            Array<OneD, NekDouble> array_buf(6, buf);
            Array<OneD, NekDouble> data = Policy::Initialize(3, 3, array_buf);
            BOOST_CHECK_EQUAL(data.num_elements(), 6);

            Policy::SetValue(3,3,0,0,data, 7.2);
            BOOST_CHECK_EQUAL(7.2, Policy::GetValue(3,3,0,0,data));
            BOOST_CHECK_EQUAL(1.0, array_buf[0]);
            BOOST_CHECK_EQUAL(7.2, data[0]);

            Policy::SetValue(3,3,0,1,data,10.0);
            BOOST_CHECK_EQUAL(10.0, Policy::GetValue(3,3,0,1,data));
            Policy::SetValue(3,3,0,2,data,20.0);
            BOOST_CHECK_EQUAL(20.0, Policy::GetValue(3,3,0,2,data));
            Policy::SetValue(3,3,1,1,data,30.0);
            BOOST_CHECK_EQUAL(30.0, Policy::GetValue(3,3,1,1,data));
            Policy::SetValue(3,3,1,2,data,40.0);
            BOOST_CHECK_EQUAL(40.0, Policy::GetValue(3,3,1,2,data));
            Policy::SetValue(3,3,2,2,data,50.0);
            BOOST_CHECK_EQUAL(50.0, Policy::GetValue(3,3,2,2,data));

            #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
                // Can't set in the lower triangle.
                BOOST_CHECK_THROW(Policy::SetValue(3,3,1,0,data,8.0), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::SetValue(3,3,2,0,data,8.0), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::SetValue(3,3,2,1,data,8.0), ErrorUtil::NekError);

                BOOST_CHECK_THROW(Policy::SetValue(3,4,3,3,data,8.0), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::SetValue(3,3,4,3,data,8.0), ErrorUtil::NekError);
                BOOST_CHECK_THROW(Policy::SetValue(3,3,3,4,data,8.0), ErrorUtil::NekError);
            #endif
        }
        void TestAdvance()
        {
            {
                NekDouble buf[] = {1.0, 2.0, 3.0,
                                        5.0, 6.0,
                                             9.0};
                Array<OneD, NekDouble> array_buf(6, buf);
                Array<OneD, NekDouble> data = Policy::Initialize(3, 3, array_buf);
                BOOST_CHECK_EQUAL(data.num_elements(), 6);

                unsigned int curRow = 0;
                unsigned int curColumn = 0;
                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(0, curRow);
                BOOST_CHECK_EQUAL(1, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(0, curRow);
                BOOST_CHECK_EQUAL(2, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(1, curRow);
                BOOST_CHECK_EQUAL(1, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(1, curRow);
                BOOST_CHECK_EQUAL(2, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(2, curRow);
                BOOST_CHECK_EQUAL(2, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(3, 3, curRow, curColumn);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curRow);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curColumn);
            }

            {
                NekDouble buf[] = {1.0};
                Array<OneD, NekDouble> array_buf(1, buf);
                Array<OneD, NekDouble> data = Policy::Initialize(1, 1, array_buf);
                BOOST_CHECK_EQUAL(data.num_elements(), 1);

                unsigned int curRow = 0;
                unsigned int curColumn = 0;
                boost::tie(curRow, curColumn) = Policy::Advance(1, 1, curRow, curColumn);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curRow);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curColumn);
            }

            {
                NekDouble buf[] = {1.0, 2.0,
                                        5.0};
                Array<OneD, NekDouble> array_buf(3, buf);
                Array<OneD, NekDouble> data = Policy::Initialize(2, 2, array_buf);
                BOOST_CHECK_EQUAL(data.num_elements(), 3);

                unsigned int curRow = 0;
                unsigned int curColumn = 0;
                boost::tie(curRow, curColumn) = Policy::Advance(2, 2, curRow, curColumn);
                BOOST_CHECK_EQUAL(0, curRow);
                BOOST_CHECK_EQUAL(1, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(2, 2, curRow, curColumn);
                BOOST_CHECK_EQUAL(1, curRow);
                BOOST_CHECK_EQUAL(1, curColumn);

                boost::tie(curRow, curColumn) = Policy::Advance(2, 2, curRow, curColumn);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curRow);
                BOOST_CHECK_EQUAL(std::numeric_limits<unsigned int>::max(), curColumn);
            }
        }
    }
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 * 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: dlgcont.hxx,v $
 * $Revision: 1.8 $
 *
 * 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 BASIC_DIALOGCONTAINER_HXX
#define BASIC_DIALOGCONTAINER_HXX

#include "namecont.hxx"

#ifndef _COM_SUN_STAR_AWT_XSTRINGRESOURCESUPPLIER_HPP_
#include <com/sun/star/resource/XStringResourceSupplier.hpp>
#endif
#include "com/sun/star/resource/XStringResourcePersistence.hpp"

#include <cppuhelper/implbase1.hxx>
#include <comphelper/uno3.hxx>

namespace basic
{

//============================================================================

class SfxDialogLibraryContainer : public SfxLibraryContainer
{
    // Methods to distinguish between different library types
    virtual SfxLibrary* SAL_CALL implCreateLibrary( const ::rtl::OUString& aName );
    virtual SfxLibrary* SAL_CALL implCreateLibraryLink
        ( const ::rtl::OUString& aName, const ::rtl::OUString& aLibInfoFileURL,
          const ::rtl::OUString& StorageURL, sal_Bool ReadOnly );
    virtual ::com::sun::star::uno::Any SAL_CALL createEmptyLibraryElement( void );
    virtual sal_Bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement );
    virtual void SAL_CALL writeLibraryElement
    (
        ::com::sun::star::uno::Any aElement,
        const ::rtl::OUString& aElementName,
        ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOutput
    )
        throw(::com::sun::star::uno::Exception);

    virtual ::com::sun::star::uno::Any SAL_CALL importLibraryElement
        ( const ::rtl::OUString& aFile,
        const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xElementStream );

    virtual void SAL_CALL importFromOldStorage( const ::rtl::OUString& aFile );

    virtual SfxLibraryContainer* createInstanceImpl( void );

    virtual void onNewRootStorage();

    virtual const sal_Char* SAL_CALL    getInfoFileName() const;
    virtual const sal_Char* SAL_CALL    getOldInfoFileName() const;
    virtual const sal_Char* SAL_CALL    getLibElementFileExtension() const;
    virtual const sal_Char* SAL_CALL    getLibrariesDir() const;

public:
    SfxDialogLibraryContainer( void );
    SfxDialogLibraryContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage );

    // Methods XStorageBasedLibraryContainer
    virtual void SAL_CALL storeLibrariesToStorage(
        const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& RootStorage )
            throw (::com::sun::star::uno::RuntimeException);

    // Resource handling
    ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourcePersistence >
        implCreateStringResource( class SfxDialogLibrary* pDialog );

    // Methods XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName( )
        throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
        throw (::com::sun::star::uno::RuntimeException);

    // Service
    static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static();
    static ::rtl::OUString getImplementationName_static();
    static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create
        ( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xServiceManager )
            throw( ::com::sun::star::uno::Exception );
};

//============================================================================

typedef ::cppu::ImplHelper1 <   ::com::sun::star::resource::XStringResourceSupplier
                            >   SfxDialogLibrary_BASE;

class SfxDialogLibrary  :public SfxLibrary
                        ,public SfxDialogLibrary_BASE
{
    SfxDialogLibraryContainer*                                      m_pParent;
    ::com::sun::star::uno::Reference
        < ::com::sun::star::resource::XStringResourcePersistence>   m_xStringResourcePersistence;
    ::rtl::OUString                                                 m_aName;

    // Provide modify state including resources
    virtual sal_Bool isModified( void );
    virtual void storeResources( void );
    virtual void storeResourcesAsURL( const ::rtl::OUString& URL, const ::rtl::OUString& NewName );
    virtual void storeResourcesToURL( const ::rtl::OUString& URL,
        const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler  );
    virtual void storeResourcesToStorage( const ::com::sun::star::uno::Reference
        < ::com::sun::star::embed::XStorage >& xStorage );

public:
    SfxDialogLibrary
    (
        ModifiableHelper& _rModifiable,
        const ::rtl::OUString& aName,
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
        const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI,
        SfxDialogLibraryContainer* pParent
    );

    SfxDialogLibrary
    (
        ModifiableHelper& _rModifiable,
        const ::rtl::OUString& aName,
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
        const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI,
        const ::rtl::OUString& aLibInfoFileURL, const ::rtl::OUString& aStorageURL, sal_Bool ReadOnly,
        SfxDialogLibraryContainer* pParent
    );

    DECLARE_XINTERFACE()
    DECLARE_XTYPEPROVIDER()

    // XStringResourceSupplier
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourceResolver >
        SAL_CALL getStringResource(  ) throw (::com::sun::star::uno::RuntimeException);

    ::rtl::OUString getName( void )
        { return m_aName; }

    ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourcePersistence >
        getStringResourcePersistence( void )
    {
        return m_xStringResourcePersistence;
    }
};

}   // namespace basic

#endif

<commit_msg>INTEGRATION: CWS dba30c (1.8.12); FILE MERGED 2008/05/13 07:00:20 fs 1.8.12.1: joining changes from CWS odbmacros3 to CWS dba30c 2008/04/30 09:26:25 fs 1.8.4.1: add some safety against using an unloaded script/dialog library - this now throws an exception, instead of silently doing nothing/nonsense<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: dlgcont.hxx,v $
 * $Revision: 1.9 $
 *
 * 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 BASIC_DIALOGCONTAINER_HXX
#define BASIC_DIALOGCONTAINER_HXX

#include "namecont.hxx"

#ifndef _COM_SUN_STAR_AWT_XSTRINGRESOURCESUPPLIER_HPP_
#include <com/sun/star/resource/XStringResourceSupplier.hpp>
#endif
#include "com/sun/star/resource/XStringResourcePersistence.hpp"

#include <cppuhelper/implbase1.hxx>
#include <comphelper/uno3.hxx>

namespace basic
{

//============================================================================

class SfxDialogLibraryContainer : public SfxLibraryContainer
{
    // Methods to distinguish between different library types
    virtual SfxLibrary* SAL_CALL implCreateLibrary( const ::rtl::OUString& aName );
    virtual SfxLibrary* SAL_CALL implCreateLibraryLink
        ( const ::rtl::OUString& aName, const ::rtl::OUString& aLibInfoFileURL,
          const ::rtl::OUString& StorageURL, sal_Bool ReadOnly );
    virtual ::com::sun::star::uno::Any SAL_CALL createEmptyLibraryElement( void );
    virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const;
    virtual void SAL_CALL writeLibraryElement
    (
        ::com::sun::star::uno::Any aElement,
        const ::rtl::OUString& aElementName,
        ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream > xOutput
    )
        throw(::com::sun::star::uno::Exception);

    virtual ::com::sun::star::uno::Any SAL_CALL importLibraryElement
        ( const ::rtl::OUString& aFile,
        const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream >& xElementStream );

    virtual void SAL_CALL importFromOldStorage( const ::rtl::OUString& aFile );

    virtual SfxLibraryContainer* createInstanceImpl( void );

    virtual void onNewRootStorage();

    virtual const sal_Char* SAL_CALL    getInfoFileName() const;
    virtual const sal_Char* SAL_CALL    getOldInfoFileName() const;
    virtual const sal_Char* SAL_CALL    getLibElementFileExtension() const;
    virtual const sal_Char* SAL_CALL    getLibrariesDir() const;

public:
    SfxDialogLibraryContainer( void );
    SfxDialogLibraryContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStorage );

    // Methods XStorageBasedLibraryContainer
    virtual void SAL_CALL storeLibrariesToStorage(
        const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& RootStorage )
            throw (::com::sun::star::uno::RuntimeException);

    // Resource handling
    ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourcePersistence >
        implCreateStringResource( class SfxDialogLibrary* pDialog );

    // Methods XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName( )
        throw (::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
        throw (::com::sun::star::uno::RuntimeException);

    // Service
    static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_static();
    static ::rtl::OUString getImplementationName_static();
    static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL Create
        ( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xServiceManager )
            throw( ::com::sun::star::uno::Exception );
};

//============================================================================

typedef ::cppu::ImplHelper1 <   ::com::sun::star::resource::XStringResourceSupplier
                            >   SfxDialogLibrary_BASE;

class SfxDialogLibrary  :public SfxLibrary
                        ,public SfxDialogLibrary_BASE
{
    SfxDialogLibraryContainer*                                      m_pParent;
    ::com::sun::star::uno::Reference
        < ::com::sun::star::resource::XStringResourcePersistence>   m_xStringResourcePersistence;
    ::rtl::OUString                                                 m_aName;

    // Provide modify state including resources
    virtual sal_Bool isModified( void );
    virtual void storeResources( void );
    virtual void storeResourcesAsURL( const ::rtl::OUString& URL, const ::rtl::OUString& NewName );
    virtual void storeResourcesToURL( const ::rtl::OUString& URL,
        const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler  );
    virtual void storeResourcesToStorage( const ::com::sun::star::uno::Reference
        < ::com::sun::star::embed::XStorage >& xStorage );

public:
    SfxDialogLibrary
    (
        ModifiableHelper& _rModifiable,
        const ::rtl::OUString& aName,
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
        const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI,
        SfxDialogLibraryContainer* pParent
    );

    SfxDialogLibrary
    (
        ModifiableHelper& _rModifiable,
        const ::rtl::OUString& aName,
        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSF,
        const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xSFI,
        const ::rtl::OUString& aLibInfoFileURL, const ::rtl::OUString& aStorageURL, sal_Bool ReadOnly,
        SfxDialogLibraryContainer* pParent
    );

    DECLARE_XINTERFACE()
    DECLARE_XTYPEPROVIDER()

    // XStringResourceSupplier
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourceResolver >
        SAL_CALL getStringResource(  ) throw (::com::sun::star::uno::RuntimeException);

    ::rtl::OUString getName( void )
        { return m_aName; }

    ::com::sun::star::uno::Reference< ::com::sun::star::resource::XStringResourcePersistence >
        getStringResourcePersistence( void )
    {
        return m_xStringResourcePersistence;
    }

    static bool containsValidDialog( const ::com::sun::star::uno::Any& aElement );

protected:
    virtual bool SAL_CALL isLibraryElementValid( ::com::sun::star::uno::Any aElement ) const;
};

}   // namespace basic

#endif

<|endoftext|>


<commit_before>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the BSD License.
*/

#ifndef TRITON_REGISTERS_E_H
#define TRITON_REGISTERS_E_H

//! The Triton namespace
namespace triton {
/*!
 *  \addtogroup triton
 *  @{
 */

  //! The Architecture namespace
  namespace arch {
  /*!
   *  \ingroup triton
   *  \addtogroup arch
   *  @{
   */
      //! The list of registers.
      enum registers_e {
        ID_REG_INVALID = 0, //!< invalid = 0

        #define REG_SPEC(UPPER_NAME, LOWER_NAME, X86_64_UPPER, X86_64_LOWER, X86_64_PARENT, X86_UPPER, X86_LOWER, X86_PARENT, X86_AVAIL) \
        ID_REG_##UPPER_NAME,
        #define REG_SPEC_NO_CAPSTONE REG_SPEC
        #include "triton/x86.spec"

        /* Must be the last item */
        ID_REG_LAST_ITEM //!< must be the last item
      };

  /*! @} End of arch namespace */
  };
/*! @} End of triton namespace */
};

namespace std {
  // Define the hash function for registers_e to be use in stl containers like unordered_map
  template <>
  class hash<triton::arch::registers_e>: public hash<uint64_t> {
  };
};

#endif /* TRITON_REGISTERS_E_H */
<commit_msg>Correctly specialize std::hash<commit_after>//! \file
/*
**  Copyright (C) - Triton
**
**  This program is under the terms of the BSD License.
*/

#ifndef TRITON_REGISTERS_E_H
#define TRITON_REGISTERS_E_H

//! The Triton namespace
namespace triton {
/*!
 *  \addtogroup triton
 *  @{
 */

  //! The Architecture namespace
  namespace arch {
  /*!
   *  \ingroup triton
   *  \addtogroup arch
   *  @{
   */
      //! The list of registers.
      enum registers_e {
        ID_REG_INVALID = 0, //!< invalid = 0

        #define REG_SPEC(UPPER_NAME, LOWER_NAME, X86_64_UPPER, X86_64_LOWER, X86_64_PARENT, X86_UPPER, X86_LOWER, X86_PARENT, X86_AVAIL) \
        ID_REG_##UPPER_NAME,
        #define REG_SPEC_NO_CAPSTONE REG_SPEC
        #include "triton/x86.spec"

        /* Must be the last item */
        ID_REG_LAST_ITEM //!< must be the last item
      };

  /*! @} End of arch namespace */
  };
/*! @} End of triton namespace */
};

namespace std {
  // Define the hash function for registers_e to be use in stl containers like unordered_map
  template <>
  struct hash<triton::arch::registers_e> : public hash<uint64_t> {
  };
};

#endif /* TRITON_REGISTERS_E_H */
<|endoftext|>


<commit_before>#define SP_USE_DEBUG 1

#include "simplesp.h"

using namespace sp;

int main(){

	//--------------------------------------------------------------------------------
	// kd tree
	//--------------------------------------------------------------------------------

	const int dim = 3;

	const int dataNum = 10000;

	// search target data
	Mem1<Vec3> targ;
	for (int i = 0; i < dataNum; i++) {
		targ.push(randVecUnif(100.0, 100.0, 100.0));
	}

	// test data
	Mem1<Vec3> test;
	for (int i = 0; i < dataNum; i++) {
		test.push(randVecUnif(100.0, 100.0, 100.0));
	}

	// kd tree
	{
		Mem1<Vec3> result;
		result.reserve(test.size());

		{
			SP_LOGGER_INSTANCE;
			SP_LOGGER_SET("kd tree");

			// create instance
			KdTree<double> kdtree(dim);

			// set data
			for (int i = 0; i < targ.size(); i++){
				kdtree.addData(&targ[i]);
			}

			for (int i = 0; i < test.size(); i++){
				const int crsp = kdtree.search(&test[i]);
				result.push(targ[crsp]);
			}
		}

		printf("kd tree\n");
		{
			int step = (test.size() / 10);
			for (int i = 0; i < test.size(); i += step){
				print(result[i]);
			}
		}
		printf("\n");
	}

	// brute force search
	{
		Mem1<Vec3> result;
		result.reserve(dim * test.size());

		{
			SP_LOGGER_INSTANCE;
			SP_LOGGER_SET("brute force search");

			for (int i = 0; i < test.size(); i++){
				int crsp = -1;

				double minv = SP_INFINITY;
				for (int j = 0; j < targ.size(); j++){
					const double sq = sqVec(test[i] - targ[j]);
					if (sq < minv){
						minv = sq;
						crsp = j;
					}
				}

				result.push(targ[crsp]);
			}
		}

		printf("brute force search\n");
		{
			int step = (test.size() / 10);
			for (int i = 0; i < test.size(); i += step){
				print(result[i]);
			}
		}
		printf("\n");
	}

	return 0;
}<commit_msg>update parameter<commit_after>#define SP_USE_DEBUG 1

#include "simplesp.h"

using namespace sp;

int main(){

	//--------------------------------------------------------------------------------
	// kd tree
	//--------------------------------------------------------------------------------

	const int dim = 2;
	typedef Vec2 VEC;

	const int dataNum = 1000;

	// search target data
	Mem1<VEC> targ;
	for (int i = 0; i < dataNum; i++) {
		targ.push(randVecUnif(100.0, 100.0));
	}

	// test data
	Mem1<VEC> test;
	for (int i = 0; i < 1000; i++) {
		test.push(randVecUnif(100.0, 100.0));
	}

	// kd tree
	{
		Mem1<VEC> result;
		result.reserve(test.size());

		{
			SP_LOGGER_INSTANCE;
			SP_LOGGER_SET("kd tree");

			// create instance
			KdTree<double> kdtree(dim);

			// set data
			for (int i = 0; i < targ.size(); i++){
				kdtree.addData(&targ[i]);
			}

			for (int i = 0; i < test.size(); i++){
				const int crsp = kdtree.search(&test[i]);
				result.push(targ[crsp]);
			}
		}

		printf("kd tree\n");
		{
			int step = (test.size() / 10);
			for (int i = 0; i < test.size(); i += step){
				print(result[i]);
			}
		}
		printf("\n");
	}

	// brute force search
	{
		Mem1<VEC> result;
		result.reserve(dim * test.size());

		{
			SP_LOGGER_INSTANCE;
			SP_LOGGER_SET("brute force search");

			for (int i = 0; i < test.size(); i++){
				int crsp = -1;

				double minv = SP_INFINITY;
				for (int j = 0; j < targ.size(); j++){
					const double sq = sqVec(test[i] - targ[j]);
					if (sq < minv){
						minv = sq;
						crsp = j;
					}
				}

				result.push(targ[crsp]);
			}
		}

		printf("brute force search\n");
		{
			int step = (test.size() / 10);
			for (int i = 0; i < test.size(); i += step){
				print(result[i]);
			}
		}
		printf("\n");
	}

	return 0;
}<|endoftext|>


<commit_before>#include <array>

#include "core/image.h"
#include "core/image_draw.h"
#include "core/io.h"
#include "core/identicon.h"
#include "core/hashgen_retro.h"
#include "core/hashgen_sprator.h"
#include "core/argparse.h"
#include "core/random.h"
#include "core/str.h"
#include "core/collage.h"
#include "core/palette.h"

using namespace euphoria::core;

enum class HashType
{
    Identicon, Retro, Sprator
};

int
main(int argc, char* argv[])
{
    auto image_size = 512;
    auto number_of_images = 10;
    bool use_random = true;
    bool collage = false;
    HashType type = HashType::Identicon;

    auto parser = argparse::Parser {"identicon test"};
    parser.Add("--size", &image_size).Help("image size");
    parser.Add("--count", &number_of_images).Help("The number of images to generate");
    parser.SetFalse("--const", &use_random).Help("Use a constant value");
    parser.SetTrue("--collage", &collage).Help("output to a single collage istead of several images");
    parser.Add("-t", &type).Help("Set the type to use");

    if(const auto r = parser.Parse(argc, argv))
    {
        return *r;
    }

    if(use_random==false && number_of_images > 1)
    {
        std::cout << "Since random isn't requested: setting the number of images to 1...\n";
        number_of_images = 1;
    }

    Random random;

    const auto pal = Palette
    {
        "",
        Color::Red,
        Color::White,
        Color::Blue,

        Color::LightGreen,
        Color::Yellow,
        Color::LightBlue,

        Color::Pink,
        Color::Orange,
        Color::Tan,

        Color::Brown,
        Color::Green,
        Color::Purple,
        Color::CornflowerBlue,
        Color::Cyan
    };

    auto images = std::vector<Image>{};
    Image image;
    image.SetupWithAlphaSupport(image_size, image_size);

    for(int i = 0; i < number_of_images; i += 1)
    {
        int code = -2044886870;
        if(use_random)
        {
            code = random.NextInteger();
        }

        switch(type)
        {
        case HashType::Identicon:
            RenderIdenticon(&image, code);
            break;
        case HashType::Retro:
            RenderRetro(&image, code);
            break;
        case HashType::Sprator:
            RenderSprator(&image, code, pal.GetSafeIndex(i));
            break;
        default:
            DIE("Unhandled type");
            break;
        }

        std::string file_name = "identicon.png";

        if(collage)
        {
            images.emplace_back(image);
            std::cout << "Generated collage image\n";
        }
        else
        {
            if(number_of_images > 1)
            {
                file_name = Str() << "identicon_" << (i + 1) << ".png";
                std::cout << "Writing " << file_name << "\n";
            }

            io::ChunkToFile(image.Write(ImageWriteFormat::PNG), file_name);
        }
    }

    if(collage)
    {
        std::cout << "writing collage...\n";
        int padding = 20;
        auto collage_image = GridLayout(images, padding, Color::Gray, true);
        std::string file_name = "identicon.png";
        io::ChunkToFile(collage_image.Write(ImageWriteFormat::PNG), file_name);
    }

    return 0;
}

<commit_msg>refactored to subparser<commit_after>#include <array>

#include "core/image.h"
#include "core/image_draw.h"
#include "core/io.h"
#include "core/identicon.h"
#include "core/hashgen_retro.h"
#include "core/hashgen_sprator.h"
#include "core/argparse.h"
#include "core/random.h"
#include "core/str.h"
#include "core/collage.h"
#include "core/palette.h"

using namespace euphoria::core;

enum class HashType
{
    Identicon, Retro, Sprator
};

struct CommonArguments
{
    int image_size = 512;
    int number_of_images = 10;
    bool use_random = true;
    HashType type = HashType::Identicon;

    explicit CommonArguments(argparse::ParserBase* base)
    {
        base->Add("--size", &image_size).Help("image size");
        base->Add("--count", &number_of_images).Help("The number of images to generate");
        base->SetFalse("--const", &use_random).Help("Use a constant value");
        base->Add("-t", &type).Help("Set the type to use");
    }
};

void RunMain
(
    int image_size,
    int number_of_images,
    bool use_random,
    HashType type,
    bool collage
)
{
    if(use_random==false && number_of_images > 1)
    {
        std::cout << "Since random isn't requested: setting the number of images to 1...\n";
        number_of_images = 1;
    }

    Random random;

    const auto pal = Palette
    {
        "",
        Color::Red,
        Color::White,
        Color::Blue,

        Color::LightGreen,
        Color::Yellow,
        Color::LightBlue,

        Color::Pink,
        Color::Orange,
        Color::Tan,

        Color::Brown,
        Color::Green,
        Color::Purple,
        Color::CornflowerBlue,
        Color::Cyan
    };

    auto images = std::vector<Image>{};
    Image image;
    image.SetupWithAlphaSupport(image_size, image_size);

    for(int i = 0; i < number_of_images; i += 1)
    {
        int code = -2044886870;
        if(use_random)
        {
            code = random.NextInteger();
        }

        switch(type)
        {
        case HashType::Identicon:
            RenderIdenticon(&image, code);
            break;
        case HashType::Retro:
            RenderRetro(&image, code);
            break;
        case HashType::Sprator:
            RenderSprator(&image, code, pal.GetSafeIndex(i));
            break;
        default:
            DIE("Unhandled type");
            break;
        }

        std::string file_name = "identicon.png";

        if(collage)
        {
            images.emplace_back(image);
            std::cout << "Generated collage image\n";
        }
        else
        {
            if(number_of_images > 1)
            {
                file_name = Str() << "identicon_" << (i + 1) << ".png";
                std::cout << "Writing " << file_name << "\n";
            }

            io::ChunkToFile(image.Write(ImageWriteFormat::PNG), file_name);
        }
    }

    if(collage)
    {
        std::cout << "writing collage...\n";
        int padding = 20;
        auto collage_image = GridLayout(images, padding, Color::Gray, true);
        std::string file_name = "identicon.png";
        io::ChunkToFile(collage_image.Write(ImageWriteFormat::PNG), file_name);
    }
}

int
main(int argc, char* argv[])
{
    auto parser = argparse::Parser {"identicon test"};

    auto subs = parser.AddSubParsers();

    subs->Add
    (
        "singles", "write many images",
        [](argparse::SubParser* sub)
        {
            auto arguments = CommonArguments{sub};
            return sub->OnComplete
            (
                [&]
                {
                    RunMain
                    (
                        arguments.image_size,
                        arguments.number_of_images,
                        arguments.use_random,
                        arguments.type,
                        false
                    );
                    return argparse::ParseResult::Ok;
                }
            );
        }
    );
    subs->Add
    (
        "collage", "write collage",
        [](argparse::SubParser* sub)
        {
            auto arguments = CommonArguments{sub};
            return sub->OnComplete
            (
                [&]
                {
                    RunMain
                    (
                        arguments.image_size,
                        arguments.number_of_images,
                        arguments.use_random,
                        arguments.type,
                        true
                    );
                    return argparse::ParseResult::Ok;
                }
            );
        }
    );

    return argparse::ParseFromMain(&parser, argc, argv);
}

<|endoftext|>


<commit_before>// Ouzel by Elviss Strazdins

#include <iterator>
#include <stdexcept>
#include <string>
#include "MtlLoader.hpp"
#include "Bundle.hpp"
#include "Cache.hpp"
#include "../core/Engine.hpp"

namespace ouzel::assets
{
    namespace
    {
        constexpr auto isWhitespace(std::byte c)
        {
            return static_cast<char>(c) == ' ' ||
                static_cast<char>(c) == '\t';
        }

        constexpr auto isNewline(std::byte c)
        {
            return static_cast<char>(c) == '\r' ||
                static_cast<char>(c) == '\n';
        }

        constexpr auto isControlChar(std::byte c)
        {
            return static_cast<std::uint8_t>(c) <= 0x1F;
        }

        void skipWhitespaces(std::vector<std::byte>::const_iterator& iterator,
                             std::vector<std::byte>::const_iterator end)
        {
            while (iterator != end)
                if (isWhitespace(*iterator))
                    ++iterator;
                else
                    break;
        }

        void skipLine(std::vector<std::byte>::const_iterator& iterator,
                      std::vector<std::byte>::const_iterator end)
        {
            while (iterator != end)
            {
                if (isNewline(*iterator))
                {
                    ++iterator;
                    break;
                }

                ++iterator;
            }
        }

        std::string parseString(std::vector<std::byte>::const_iterator& iterator,
                                std::vector<std::byte>::const_iterator end)
        {
            std::string result;

            while (iterator != end && !isControlChar(*iterator) && !isWhitespace(*iterator))
            {
                result.push_back(static_cast<char>(*iterator));
                ++iterator;
            }

            if (result.empty())
                throw std::runtime_error("Invalid string");

            return result;
        }

        float parseFloat(std::vector<std::byte>::const_iterator& iterator,
                         std::vector<std::byte>::const_iterator end)
        {
            std::string value;
            std::uint32_t length = 1;

            if (iterator != end &&
                static_cast<char>(*iterator) == '-')
            {
                value.push_back(static_cast<char>(*iterator));
                ++length;
                ++iterator;
            }

            while (iterator != end &&
                   static_cast<char>(*iterator) >= '0' &&
                   static_cast<char>(*iterator) <= '9')
            {
                value.push_back(static_cast<char>(*iterator));

                ++iterator;
            }

            if (iterator != end &&
                static_cast<char>(*iterator) == '.')
            {
                value.push_back(static_cast<char>(*iterator));
                ++length;
                ++iterator;

                while (iterator != end &&
                       static_cast<char>(*iterator) >= '0' &&
                       static_cast<char>(*iterator) <= '9')
                {
                    value.push_back(static_cast<char>(*iterator));

                    ++iterator;
                }
            }

            // parse exponent
            if (iterator != end &&
                (static_cast<char>(*iterator) == 'e' ||
                 static_cast<char>(*iterator) == 'E'))
            {
                value.push_back(static_cast<char>(*iterator));
                if (++iterator == end)
                    throw std::runtime_error("Invalid exponent");

                if (static_cast<char>(*iterator) == '+' ||
                    static_cast<char>(*iterator) == '-')
                    value.push_back(static_cast<char>(*iterator++));

                if (iterator == end ||
                    static_cast<char>(*iterator) < '0' ||
                    static_cast<char>(*iterator) > '9')
                    throw std::runtime_error("Invalid exponent");

                while (iterator != end &&
                       static_cast<char>(*iterator) >= '0' &&
                       static_cast<char>(*iterator) <= '9')
                {
                    value.push_back(static_cast<char>(*iterator));
                    ++iterator;
                }
            }

            if (value.length() < length) return false;

            return std::stof(value);
        }
    }

    MtlLoader::MtlLoader(Cache& initCache):
        Loader(initCache, Type::material)
    {
    }

    bool MtlLoader::loadAsset(Bundle& bundle,
                              const std::string& name,
                              const std::vector<std::byte>& data,
                              bool mipmaps)
    {
        std::string materialName = name;
        std::shared_ptr<graphics::Texture> diffuseTexture;
        std::shared_ptr<graphics::Texture> ambientTexture;
        Color diffuseColor = Color::white();
        float opacity = 1.0F;

        std::uint32_t materialCount = 0;

        auto iterator = data.cbegin();

        while (iterator != data.end())
        {
            if (isNewline(*iterator))
            {
                // skip empty lines
                ++iterator;
            }
            else if (static_cast<char>(*iterator) == '#')
            {
                // skip the comment
                skipLine(iterator, data.end());
            }
            else
            {
                skipWhitespaces(iterator, data.end());
                const auto keyword = parseString(iterator, data.end());

                if (keyword == "newmtl")
                {
                    if (materialCount)
                    {
                        auto material = std::make_unique<graphics::Material>();
                        material->blendState = cache.getBlendState(blendAlpha);
                        material->shader = diffuseTexture ? cache.getShader(shaderTexture) : cache.getShader(shaderColor);
                        material->textures[0] = diffuseTexture;
                        material->textures[1] = ambientTexture;
                        material->diffuseColor = diffuseColor;
                        material->opacity = opacity;
                        material->cullMode = graphics::CullMode::back;

                        bundle.setMaterial(materialName, std::move(material));
                    }

                    skipWhitespaces(iterator, data.end());
                    materialName = parseString(iterator, data.end());

                    skipLine(iterator, data.end());

                    diffuseTexture.reset();
                    ambientTexture.reset();
                    diffuseColor = Color::white();
                    opacity = 1.0F;
                }
                else if (keyword == "map_Ka") // ambient texture map
                {
                    // TODO: parse options
                    skipWhitespaces(iterator, data.end());
                    const auto filename = parseString(iterator, data.end());

                    skipLine(iterator, data.end());

                    ambientTexture = cache.getTexture(filename);

                    if (!ambientTexture)
                    {
                        bundle.loadAsset(Type::image, filename, filename, mipmaps);
                        ambientTexture = cache.getTexture(filename);
                    }
                }
                else if (keyword == "map_Kd") // diffuse texture map
                {
                    // TODO: parse options
                    skipWhitespaces(iterator, data.end());
                    const auto filename = parseString(iterator, data.end());

                    skipLine(iterator, data.end());

                    diffuseTexture = cache.getTexture(filename);

                    if (!diffuseTexture)
                    {
                        bundle.loadAsset(Type::image, filename, filename, mipmaps);
                        diffuseTexture = cache.getTexture(filename);
                    }
                }
                else if (keyword == "Ka") // ambient color
                    skipLine(iterator, data.end());
                else if (keyword == "Kd") // diffuse color
                {
                    skipWhitespaces(iterator, data.end());
                    const auto red = parseFloat(iterator, data.end());
                    skipWhitespaces(iterator, data.end());
                    const auto green = parseFloat(iterator, data.end());
                    skipWhitespaces(iterator, data.end());
                    const auto blue = parseFloat(iterator, data.end());

                    skipLine(iterator, data.end());

                    diffuseColor = Color{red, green, blue, 1.0F};
                }
                else if (keyword == "Ks") // specular color
                    skipLine(iterator, data.end());
                else if (keyword == "Ke") // emissive color
                    skipLine(iterator, data.end());
                else if (keyword == "d") // opacity
                {
                    skipWhitespaces(iterator, data.end());
                    opacity = parseFloat(iterator, data.end());

                    skipLine(iterator, data.end());
                }
                else if (keyword == "Tr") // transparency
                {
                    skipWhitespaces(iterator, data.end());
                    const auto transparency = parseFloat(iterator, data.end());

                    skipLine(iterator, data.end());

                    // d = 1 - Tr
                    opacity = 1.0F - transparency;
                }
                else
                {
                    // skip all unknown commands
                    skipLine(iterator, data.end());
                }

                if (!materialCount) ++materialCount; // if we got at least one attribute, we have an material
            }
        }

        if (materialCount)
        {
            auto material = std::make_unique<graphics::Material>();
            material->blendState = cache.getBlendState(blendAlpha);
            material->shader = cache.getShader(shaderTexture);
            material->textures[0] = diffuseTexture;
            material->textures[1] = ambientTexture;
            material->diffuseColor = diffuseColor;
            material->opacity = opacity;
            material->cullMode = graphics::CullMode::back;

            bundle.setMaterial(materialName, std::move(material));
        }

        return true;
    }
}
<commit_msg>Make functions noexcept<commit_after>// Ouzel by Elviss Strazdins

#include <iterator>
#include <stdexcept>
#include <string>
#include "MtlLoader.hpp"
#include "Bundle.hpp"
#include "Cache.hpp"
#include "../core/Engine.hpp"

namespace ouzel::assets
{
    namespace
    {
        constexpr auto isWhitespace(std::byte c) noexcept
        {
            return static_cast<char>(c) == ' ' ||
                static_cast<char>(c) == '\t';
        }

        constexpr auto isNewline(std::byte c) noexcept
        {
            return static_cast<char>(c) == '\r' ||
                static_cast<char>(c) == '\n';
        }

        constexpr auto isControlChar(std::byte c) noexcept
        {
            return static_cast<std::uint8_t>(c) <= 0x1F;
        }

        void skipWhitespaces(std::vector<std::byte>::const_iterator& iterator,
                             std::vector<std::byte>::const_iterator end) noexcept
        {
            while (iterator != end)
                if (isWhitespace(*iterator))
                    ++iterator;
                else
                    break;
        }

        void skipLine(std::vector<std::byte>::const_iterator& iterator,
                      std::vector<std::byte>::const_iterator end) noexcept
        {
            while (iterator != end)
            {
                if (isNewline(*iterator))
                {
                    ++iterator;
                    break;
                }

                ++iterator;
            }
        }

        std::string parseString(std::vector<std::byte>::const_iterator& iterator,
                                std::vector<std::byte>::const_iterator end)
        {
            std::string result;

            while (iterator != end && !isControlChar(*iterator) && !isWhitespace(*iterator))
            {
                result.push_back(static_cast<char>(*iterator));
                ++iterator;
            }

            if (result.empty())
                throw std::runtime_error("Invalid string");

            return result;
        }

        float parseFloat(std::vector<std::byte>::const_iterator& iterator,
                         std::vector<std::byte>::const_iterator end)
        {
            std::string value;
            std::uint32_t length = 1;

            if (iterator != end &&
                static_cast<char>(*iterator) == '-')
            {
                value.push_back(static_cast<char>(*iterator));
                ++length;
                ++iterator;
            }

            while (iterator != end &&
                   static_cast<char>(*iterator) >= '0' &&
                   static_cast<char>(*iterator) <= '9')
            {
                value.push_back(static_cast<char>(*iterator));

                ++iterator;
            }

            if (iterator != end &&
                static_cast<char>(*iterator) == '.')
            {
                value.push_back(static_cast<char>(*iterator));
                ++length;
                ++iterator;

                while (iterator != end &&
                       static_cast<char>(*iterator) >= '0' &&
                       static_cast<char>(*iterator) <= '9')
                {
                    value.push_back(static_cast<char>(*iterator));

                    ++iterator;
                }
            }

            // parse exponent
            if (iterator != end &&
                (static_cast<char>(*iterator) == 'e' ||
                 static_cast<char>(*iterator) == 'E'))
            {
                value.push_back(static_cast<char>(*iterator));
                if (++iterator == end)
                    throw std::runtime_error("Invalid exponent");

                if (static_cast<char>(*iterator) == '+' ||
                    static_cast<char>(*iterator) == '-')
                    value.push_back(static_cast<char>(*iterator++));

                if (iterator == end ||
                    static_cast<char>(*iterator) < '0' ||
                    static_cast<char>(*iterator) > '9')
                    throw std::runtime_error("Invalid exponent");

                while (iterator != end &&
                       static_cast<char>(*iterator) >= '0' &&
                       static_cast<char>(*iterator) <= '9')
                {
                    value.push_back(static_cast<char>(*iterator));
                    ++iterator;
                }
            }

            if (value.length() < length) return false;

            return std::stof(value);
        }
    }

    MtlLoader::MtlLoader(Cache& initCache):
        Loader(initCache, Type::material)
    {
    }

    bool MtlLoader::loadAsset(Bundle& bundle,
                              const std::string& name,
                              const std::vector<std::byte>& data,
                              bool mipmaps)
    {
        std::string materialName = name;
        std::shared_ptr<graphics::Texture> diffuseTexture;
        std::shared_ptr<graphics::Texture> ambientTexture;
        Color diffuseColor = Color::white();
        float opacity = 1.0F;

        std::uint32_t materialCount = 0;

        auto iterator = data.cbegin();

        while (iterator != data.end())
        {
            if (isNewline(*iterator))
            {
                // skip empty lines
                ++iterator;
            }
            else if (static_cast<char>(*iterator) == '#')
            {
                // skip the comment
                skipLine(iterator, data.end());
            }
            else
            {
                skipWhitespaces(iterator, data.end());
                const auto keyword = parseString(iterator, data.end());

                if (keyword == "newmtl")
                {
                    if (materialCount)
                    {
                        auto material = std::make_unique<graphics::Material>();
                        material->blendState = cache.getBlendState(blendAlpha);
                        material->shader = diffuseTexture ? cache.getShader(shaderTexture) : cache.getShader(shaderColor);
                        material->textures[0] = diffuseTexture;
                        material->textures[1] = ambientTexture;
                        material->diffuseColor = diffuseColor;
                        material->opacity = opacity;
                        material->cullMode = graphics::CullMode::back;

                        bundle.setMaterial(materialName, std::move(material));
                    }

                    skipWhitespaces(iterator, data.end());
                    materialName = parseString(iterator, data.end());

                    skipLine(iterator, data.end());

                    diffuseTexture.reset();
                    ambientTexture.reset();
                    diffuseColor = Color::white();
                    opacity = 1.0F;
                }
                else if (keyword == "map_Ka") // ambient texture map
                {
                    // TODO: parse options
                    skipWhitespaces(iterator, data.end());
                    const auto filename = parseString(iterator, data.end());

                    skipLine(iterator, data.end());

                    ambientTexture = cache.getTexture(filename);

                    if (!ambientTexture)
                    {
                        bundle.loadAsset(Type::image, filename, filename, mipmaps);
                        ambientTexture = cache.getTexture(filename);
                    }
                }
                else if (keyword == "map_Kd") // diffuse texture map
                {
                    // TODO: parse options
                    skipWhitespaces(iterator, data.end());
                    const auto filename = parseString(iterator, data.end());

                    skipLine(iterator, data.end());

                    diffuseTexture = cache.getTexture(filename);

                    if (!diffuseTexture)
                    {
                        bundle.loadAsset(Type::image, filename, filename, mipmaps);
                        diffuseTexture = cache.getTexture(filename);
                    }
                }
                else if (keyword == "Ka") // ambient color
                    skipLine(iterator, data.end());
                else if (keyword == "Kd") // diffuse color
                {
                    skipWhitespaces(iterator, data.end());
                    const auto red = parseFloat(iterator, data.end());
                    skipWhitespaces(iterator, data.end());
                    const auto green = parseFloat(iterator, data.end());
                    skipWhitespaces(iterator, data.end());
                    const auto blue = parseFloat(iterator, data.end());

                    skipLine(iterator, data.end());

                    diffuseColor = Color{red, green, blue, 1.0F};
                }
                else if (keyword == "Ks") // specular color
                    skipLine(iterator, data.end());
                else if (keyword == "Ke") // emissive color
                    skipLine(iterator, data.end());
                else if (keyword == "d") // opacity
                {
                    skipWhitespaces(iterator, data.end());
                    opacity = parseFloat(iterator, data.end());

                    skipLine(iterator, data.end());
                }
                else if (keyword == "Tr") // transparency
                {
                    skipWhitespaces(iterator, data.end());
                    const auto transparency = parseFloat(iterator, data.end());

                    skipLine(iterator, data.end());

                    // d = 1 - Tr
                    opacity = 1.0F - transparency;
                }
                else
                {
                    // skip all unknown commands
                    skipLine(iterator, data.end());
                }

                if (!materialCount) ++materialCount; // if we got at least one attribute, we have an material
            }
        }

        if (materialCount)
        {
            auto material = std::make_unique<graphics::Material>();
            material->blendState = cache.getBlendState(blendAlpha);
            material->shader = cache.getShader(shaderTexture);
            material->textures[0] = diffuseTexture;
            material->textures[1] = ambientTexture;
            material->diffuseColor = diffuseColor;
            material->opacity = opacity;
            material->cullMode = graphics::CullMode::back;

            bundle.setMaterial(materialName, std::move(material));
        }

        return true;
    }
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2005-2008 by the FIFE team                              *
 *   http://www.fifengine.de                                               *
 *   This file is part of FIFE.                                            *
 *                                                                         *
 *   FIFE is free software; you can redistribute it and/or                 *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   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.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
 ***************************************************************************/

// Standard C++ library includes
#include <cassert>
#include <iostream>

// 3rd party library includes
#include <SDL.h>

// FIFE includes
// These includes are split up in two parts, separated by one empty line
// First block: files included from the FIFE root src directory
// Second block: files included from the same folder
#include "image.h"

namespace FIFE {

	Image::Image(SDL_Surface* surface):
		m_location(ResourceLocation("")),
		m_surface(NULL) {
		reset(surface);
	}

	Image::Image(const uint8_t* data, unsigned int width, unsigned int height):
		m_location(ResourceLocation("")),
		m_surface(NULL) {
		SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, width,height, 32,
		                                            RMASK, GMASK, BMASK ,AMASK);
		SDL_LockSurface(surface);

		unsigned int size = width * height * 4;
		uint8_t* pixeldata = static_cast<uint8_t*>(surface->pixels);
		std::copy(data, data + size, pixeldata);
		SDL_UnlockSurface(surface);
		reset(surface);
	}

	void Image::reset(SDL_Surface* surface) {
		if( m_surface ) {
			SDL_FreeSurface(m_surface);
		}
		m_surface = surface;
		m_xshift = 0;
		m_yshift = 0;
		while (!m_clipstack.empty()) {
			m_clipstack.pop();
		}
		m_area.x = m_area.y = m_area.w = m_area.h = 0;
		m_surface = surface;
	}

	Image::~Image() {
		//assert(m_refcount == 0);
		reset(NULL);
	}

	SDL_Surface* Image::detachSurface() {
		SDL_Surface* srf = m_surface;
		m_surface = NULL;
		return srf;
	}

	unsigned int Image::getWidth() const {
		if (!m_surface) {
			return 0;
		}
		return m_surface->w;
	}

	unsigned int Image::getHeight() const {
		if (!m_surface) {
			return 0;
		}
		return m_surface->h;
	}

	const Rect& Image::getArea() {
		m_area.w = getWidth();
		m_area.h = getHeight();
		return m_area;
	}

	void Image::setXShift(int xshift) {
		m_xshift = xshift;
	}

	void Image::setYShift(int yshift) {
		m_yshift = yshift;
	}

	void Image::getPixelRGBA(int x, int y, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) {
		if ((x < 0) || (x >= m_surface->w) || (y < 0) || (y >= m_surface->h)) {
			r = 0;
			g = 0;
			b = 0;
			a = 0;
			return;
		}

		int bpp = m_surface->format->BytesPerPixel;
		Uint8 *p = (Uint8*)m_surface->pixels + y * m_surface->pitch + x * bpp;
		uint32_t pixel;
		switch(bpp) {
		case 1:
			pixel = *p;

		case 2:
			pixel = *(Uint16 *)p;

		case 3:
			if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
				pixel = p[0] << 16 | p[1] << 8 | p[2];
			} else {
				pixel = p[0] | p[1] << 8 | p[2] << 16;
			}

		case 4:
			pixel = *(Uint32 *)p;
		}
		SDL_GetRGBA(pixel, m_surface->format, r, g, b, a);
	}

	void Image::render(const Rect& rect, unsigned char alpha) {
		render(rect, SDL_GetVideoSurface(), alpha);
	}

	void Image::pushClipArea(const Rect& cliparea, bool clear) {
		ClipInfo ci;
		ci.r = cliparea;
		ci.clearing = clear;
		m_clipstack.push(ci);
		setClipArea(cliparea, clear);
	}

	void Image::popClipArea() {
		assert(!m_clipstack.empty());
		m_clipstack.pop();
		if (m_clipstack.empty()) {
			clearClipArea();
		} else {
			ClipInfo ci = m_clipstack.top();
			setClipArea(ci.r, ci.clearing);
		}
	}

	const Rect& Image::getClipArea() const {
		if (m_clipstack.empty()) {
			return m_clipstack.top().r;
		} else {
			return m_area;
		}
	}

	void Image::clearClipArea() {
		setClipArea(m_area, true);
	}

	void Image::saveAsPng(const std::string& filename, SDL_Surface& surface) {
		FILE *fp;
		png_structp pngptr;
		png_infop infoptr;
		int colortype;
		png_bytep *rowpointers = NULL;
		Uint32 rmask, gmask, bmask, amask;
		//get endian
		#if SDL_BYTEORDER == SDL_BIG_ENDIAN
		rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff;
		#else
		rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000;
		#endif

		fp = fopen(filename.c_str(), "wb");

		if (fp == NULL) {
			return;
		}

		//create the png file
		pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
		NULL, NULL, NULL);
		if (pngptr == NULL) {
			fclose(fp);
			return;
		}

		//create information struct
		infoptr = png_create_info_struct(pngptr);
		if (infoptr == NULL) {
			fclose(fp);
			png_destroy_write_struct(&pngptr, (png_infopp)NULL);
			return;
		}

		if (setjmp(png_jmpbuf(pngptr))) {
			png_destroy_write_struct(&pngptr, &infoptr);
			fclose(fp);
			return;
		}

		//initialize io
		png_init_io(pngptr, fp);

		//lock the surface for access
		SDL_LockSurface(&surface);

		colortype = PNG_COLOR_TYPE_RGB;
		if(m_surface->format->palette){
			colortype |= PNG_COLOR_TYPE_PALETTE;
		}
		else if (m_surface->format->Amask){
			colortype |= PNG_COLOR_TYPE_RGB_ALPHA;
		}
		else{}

		png_set_IHDR(pngptr, infoptr, surface.w, surface.h, 8, colortype,
			PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

		png_write_info(pngptr, infoptr);
		png_set_packing(pngptr);

		rowpointers = new png_bytep[surface.h];
		for (int i = 0; i < surface.h; i++) {
			rowpointers[i] = (png_bytep)(Uint8 *)surface.pixels + i*surface.pitch;
		}
		//write the image
		png_write_image(pngptr, rowpointers);
		png_write_end(pngptr, infoptr);

		SDL_UnlockSurface(&surface);
		delete [] rowpointers;
		png_destroy_write_struct(&pngptr, &infoptr);
		fclose(fp);

	}
}
<commit_msg>Fixed a tiny off-by-one in the getBixel function.<commit_after>/***************************************************************************
 *   Copyright (C) 2005-2008 by the FIFE team                              *
 *   http://www.fifengine.de                                               *
 *   This file is part of FIFE.                                            *
 *                                                                         *
 *   FIFE is free software; you can redistribute it and/or                 *
 *   modify it under the terms of the GNU Lesser General Public            *
 *   License as published by the Free Software Foundation; either          *
 *   version 2.1 of the License, or (at your option) any later version.    *
 *                                                                         *
 *   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.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
 ***************************************************************************/

// Standard C++ library includes
#include <cassert>
#include <iostream>

// 3rd party library includes
#include <SDL.h>

// FIFE includes
// These includes are split up in two parts, separated by one empty line
// First block: files included from the FIFE root src directory
// Second block: files included from the same folder
#include "image.h"

namespace FIFE {

	Image::Image(SDL_Surface* surface):
		m_location(ResourceLocation("")),
		m_surface(NULL) {
		reset(surface);
	}

	Image::Image(const uint8_t* data, unsigned int width, unsigned int height):
		m_location(ResourceLocation("")),
		m_surface(NULL) {
		SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, width,height, 32,
		                                            RMASK, GMASK, BMASK ,AMASK);
		SDL_LockSurface(surface);

		unsigned int size = width * height * 4;
		uint8_t* pixeldata = static_cast<uint8_t*>(surface->pixels);
		std::copy(data, data + size, pixeldata);
		SDL_UnlockSurface(surface);
		reset(surface);
	}

	void Image::reset(SDL_Surface* surface) {
		if( m_surface ) {
			SDL_FreeSurface(m_surface);
		}
		m_surface = surface;
		m_xshift = 0;
		m_yshift = 0;
		while (!m_clipstack.empty()) {
			m_clipstack.pop();
		}
		m_area.x = m_area.y = m_area.w = m_area.h = 0;
		m_surface = surface;
	}

	Image::~Image() {
		//assert(m_refcount == 0);
		reset(NULL);
	}

	SDL_Surface* Image::detachSurface() {
		SDL_Surface* srf = m_surface;
		m_surface = NULL;
		return srf;
	}

	unsigned int Image::getWidth() const {
		if (!m_surface) {
			return 0;
		}
		return m_surface->w;
	}

	unsigned int Image::getHeight() const {
		if (!m_surface) {
			return 0;
		}
		return m_surface->h;
	}

	const Rect& Image::getArea() {
		m_area.w = getWidth();
		m_area.h = getHeight();
		return m_area;
	}

	void Image::setXShift(int xshift) {
		m_xshift = xshift;
	}

	void Image::setYShift(int yshift) {
		m_yshift = yshift;
	}

	void Image::getPixelRGBA(int x, int y, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) {
		if ((x < 0) || (x > m_surface->w) || (y < 0) || (y > m_surface->h)) {
			r = 0;
			g = 0;
			b = 0;
			a = 0;
			return;
		}

		int bpp = m_surface->format->BytesPerPixel;
		Uint8 *p = (Uint8*)m_surface->pixels + y * m_surface->pitch + x * bpp;
		uint32_t pixel;
		switch(bpp) {
		case 1:
			pixel = *p;

		case 2:
			pixel = *(Uint16 *)p;

		case 3:
			if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
				pixel = p[0] << 16 | p[1] << 8 | p[2];
			} else {
				pixel = p[0] | p[1] << 8 | p[2] << 16;
			}

		case 4:
			pixel = *(Uint32 *)p;
		}
		SDL_GetRGBA(pixel, m_surface->format, r, g, b, a);
	}

	void Image::render(const Rect& rect, unsigned char alpha) {
		render(rect, SDL_GetVideoSurface(), alpha);
	}

	void Image::pushClipArea(const Rect& cliparea, bool clear) {
		ClipInfo ci;
		ci.r = cliparea;
		ci.clearing = clear;
		m_clipstack.push(ci);
		setClipArea(cliparea, clear);
	}

	void Image::popClipArea() {
		assert(!m_clipstack.empty());
		m_clipstack.pop();
		if (m_clipstack.empty()) {
			clearClipArea();
		} else {
			ClipInfo ci = m_clipstack.top();
			setClipArea(ci.r, ci.clearing);
		}
	}

	const Rect& Image::getClipArea() const {
		if (m_clipstack.empty()) {
			return m_clipstack.top().r;
		} else {
			return m_area;
		}
	}

	void Image::clearClipArea() {
		setClipArea(m_area, true);
	}

	void Image::saveAsPng(const std::string& filename, SDL_Surface& surface) {
		FILE *fp;
		png_structp pngptr;
		png_infop infoptr;
		int colortype;
		png_bytep *rowpointers = NULL;
		Uint32 rmask, gmask, bmask, amask;
		//get endian
		#if SDL_BYTEORDER == SDL_BIG_ENDIAN
		rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff;
		#else
		rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000;
		#endif

		fp = fopen(filename.c_str(), "wb");

		if (fp == NULL) {
			return;
		}

		//create the png file
		pngptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
		NULL, NULL, NULL);
		if (pngptr == NULL) {
			fclose(fp);
			return;
		}

		//create information struct
		infoptr = png_create_info_struct(pngptr);
		if (infoptr == NULL) {
			fclose(fp);
			png_destroy_write_struct(&pngptr, (png_infopp)NULL);
			return;
		}

		if (setjmp(png_jmpbuf(pngptr))) {
			png_destroy_write_struct(&pngptr, &infoptr);
			fclose(fp);
			return;
		}

		//initialize io
		png_init_io(pngptr, fp);

		//lock the surface for access
		SDL_LockSurface(&surface);

		colortype = PNG_COLOR_TYPE_RGB;
		if(m_surface->format->palette){
			colortype |= PNG_COLOR_TYPE_PALETTE;
		}
		else if (m_surface->format->Amask){
			colortype |= PNG_COLOR_TYPE_RGB_ALPHA;
		}
		else{}

		png_set_IHDR(pngptr, infoptr, surface.w, surface.h, 8, colortype,
			PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

		png_write_info(pngptr, infoptr);
		png_set_packing(pngptr);

		rowpointers = new png_bytep[surface.h];
		for (int i = 0; i < surface.h; i++) {
			rowpointers[i] = (png_bytep)(Uint8 *)surface.pixels + i*surface.pitch;
		}
		//write the image
		png_write_image(pngptr, rowpointers);
		png_write_end(pngptr, infoptr);

		SDL_UnlockSurface(&surface);
		delete [] rowpointers;
		png_destroy_write_struct(&pngptr, &infoptr);
		fclose(fp);

	}
}
<|endoftext|>