1 #ifndef MARISA_BASE_H_ 2 #define MARISA_BASE_H_ 3 4 // Visual C++ does not provide stdint.h. 5 #ifndef _MSC_VER 6 #include <stdint.h> 7 #endif // _MSC_VER 8 9 #ifdef __cplusplus 10 #include <cstddef> 11 #include <new> 12 #else // __cplusplus 13 #include <stddef.h> 14 #endif // __cplusplus 15 16 #if defined(__ANDROID__) 17 #include <android/log.h> 18 #include <stdio.h> 19 #endif // __ANDROID__ 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif // __cplusplus 24 25 #ifdef _MSC_VER 26 typedef unsigned __int8 marisa_uint8; 27 typedef unsigned __int16 marisa_uint16; 28 typedef unsigned __int32 marisa_uint32; 29 typedef unsigned __int64 marisa_uint64; 30 #else // _MSC_VER 31 typedef uint8_t marisa_uint8; 32 typedef uint16_t marisa_uint16; 33 typedef uint32_t marisa_uint32; 34 typedef uint64_t marisa_uint64; 35 #endif // _MSC_VER 36 37 #define MARISA_UINT8_MAX ((marisa_uint8)-1) 38 #define MARISA_UINT16_MAX ((marisa_uint16)-1) 39 #define MARISA_UINT32_MAX ((marisa_uint32)-1) 40 #define MARISA_UINT64_MAX ((marisa_uint64)-1) 41 #define MARISA_SIZE_MAX ((size_t)-1) 42 43 #define MARISA_ZERO_TERMINATED MARISA_UINT32_MAX 44 #define MARISA_NOT_FOUND MARISA_UINT32_MAX 45 #define MARISA_MISMATCH MARISA_UINT32_MAX 46 47 #define MARISA_MAX_LENGTH (MARISA_UINT32_MAX - 1) 48 #define MARISA_MAX_NUM_KEYS (MARISA_UINT32_MAX - 1) 49 50 // marisa_status provides a list of error codes. Most of functions in 51 // libmarisa throw or return an error code. 52 typedef enum marisa_status_ { 53 // MARISA_OK means that a requested operation has succeeded. 54 MARISA_OK = 0, 55 56 // MARISA_HANDLE_ERROR means that a given handle is invalid. 57 MARISA_HANDLE_ERROR = 1, 58 59 // MARISA_STATE_ERROR means that an object is not ready for a requested 60 // operation. For example, an operation to modify a fixed container throws 61 // an exception with this error code. 62 MARISA_STATE_ERROR = 2, 63 64 // MARISA_PARAM_ERROR means that a given argument is invalid. For example, 65 // some functions throw an exception with this error code when an 66 // out-of-range value or a NULL pointer is given. 67 MARISA_PARAM_ERROR = 3, 68 69 // MARISA_SIZE_ERROR means that a size exceeds its limit. This error code 70 // is used when a building dictionary is too large or std::length_error is 71 // catched. 72 MARISA_SIZE_ERROR = 4, 73 74 // MARISA_MEMORY_ERROR means that a memory allocation has failed. 75 MARISA_MEMORY_ERROR = 5, 76 77 // MARISA_IO_ERROR means that an I/O failure. 78 MARISA_IO_ERROR = 6, 79 80 // MARISA_UNEXPECTED_ERROR means that an unexpected error has occurred. 81 MARISA_UNEXPECTED_ERROR = 7 82 } marisa_status; 83 84 // marisa_strerror() returns a name of an error code. 85 const char *marisa_strerror(marisa_status status); 86 87 // Flags and masks for dictionary settings are defined as follows. Please note 88 // that unspecified value/flags will be replaced with default value/flags. 89 typedef enum marisa_flags_ { 90 // A dictionary consinsts of 3 tries in default. If you want to change the 91 // number of tries, please give it with other flags. 92 MARISA_MIN_NUM_TRIES = 0x00001, 93 MARISA_MAX_NUM_TRIES = 0x000FF, 94 MARISA_DEFAULT_NUM_TRIES = 0x00003, 95 96 // MARISA_PATRICIA_TRIE is usually a better choice. MARISA_PREFIX_TRIE is 97 // provided for comparing prefix/patricia tries. 98 MARISA_PATRICIA_TRIE = 0x00100, 99 MARISA_PREFIX_TRIE = 0x00200, 100 MARISA_DEFAULT_TRIE = MARISA_PATRICIA_TRIE, 101 102 // There are 3 kinds of TAIL implementations. 103 // - MARISA_WITHOUT_TAIL: 104 // builds a dictionary without a TAIL. Its last trie has only 1-byte 105 // labels. 106 // - MARISA_BINARY_TAIL: 107 // builds a dictionary with a binary-mode TAIL. Its last labels are stored 108 // as binary data. 109 // - MARISA_TEXT_TAIL: 110 // builds a dictionary with a text-mode TAIL if its last labels do not 111 // contain NULL characters. The last labels are stored as zero-terminated 112 // string. Otherwise, a dictionary is built with a binary-mode TAIL. 113 MARISA_WITHOUT_TAIL = 0x01000, 114 MARISA_BINARY_TAIL = 0x02000, 115 MARISA_TEXT_TAIL = 0x04000, 116 MARISA_DEFAULT_TAIL = MARISA_TEXT_TAIL, 117 118 // libmarisa arranges nodes in ascending order of their labels 119 // (MARISA_LABEL_ORDER) or in descending order of their weights 120 // (MARISA_WEIGHT_ORDER). MARISA_WEIGHT_ORDER is generally a better choice 121 // because it enables faster lookups, but MARISA_LABEL_ORDER is still useful 122 // if an application needs to predict keys in label order. 123 MARISA_LABEL_ORDER = 0x10000, 124 MARISA_WEIGHT_ORDER = 0x20000, 125 MARISA_DEFAULT_ORDER = MARISA_WEIGHT_ORDER, 126 127 // The default settings. 0 is equivalent to MARISA_DEFAULT_FLAGS. 128 MARISA_DEFAULT_FLAGS = MARISA_DEFAULT_NUM_TRIES 129 | MARISA_DEFAULT_TRIE | MARISA_DEFAULT_TAIL | MARISA_DEFAULT_ORDER, 130 131 MARISA_NUM_TRIES_MASK = 0x000FF, 132 MARISA_TRIE_MASK = 0x00F00, 133 MARISA_TAIL_MASK = 0x0F000, 134 MARISA_ORDER_MASK = 0xF0000, 135 MARISA_FLAGS_MASK = 0xFFFFF 136 } marisa_flags; 137 138 #ifdef __cplusplus 139 } // extern "C" 140 #endif // __cplusplus 141 142 //#include <cstddef> 143 144 #ifdef __cplusplus 145 namespace marisa { 146 147 typedef ::marisa_uint8 UInt8; 148 typedef ::marisa_uint16 UInt16; 149 typedef ::marisa_uint32 UInt32; 150 typedef ::marisa_uint64 UInt64; 151 152 typedef ::marisa_status Status; 153 154 // An exception object stores a filename, a line number and an error code. 155 class Exception { 156 public: 157 Exception(const char *filename, int line, Status status) 158 : filename_(filename), line_(line), status_(status) {} 159 Exception(const Exception &ex) 160 : filename_(ex.filename_), line_(ex.line_), status_(ex.status_) {} 161 162 Exception &operator=(const Exception &rhs) { 163 filename_ = rhs.filename_; 164 line_ = rhs.line_; 165 status_ = rhs.status_; 166 return *this; 167 } 168 169 const char *filename() const { 170 return filename_; 171 } 172 int line() const { 173 return line_; 174 } 175 Status status() const { 176 return status_; 177 } 178 179 // Same as std::exception, what() returns an error message. 180 const char *what() const { 181 return ::marisa_strerror(status_); 182 } 183 184 private: 185 const char *filename_; 186 int line_; 187 Status status_; 188 }; 189 190 // MARISA_THROW adds a filename and a line number to an exception. 191 #if !defined(__ANDROID__) 192 #define MARISA_THROW(status) \ 193 (throw Exception(__FILE__, __LINE__, status)) 194 #else 195 196 inline int android_log_exception(int status) { 197 char tmpbuf[100]; 198 snprintf(tmpbuf, sizeof(tmpbuf), "marisa exception: %d", status); 199 __android_log_write(ANDROID_LOG_ERROR, "marisa-trie", tmpbuf); 200 return 0; 201 } 202 203 #define MARISA_THROW(status) \ 204 (android_log_exception(status)) 205 206 #endif // __ANDROID__ 207 208 // MARISA_THROW_IF throws an exception with `status' if `cond' is true. 209 #define MARISA_THROW_IF(cond, status) \ 210 (void)((!(cond)) || (MARISA_THROW(status), 0)) 211 212 // MARISA_DEBUG_IF is used for debugging. For example, MARISA_DEBUG_IF is used 213 // to find out-of-range accesses in marisa::Vector, marisa::IntVector, etc. 214 #ifdef _DEBUG 215 #define MARISA_DEBUG_IF(cond, status) \ 216 MARISA_THROW_IF(cond, status) 217 #else 218 #define MARISA_DEBUG_IF(cond, status) 219 #endif 220 221 // To not include <algorithm> only for std::swap(). 222 template <typename T> 223 void Swap(T *lhs, T *rhs) { 224 MARISA_THROW_IF((lhs == NULL) || (rhs == NULL), MARISA_PARAM_ERROR); 225 T temp = *lhs; 226 *lhs = *rhs; 227 *rhs = temp; 228 } 229 230 } // namespace marisa 231 #endif // __cplusplus 232 233 #endif // MARISA_BASE_H_ 234