/******************************************************************************
*
* Copyright (c) 2014 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
* Globber.h
*
*****************************************************************************/
#pragma once
#include <oz++/CommonObject.h>
#include <oz++/Exception.h>
#include <oz++/Pair.h>
#include <oz++/KeyNamePairs.h>
#include <glob.h>
/*
typedef struct {
size_t gl_pathc; // Count of paths matched so
char **gl_pathv; // List of matched pathnames.
size_t gl_offs; // Slots to reserve in gl_pathv.
} glob_t;
*/
namespace OZ {
typedef int (*GlobError)(const char*, int);
class Globber :public CommonObject {
private:
glob_t globber;
bool firstTime;
private:
static int globError(const char* path, int errno)
{
printf("Error: path(%s), errno(%d)\n", path, errno);
return 0;
}
public:
Globber()
{
memset(&globber, 0, sizeof(globber));
firstTime = true;
}
void match(const char* pattern, int flags=0)
{
if (!firstTime) {
flags |= GLOB_APPEND;
}
int rc = glob(pattern, flags, (GlobError)&Globber::globError, &globber);
firstTime = false;
if (rc != 0) {
const char* msg = getError(rc);
throw IException("Failed to glob error=%s", msg);
}
}
~Globber()
{
clear();
}
const char* getError(int err)
{
static Pair<int, const char*> errors[] = {
{GLOB_NOSPACE, "Nospace"},
{GLOB_ABORTED, "Aborted"},
{GLOB_NOMATCH, "Nomatch"},
};
KeyNamePairs<int> pairs(errors, SizeOf(errors));
return pairs.match(err);
}
int pathCount()
{
return globber.gl_pathc;
}
const char** pathList()
{
return (const char**)globber.gl_pathv;
}
void clear()
{
globfree(&globber);
memset(&globber, 0, sizeof(globber));
firstTime = true;
}
const char* getPath(int i)
{
int count = pathCount();
const char** pathv = pathList();
const char* path = NULL;
if (count >0 && pathv) {
if (i >= 0 && i <count) {
path = pathv[i];
} else {
throw IException("Invalid argument i: %d", i);
}
} else {
throw IException("Pathlist is empty.");
}
return path;
}
virtual void display()
{
int count = pathCount();
const char** pathv = pathList();
if (count >0 && pathv) {
for (int i = 0; i< count; i++) {
printf("%s\n", pathv[i]);
}
}
}
};
}