| #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_ |