From bfdb184d349d2b8ecf4ea993793182cb32098e12 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Fri, 13 Nov 2015 19:21:31 +0100 Subject: Refactored Resource and added unittests. --- plugingui/resource.cc | 173 ++++++++++++++++++++++++++-------------------- plugingui/resource.h | 27 ++++---- plugingui/resource_data.h | 5 +- test/Makefile.am | 12 +++- test/resource_test.cc | 72 +++++++++++++++++++ 5 files changed, 195 insertions(+), 94 deletions(-) create mode 100644 test/resource_test.cc diff --git a/plugingui/resource.cc b/plugingui/resource.cc index 80bd51e..c0248c3 100644 --- a/plugingui/resource.cc +++ b/plugingui/resource.cc @@ -26,94 +26,119 @@ */ #include "resource.h" -#include #include +#include + +// rcgen generated file containing rc_data declaration. #include "resource_data.h" -GUI::Resource::Resource(std::string name) +namespace GUI { + +// Internal resources start with a colon. +static bool nameIsInternal(const std::string& name) +{ + return name.size() && (name[0] == ':'); +} + +Resource::Resource(const std::string& name) { - is_valid = false; - is_internal = false; - - if(name.length() == 0) return; - if(name[0] == ':') { - i_data = NULL; - i_size = 0; - - // Use internal resource: - const rc_data_t *p = rc_data; - while(p->name[0] == ':') { - if(std::string(p->name) == name) { - i_data = p->data; - i_size = p->size; - break; - } - p++; - } - - // We did not find the named resource. - if(i_data == NULL) { - ERR(rc, "Could not find '%s'\n", name.c_str()); - return; - } - - is_internal = true; - } else { - // Read from file: - FILE *fp = fopen(name.c_str(), "r"); - if(!fp) return; - char buf[32]; - while(!feof(fp)) { - size_t sz = fread(buf, 1, sizeof(buf), fp); - e_data.append(buf, sz); - } - fclose(fp); - is_internal = false; + if(nameIsInternal(name)) + { + // Use internal resource: + + // Find internal resource in rc_data. + const rc_data_t* p = rc_data; + while(p->name) // last entry in rc_data has the name := "" + { + if(name == p->name) + { + internalData = p->data; + internalSize = p->size; + break; + } + ++p; + } + + // We did not find the named resource. + if(internalData == nullptr) + { + ERR(rc, "Could not find '%s'\n", name.c_str()); + return; + } + + isInternal = true; + } + else + { + // Read from file: + std::FILE *fp = std::fopen(name.c_str(), "rb"); + if(!fp) + { + return; + } + + // Get the file size + std::fseek(fp, 0, SEEK_END); + size_t filesize = ftell(fp); + + // Reserve space in the string for the data. + externalData.reserve(filesize); + + // Rewind and read... + std::rewind(fp); + + char buffer[32]; + while(!std::feof(fp)) + { + size_t size = std::fread(buffer, 1, sizeof(buffer), fp); + externalData.append(buffer, size); + } + + std::fclose(fp); + + isInternal = false; } - is_valid = true; + isValid = true; } -const char *GUI::Resource::data() +const char *Resource::data() { - if(is_valid == false) return NULL; - if(is_internal) { - return i_data; - } else { - return e_data.data(); - } - return NULL; + if(isValid == false) + { + return nullptr; + } + + if(isInternal) + { + return internalData; + } + else + { + return externalData.data(); + } } -size_t GUI::Resource::size() +size_t Resource::size() { - if(is_valid == false) return 0; - if(is_internal) { - return i_size; - } else { - return e_data.length(); - } - return 0; + if(isValid == false) + { + return 0; + } + + if(isInternal) + { + return internalSize; + } + else + { + return externalData.length(); + } } -bool GUI::Resource::valid() +bool Resource::valid() { - return is_valid; + return isValid; } -#ifdef TEST_RESOURCE -//Additional dependency files -//deps: -//Required cflags (autoconf vars may be used) -//cflags: -//Required link options (autoconf vars may be used) -//libs: -#include "test.h" - -TEST_BEGIN; - -// TODO: Put some testcode here (see test.h for usable macros). - -TEST_END; - -#endif/*TEST_RESOURCE*/ +} // GUI:: diff --git a/plugingui/resource.h b/plugingui/resource.h index 4b494f7..101c689 100644 --- a/plugingui/resource.h +++ b/plugingui/resource.h @@ -24,8 +24,7 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_RESOURCE_H__ -#define __DRUMGIZMO_RESOURCE_H__ +#pragma once #include @@ -33,21 +32,19 @@ namespace GUI { class Resource { public: - Resource(std::string name); + Resource(const std::string& name); - const char *data(); - size_t size(); + const char* data(); + size_t size(); - bool valid(); + bool valid(); -private: - std::string e_data; - bool is_valid; - bool is_internal; - const char *i_data; - size_t i_size; +protected: + std::string externalData; + bool isValid = false; + bool isInternal = false; + const char *internalData = nullptr; + size_t internalSize = 0; }; -}; - -#endif/*__DRUMGIZMO_RESOURCE_H__*/ +} // GUI:: diff --git a/plugingui/resource_data.h b/plugingui/resource_data.h index c81c6cc..5d6392f 100644 --- a/plugingui/resource_data.h +++ b/plugingui/resource_data.h @@ -24,8 +24,7 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_RESOURCE_DATA_H__ -#define __DRUMGIZMO_RESOURCE_DATA_H__ +#pragma once typedef struct { const char *name; @@ -34,5 +33,3 @@ typedef struct { } rc_data_t; extern const rc_data_t rc_data[]; - -#endif/*__DRUMGIZMO_RESOURCE_DATA_H__*/ diff --git a/test/Makefile.am b/test/Makefile.am index 90373e1..08dba3b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,10 +1,20 @@ # Rules for the test code (use `make check` to execute) include $(top_srcdir)/src/Makefile.am.drumgizmo -TESTS = engine gui resampler lv2 configfile +TESTS = resource engine gui resampler lv2 configfile check_PROGRAMS = $(TESTS) +resource_CXXFLAGS = -DOUTPUT=\"resource\" $(CPPUNIT_CFLAGS) \ + -I$(top_srcdir)/hugin +resource_LDFLAGS = $(CPPUNIT_LIBS) +resource_SOURCES = \ + $(top_srcdir)/plugingui/resource.cc \ + $(top_srcdir)/plugingui/resource_data.cc \ + $(top_srcdir)/hugin/hugin.c \ + test.cc \ + resource_test.cc + engine_CXXFLAGS = -DOUTPUT=\"engine\" $(CPPUNIT_CFLAGS) \ -I$(top_srcdir)/src -I$(top_srcdir)/include \ -I$(top_srcdir)/hugin -DDISABLE_HUGIN diff --git a/test/resource_test.cc b/test/resource_test.cc new file mode 100644 index 0000000..7fc632a --- /dev/null +++ b/test/resource_test.cc @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * resource_test.cc + * + * Fri Nov 13 18:50:52 CET 2015 + * Copyright 2015 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DrumGizmo 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include + +#include "../plugingui/resource.h" + +class ResourceTester : public GUI::Resource { +public: + ResourceTester(const std::string& name) + : Resource(name) + {} + + bool probeIsInternal() + { + return isInternal; + } +}; + +class ResourceTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(ResourceTest); + CPPUNIT_TEST(externalReadTest); + CPPUNIT_TEST(internalReadTest); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() {} + void tearDown() {} + + void externalReadTest() + { + ResourceTester rc("kit/0000.wav"); + CPPUNIT_ASSERT(!rc.probeIsInternal()); + CPPUNIT_ASSERT(rc.valid()); + CPPUNIT_ASSERT_EQUAL((size_t)46, rc.size()); + } + + void internalReadTest() + { + ResourceTester rc(":bg.png"); + CPPUNIT_ASSERT(rc.probeIsInternal()); + CPPUNIT_ASSERT(rc.valid()); + CPPUNIT_ASSERT_EQUAL((size_t)1123, rc.size()); + } +}; + +// Registers the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION(ResourceTest); -- cgit v1.2.3