blob: 098384cef3b2eda5214e97a6e11d8a1842ec3d5a [file] [log] [blame]
#ifndef MARISA_BASE_H_
#define MARISA_BASE_H_
// Visual C++ does not provide stdint.h.
#ifndef _MSC_VER
#include <stdint.h>
#endif // _MSC_VER
#ifdef __cplusplus
#include <cstddef>
#include <new>
#else // __cplusplus
#include <stddef.h>
#endif // __cplusplus
#if defined(__ANDROID__)
#include <android/log.h>
#include <stdio.h>
#endif // __ANDROID__
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#ifdef _MSC_VER
typedef unsigned __int8 marisa_uint8;
typedef unsigned __int16 marisa_uint16;
typedef unsigned __int32 marisa_uint32;
typedef unsigned __int64 marisa_uint64;
#else // _MSC_VER
typedef uint8_t marisa_uint8;
typedef uint16_t marisa_uint16;
typedef uint32_t marisa_uint32;
typedef uint64_t marisa_uint64;
#endif // _MSC_VER
#define MARISA_UINT8_MAX ((marisa_uint8)-1)
#define MARISA_UINT16_MAX ((marisa_uint16)-1)
#define MARISA_UINT32_MAX ((marisa_uint32)-1)
#define MARISA_UINT64_MAX ((marisa_uint64)-1)
#define MARISA_SIZE_MAX ((size_t)-1)
#define MARISA_ZERO_TERMINATED MARISA_UINT32_MAX
#define MARISA_NOT_FOUND MARISA_UINT32_MAX
#define MARISA_MISMATCH MARISA_UINT32_MAX
#define MARISA_MAX_LENGTH (MARISA_UINT32_MAX - 1)
#define MARISA_MAX_NUM_KEYS (MARISA_UINT32_MAX - 1)
// marisa_status provides a list of error codes. Most of functions in
// libmarisa throw or return an error code.
typedef enum marisa_status_ {
// MARISA_OK means that a requested operation has succeeded.
MARISA_OK = 0,
// MARISA_HANDLE_ERROR means that a given handle is invalid.
MARISA_HANDLE_ERROR = 1,
// MARISA_STATE_ERROR means that an object is not ready for a requested
// operation. For example, an operation to modify a fixed container throws
// an exception with this error code.
MARISA_STATE_ERROR = 2,
// MARISA_PARAM_ERROR means that a given argument is invalid. For example,
// some functions throw an exception with this error code when an
// out-of-range value or a NULL pointer is given.
MARISA_PARAM_ERROR = 3,
// MARISA_SIZE_ERROR means that a size exceeds its limit. This error code
// is used when a building dictionary is too large or std::length_error is
// catched.
MARISA_SIZE_ERROR = 4,
// MARISA_MEMORY_ERROR means that a memory allocation has failed.
MARISA_MEMORY_ERROR = 5,
// MARISA_IO_ERROR means that an I/O failure.
MARISA_IO_ERROR = 6,
// MARISA_UNEXPECTED_ERROR means that an unexpected error has occurred.
MARISA_UNEXPECTED_ERROR = 7
} marisa_status;
// marisa_strerror() returns a name of an error code.
const char *marisa_strerror(marisa_status status);
// Flags and masks for dictionary settings are defined as follows. Please note
// that unspecified value/flags will be replaced with default value/flags.
typedef enum marisa_flags_ {
// A dictionary consinsts of 3 tries in default. If you want to change the
// number of tries, please give it with other flags.
MARISA_MIN_NUM_TRIES = 0x00001,
MARISA_MAX_NUM_TRIES = 0x000FF,
MARISA_DEFAULT_NUM_TRIES = 0x00003,
// MARISA_PATRICIA_TRIE is usually a better choice. MARISA_PREFIX_TRIE is
// provided for comparing prefix/patricia tries.
MARISA_PATRICIA_TRIE = 0x00100,
MARISA_PREFIX_TRIE = 0x00200,
MARISA_DEFAULT_TRIE = MARISA_PATRICIA_TRIE,
// There are 3 kinds of TAIL implementations.
// - MARISA_WITHOUT_TAIL:
// builds a dictionary without a TAIL. Its last trie has only 1-byte
// labels.
// - MARISA_BINARY_TAIL:
// builds a dictionary with a binary-mode TAIL. Its last labels are stored
// as binary data.
// - MARISA_TEXT_TAIL:
// builds a dictionary with a text-mode TAIL if its last labels do not
// contain NULL characters. The last labels are stored as zero-terminated
// string. Otherwise, a dictionary is built with a binary-mode TAIL.
MARISA_WITHOUT_TAIL = 0x01000,
MARISA_BINARY_TAIL = 0x02000,
MARISA_TEXT_TAIL = 0x04000,
MARISA_DEFAULT_TAIL = MARISA_TEXT_TAIL,
// libmarisa arranges nodes in ascending order of their labels
// (MARISA_LABEL_ORDER) or in descending order of their weights
// (MARISA_WEIGHT_ORDER). MARISA_WEIGHT_ORDER is generally a better choice
// because it enables faster lookups, but MARISA_LABEL_ORDER is still useful
// if an application needs to predict keys in label order.
MARISA_LABEL_ORDER = 0x10000,
MARISA_WEIGHT_ORDER = 0x20000,
MARISA_DEFAULT_ORDER = MARISA_WEIGHT_ORDER,
// The default settings. 0 is equivalent to MARISA_DEFAULT_FLAGS.
MARISA_DEFAULT_FLAGS = MARISA_DEFAULT_NUM_TRIES
| MARISA_DEFAULT_TRIE | MARISA_DEFAULT_TAIL | MARISA_DEFAULT_ORDER,
MARISA_NUM_TRIES_MASK = 0x000FF,
MARISA_TRIE_MASK = 0x00F00,
MARISA_TAIL_MASK = 0x0F000,
MARISA_ORDER_MASK = 0xF0000,
MARISA_FLAGS_MASK = 0xFFFFF
} marisa_flags;
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
//#include <cstddef>
#ifdef __cplusplus
namespace marisa {
typedef ::marisa_uint8 UInt8;
typedef ::marisa_uint16 UInt16;
typedef ::marisa_uint32 UInt32;
typedef ::marisa_uint64 UInt64;
typedef ::marisa_status Status;
// An exception object stores a filename, a line number and an error code.
class Exception {
public:
Exception(const char *filename, int line, Status status)
: filename_(filename), line_(line), status_(status) {}
Exception(const Exception &ex)
: filename_(ex.filename_), line_(ex.line_), status_(ex.status_) {}
Exception &operator=(const Exception &rhs) {
filename_ = rhs.filename_;
line_ = rhs.line_;
status_ = rhs.status_;
return *this;
}
const char *filename() const {
return filename_;
}
int line() const {
return line_;
}
Status status() const {
return status_;
}
// Same as std::exception, what() returns an error message.
const char *what() const {
return ::marisa_strerror(status_);
}
private:
const char *filename_;
int line_;
Status status_;
};
// MARISA_THROW adds a filename and a line number to an exception.
#if !defined(__ANDROID__)
#define MARISA_THROW(status) \
(throw Exception(__FILE__, __LINE__, status))
#else
inline int android_log_exception(int status) {
char tmpbuf[100];
snprintf(tmpbuf, sizeof(tmpbuf), "marisa exception: %d", status);
__android_log_write(ANDROID_LOG_ERROR, "marisa-trie", tmpbuf);
return 0;
}
#define MARISA_THROW(status) \
(android_log_exception(status))
#endif // __ANDROID__
// MARISA_THROW_IF throws an exception with `status' if `cond' is true.
#define MARISA_THROW_IF(cond, status) \
(void)((!(cond)) || (MARISA_THROW(status), 0))
// MARISA_DEBUG_IF is used for debugging. For example, MARISA_DEBUG_IF is used
// to find out-of-range accesses in marisa::Vector, marisa::IntVector, etc.
#ifdef _DEBUG
#define MARISA_DEBUG_IF(cond, status) \
MARISA_THROW_IF(cond, status)
#else
#define MARISA_DEBUG_IF(cond, status)
#endif
// To not include <algorithm> only for std::swap().
template <typename T>
void Swap(T *lhs, T *rhs) {
MARISA_THROW_IF((lhs == NULL) || (rhs == NULL), MARISA_PARAM_ERROR);
T temp = *lhs;
*lhs = *rhs;
*rhs = temp;
}
} // namespace marisa
#endif // __cplusplus
#endif // MARISA_BASE_H_